[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