# 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"
  - Previous message: Petter Reinholdtsen: "DBG(0, ...)"
  - Maybe in reply to: Henning Meier-Geinitz: "[dev] Status of pnm.c-bad?"
  - Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

  [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

  - Next message: Sebastien Sable: "Re: [dev] TODO list and time table for 1.0.5"
  - Previous message: Petter Reinholdtsen: "DBG(0, ...)"
  - Maybe in reply to: Henning Meier-Geinitz: "[dev] Status of pnm.c-bad?"
  - Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

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