Re: [dev] Status of pnm.c-bad?

From: Petter Reinholdtsen (pere@hungry.com)
Date: Mon May 14 2001 - 01:28:16 PDT

  • Next message: Sebastien Sable: "Re: [dev] TODO list and time table for 1.0.5"

    [Henning Meier-Geinitz]
    > what about the file pnm.c-bad in the backend directory? It seems to
    > be a modification of an old version of the pnm backend. Has anyone
    > played with it recently? Should we try to incorporate it into the
    > pnm backend, leave it without changes, or remove it from
    > distribution?

    Check the ChangeLog for 1999-04-03, and previous entries on pnm.c.
    The version tagged with RELEASE_1_0_1 should be the same as the one
    from 0.74. The patch was reverted for reliability reasons:

    --- pnm.c Mon May 14 10:23:23 2001
    +++ pnm.c-bad Fri Aug 13 21:22:28 1999
    @@ -38,11 +38,30 @@
        whether to permit this exception to apply to your modifications.
        If you do not wish that, delete this exception notice. */
     
    +/*
    + Modification allows selection to scan part of the image.
    + Shortcomings:
    + * Only tested with color PNM
    + * Not working with grey or 3-pass options
    +
    + Changes written by Göran Thyni <goran@bildbasen.se>
    + Copyright (C) 1998 JMS Bildbasen i Kiruna AB.
    +*/
    +
    +#ifdef _AIX
    +# include <lalloca.h> /* MUST come first for AIX! */
    +#endif
    +
    +#include <sane/config.h>
    +
    +#include <lalloca.h>
    +
     #include <stdlib.h>
     #include <string.h>
     #include <stdio.h>
     #include <unistd.h>
     #include <fcntl.h>
    +#include <signal.h>
     
     #include <sane/sane.h>
     #include <sane/sanei.h>
    @@ -53,7 +72,12 @@
     
     #define MAGIC (void *)0xab730324
     
    +#define XBRMAX 750
    +#define YBRMAX 1000
    +
     static int is_open = 0;
    +static int tlx = 0, tly = 0, brx = XBRMAX, bry = YBRMAX;
    +static int read_lines = 0;
     static int three_pass = 0;
     static int hand_scanner = 0;
     static int pass = 0;
    @@ -77,9 +101,28 @@
            0 << SANE_FIXED_SCALE_SHIFT /* quantization */
       };
     
    -static const SANE_Option_Descriptor sod[] =
    +static SANE_Range x_range =
    + {
    + 0, /* minimum */
    + XBRMAX, /* maximum */
    + 0, /* quantization */
    + };
    +
    +static SANE_Range y_range =
       {
    + 0, /* minimum */
    + YBRMAX, /* maximum */
    + 0, /* quantization */
    + };
    +
    +#define OPT_TLX 4
    +#define OPT_TLY 5
    +#define OPT_BRX 6
    +#define OPT_BRY 7
    +
    +static const SANE_Option_Descriptor sod[] =
         {
    + { /* 0 */
           SANE_NAME_NUM_OPTIONS,
           SANE_TITLE_NUM_OPTIONS,
           SANE_DESC_NUM_OPTIONS,
    @@ -90,7 +133,7 @@
           SANE_CONSTRAINT_NONE,
           {NULL}
         },
    - {
    + { /* 1 */
           "",
           "Source Selection",
           "Selection of the file to load.",
    @@ -101,7 +144,7 @@
           SANE_CONSTRAINT_NONE,
           {NULL}
         },
    - {
    + { /* 2 */
           SANE_NAME_FILE,
           SANE_TITLE_FILE,
           SANE_DESC_FILE,
    @@ -112,7 +155,62 @@
           SANE_CONSTRAINT_NONE,
           {NULL}
         },
    - {
    + { /* 3 */
    + "",
    + "Image Size",
    + "controls to set image size",
    + SANE_TYPE_GROUP,
    + SANE_UNIT_NONE,
    + 0,
    + SANE_CAP_ADVANCED,
    + SANE_CONSTRAINT_NONE,
    + {NULL}
    + },
    + { /* 4 */
    + SANE_NAME_SCAN_TL_X,
    + SANE_TITLE_SCAN_TL_X,
    + SANE_DESC_SCAN_TL_X,
    + SANE_TYPE_INT,
    + SANE_UNIT_PIXEL,
    + sizeof(SANE_Word),
    + SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
    + SANE_CONSTRAINT_RANGE,
    + {(SANE_String_Const *) &x_range} /* this is ANSI conformant! */
    + },
    + { /* 5 */
    + SANE_NAME_SCAN_TL_Y,
    + SANE_TITLE_SCAN_TL_Y,
    + SANE_DESC_SCAN_TL_Y,
    + SANE_TYPE_INT,
    + SANE_UNIT_PIXEL,
    + sizeof(SANE_Word),
    + SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
    + SANE_CONSTRAINT_RANGE,
    + {(SANE_String_Const *) &y_range} /* this is ANSI conformant! */
    + },
    + { /* 6 */
    + SANE_NAME_SCAN_BR_X,
    + SANE_TITLE_SCAN_BR_X,
    + SANE_DESC_SCAN_BR_X,
    + SANE_TYPE_INT,
    + SANE_UNIT_PIXEL,
    + sizeof(SANE_Word),
    + SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
    + SANE_CONSTRAINT_RANGE,
    + {(SANE_String_Const *) &x_range} /* this is ANSI conformant! */
    + },
    + { /* 7 */
    + SANE_NAME_SCAN_BR_Y,
    + SANE_TITLE_SCAN_BR_Y,
    + SANE_DESC_SCAN_BR_Y,
    + SANE_TYPE_INT,
    + SANE_UNIT_PIXEL,
    + sizeof(SANE_Word),
    + SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
    + SANE_CONSTRAINT_RANGE,
    + {(SANE_String_Const *) &y_range} /* this is ANSI conformant! */
    + },
    + { /* 8 */
           "",
           "Image Enhancement",
           "A few controls to enhance image while loading",
    @@ -123,7 +221,7 @@
           SANE_CONSTRAINT_NONE,
           {NULL}
         },
    - {
    + { /* 9 */
           SANE_NAME_BRIGHTNESS,
           SANE_TITLE_BRIGHTNESS,
           SANE_DESC_BRIGHTNESS,
    @@ -134,7 +232,7 @@
           SANE_CONSTRAINT_RANGE,
           {(SANE_String_Const *) &percentage_range} /* this is ANSI conformant! */
         },
    - {
    + { /* 10 */
           SANE_NAME_CONTRAST,
           SANE_TITLE_CONTRAST,
           SANE_DESC_CONTRAST,
    @@ -145,7 +243,7 @@
           SANE_CONSTRAINT_RANGE,
           {(SANE_String_Const *) &percentage_range} /* this is ANSI conformant! */
         },
    - {
    + { /* 11 */
           "grayify",
           "Grayify",
           "Load the image as grayscale.",
    @@ -156,7 +254,7 @@
           SANE_CONSTRAINT_NONE,
           {NULL}
         },
    - {
    + { /* 12 */
           "three-pass",
           "Three-Pass Simulation",
           "Simulate a three-pass scanner by returning 3 separate frames. "
    @@ -168,7 +266,7 @@
           SANE_CONSTRAINT_NONE,
           {NULL}
         },
    - {
    + { /* 13 */
           "hand-scanner",
           "Hand-Scanner Simulation",
           "Simulate a hand-scanner. Hand-scanners often do not know the image "
    @@ -181,7 +279,7 @@
           SANE_CONSTRAINT_NONE,
           {NULL}
         },
    - {
    + { /* 14 */
           "default-enhancements",
           "Defaults",
           "Set default values for enhancement controls (brightness & contrast).",
    @@ -191,7 +289,7 @@
           SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
           SANE_CONSTRAINT_NONE,
           {NULL}
    - }
    + },
       };
     
     static SANE_Parameters parms =
    @@ -216,10 +314,7 @@
       return SANE_STATUS_GOOD;
     }
     
    -void
    -sane_exit (void)
    -{
    -}
    +void sane_exit (void) { }
     
     /* Device select/open/close */
     
    @@ -322,22 +417,38 @@
                 myinfo |= SANE_INFO_RELOAD_PARAMS;
               break;
             case 4:
    - bright = *(SANE_Word *) value;
    + tlx = *(SANE_Word *) value;
    + myinfo |= SANE_INFO_RELOAD_PARAMS;
               break;
             case 5:
    - contr = *(SANE_Word *) value;
    + tly = *(SANE_Word *) value;
    + myinfo |= SANE_INFO_RELOAD_PARAMS;
               break;
             case 6:
    - gray = !!*(SANE_Word *) value;
    + brx = *(SANE_Word *) value;
               myinfo |= SANE_INFO_RELOAD_PARAMS;
               break;
             case 7:
    + bry = *(SANE_Word *) value;
    + myinfo |= SANE_INFO_RELOAD_PARAMS;
    + break;
    + case 9:
    + bright = *(SANE_Word *) value;
    + break;
    + case 10:
    + contr = *(SANE_Word *) value;
    + break;
    + case 11:
    + gray = !!*(SANE_Word *) value;
    + myinfo |= SANE_INFO_RELOAD_PARAMS;
    + break;
    + case 12:
               three_pass = !!*(SANE_Word *) value;
               break;
    - case 8:
    + case 13:
               hand_scanner = !!*(SANE_Word *) value;
               break;
    - case 9:
    + case 14:
               bright = contr = 0;
               myinfo |= SANE_INFO_RELOAD_OPTIONS;
               break;
    @@ -356,27 +467,36 @@
               strcpy (value, filename);
               break;
             case 4:
    - *(SANE_Word *) value = bright;
    + *(SANE_Word *) value = tlx;
               break;
             case 5:
    - *(SANE_Word *) value = contr;
    + *(SANE_Word *) value = tly;
               break;
             case 6:
    - *(SANE_Word *) value = gray;
    + *(SANE_Word *) value = brx;
               break;
             case 7:
    + *(SANE_Word *) value = bry;
    + break;
    + case 9:
    + *(SANE_Word *) value = bright;
    + break;
    + case 10:
    + *(SANE_Word *) value = contr;
    + break;
    + case 11:
    + *(SANE_Word *) value = gray;
    + break;
    + case 12:
               *(SANE_Word *) value = three_pass;
               break;
    - case 8:
    + case 13:
               *(SANE_Word *) value = hand_scanner;
               break;
    - case 9:
    - break;
             default:
               return SANE_STATUS_INVAL;
             }
           break;
    -
         case SANE_ACTION_SET_AUTO:
           return SANE_STATUS_UNSUPPORTED; /* We are DUMB */
         }
    @@ -471,6 +591,12 @@
       else if (getparmfromfile ())
         rc = SANE_STATUS_INVAL;
       *params = parms;
    + if (1)
    + {
    + params->lines = bry - tly;
    + params->pixels_per_line = brx - tlx;
    + params->bytes_per_line = params->pixels_per_line * 3;
    + }
       return rc;
     }
     
    @@ -487,6 +613,7 @@
         {
           fclose (infile);
           infile = NULL;
    + read_lines = 0;
           if (!three_pass || ++pass >= 3)
             return SANE_STATUS_EOF;
         }
    @@ -519,13 +646,19 @@
                SANE_Int max_length, SANE_Int * length)
     {
       int len, x, hlp;
    -
    + signal (SIGSEGV, SIG_DFL);
       if (handle != MAGIC || !is_open || !infile)
         return SANE_STATUS_INVAL; /* Unknown handle or no file to read... */
    -
    + again:
       if (feof (infile))
    + {
         return SANE_STATUS_EOF;
    -
    + }
    + if (!read_lines && tly)
    + {
    + fseek(infile, parms.bytes_per_line * tly, SEEK_CUR);
    + read_lines = tly;
    + }
       /* Allocate a buffer for the RGB values. */
       if (ppm_type == ppm_color && (gray || three_pass))
         {
    @@ -534,7 +667,7 @@
           if (rgbbuf == 0 || rgblength < 3 * max_length)
             {
               /* Allocate a new rgbbuf. */
    - free (rgbbuf);
    + if (rgbbuf) free (rgbbuf);
               rgblength = 3 * max_length;
               rgbbuf = malloc (rgblength);
               if (rgbbuf == 0)
    @@ -549,19 +682,25 @@
     
           /* Slurp in the RGB buffer. */
           len = fread (q, 1, rgblength - rgbleftover[0], infile);
    + if (len == 0) goto again;
    + if (tlx || brx != XBRMAX)
    + {
    + len = (brx - tlx) * 3;
    + }
           rgbend = rgbbuf + len;
    -
           q = data;
           if (gray)
             {
               /* Zip through the buffer, converting color data to grayscale. */
    - for (p = rgbbuf; p < rgbend; p += 3)
    + for (p = rgbbuf + tlx * 3; p < rgbend; p += 3)
                 *q++ = ((long) p[0] + p[1] + p[2]) / 3;
             }
           else
             {
    + p = (rgbbuf + (pass + 1) % 3);
    + p += tlx * 3;
               /* Zip through the buffer, extracting data for this pass. */
    - for (p = (rgbbuf + (pass + 1) % 3); p < rgbend; p += 3)
    + for (; p < rgbend; p += 3)
                 *q++ = *p;
             }
     
    @@ -571,14 +710,32 @@
           q = rgbleftover + 1;
           while (p < rgbend)
             *q++ = *p++;
    -
           len /= 3;
         }
       else
    + {
         /* Suck in as much of the file as possible, since it's already in the
            correct format. */
    - len = fread (data, 1, max_length, infile);
    -
    + char *buf;
    + int doread = parms.bytes_per_line;
    + if (read_lines >= bry)
    + return SANE_STATUS_EOF;
    + buf = alloca(doread);
    + len = fread (buf, 1, doread, infile);
    + if (brx == XBRMAX && read_lines < YBRMAX)
    + {
    + memcpy(data, buf, len);
    + bzero(data + len, XBRMAX * 3);
    + len = XBRMAX * 3;
    + }
    + else
    + {
    + len = (brx - tlx) * 3;
    + memcpy(data, buf + (tlx * 3), len);
    + }
    + if (len == 0 && feof(infile)) /* goto again; */
    + return SANE_STATUS_EOF;
    + }
       if (parms.depth == 8)
         /* Do the transformations ... DEMO ONLY ! THIS MAKES NO SENSE ! */
         for (x = 0; x < len; x++)
    @@ -593,8 +750,8 @@
               hlp = 255;
             *(data + x) = hlp;
           }
    -
       *length = len;
    + read_lines++;
       return SANE_STATUS_GOOD;
     }
     
    @@ -606,6 +763,7 @@
         {
           fclose (infile);
           infile = NULL;
    + read_lines = 0;
         }
     }
     

    --
    Source code, list archive, and docs: http://www.mostang.com/sane/
    To unsubscribe: echo unsubscribe sane-devel | mail majordomo@mostang.com
    



    This archive was generated by hypermail 2b29 : Mon May 14 2001 - 01:12:15 PDT