• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* sane - Scanner Access Now Easy.
2 
3    pie.c
4 
5    Copyright (C) 2000 Simon Munton, based on the umax backend by Oliver Rauch
6 
7    This file is part of the SANE package.
8 
9    This program is free software; you can redistribute it and/or
10    modify it under the terms of the GNU General Public License as
11    published by the Free Software Foundation; either version 2 of the
12    License, or (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful, but
15    WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <https://www.gnu.org/licenses/>.
21 
22    As a special exception, the authors of SANE give permission for
23    additional uses of the libraries contained in this release of SANE.
24 
25    The exception is that, if you link a SANE library with other files
26    to produce an executable, this does not by itself cause the
27    resulting executable to be covered by the GNU General Public
28    License.  Your use of that executable is in no way restricted on
29    account of linking the SANE library code into it.
30 
31    This exception does not, however, invalidate any other reasons why
32    the executable file might be covered by the GNU General Public
33    License.
34 
35    If you submit changes to SANE to the maintainers to be included in
36    a subsequent release, you agree by submitting the changes that
37    those changes may be distributed with this exception intact.
38 
39    If you write modifications of your own for SANE, it is your choice
40    whether to permit this exception to apply to your modifications.
41    If you do not wish that, delete this exception notice.  */
42 
43 /*
44  * 22-2-2003 set devlist to NULL in sane_exit()
45  *           set first_dev to NULL in sane_exit()
46  *           eliminated num_devices
47  *
48  * 23-7-2002 added TL_X > BR_X, TL_Y > BR_Y check in sane_start
49  *
50  * 17-9-2001 changed ADLIB to AdLib as the comparison is case sensitive and
51  * 	     the scanner returns AdLib
52  *
53  * 7-5-2001 removed removal of '\n' after sanei_config_read()
54  *	    free devlist allocated in sane_get_devices() on sane_exit()
55  *
56  * 2-3-2001 improved the reordering of RGB data in pie_reader_process()
57  *
58  * 11-11-2000 eliminated some warnings about signed/unsigned comparisons
59  *            removed #undef NDEBUG and C++ style comments
60  *
61  * 1-10-2000 force gamma table to one to one mapping if lineart or halftone selected
62  *
63  * 30-9-2000 added ADLIB devices to scanner_str[]
64  *
65  * 29-9-2000 wasn't setting 'background is halftone bit' (BGHT) in halftone mode
66  *
67  * 27-9-2000 went public with build 4
68  */
69 
70 #include "../include/sane/config.h"
71 
72 #include <errno.h>
73 #include <fcntl.h>
74 #include <limits.h>
75 #include <signal.h>
76 #include <stdio.h>
77 #include <stdlib.h>
78 #include <string.h>
79 #include <sys/types.h>
80 #include <sys/wait.h>
81 #include <unistd.h>
82 
83 #include "../include/sane/sane.h"
84 #include "../include/sane/sanei.h"
85 #include "../include/sane/saneopts.h"
86 #include "../include/sane/sanei_scsi.h"
87 #include "../include/sane/sanei_debug.h"
88 
89 #define BACKEND_NAME	pie
90 #include "../include/sane/sanei_backend.h"
91 #include "../include/sane/sanei_config.h"
92 
93 # include "../include/sane/sanei_thread.h"
94 
95 #include "pie-scsidef.h"
96 
97 #define DBG_error0  0
98 #define DBG_error   1
99 #define DBG_sense   2
100 #define DBG_warning 3
101 #define DBG_inquiry 4
102 
103 #define DBG_info    5
104 #define DBG_info2   6
105 #define DBG_proc    7
106 #define DBG_read    8
107 #define DBG_sane_init   10
108 #define DBG_sane_proc   11
109 #define DBG_sane_info   12
110 #define DBG_sane_option 13
111 #define DBG_dump	14
112 
113 #define BUILD 9
114 
115 #define PIE_CONFIG_FILE "pie.conf"
116 
117 #define LINEART_STR         SANE_VALUE_SCAN_MODE_LINEART
118 #define HALFTONE_STR        SANE_VALUE_SCAN_MODE_HALFTONE
119 #define GRAY_STR            SANE_VALUE_SCAN_MODE_GRAY
120 #define COLOR_STR           SANE_VALUE_SCAN_MODE_COLOR
121 
122 #define LINEART             1
123 #define HALFTONE            2
124 #define GRAYSCALE           3
125 #define RGB                 4
126 
127 #define CAL_MODE_PREVIEW        (INQ_CAP_FAST_PREVIEW)
128 #define CAL_MODE_FLATBED        0x00
129 #define CAL_MODE_ADF            (INQ_OPT_DEV_ADF)
130 #define CAL_MODE_TRANPSARENCY   (INQ_OPT_DEV_TP)
131 #define CAL_MODE_TRANPSARENCY1  (INQ_OPT_DEV_TP1)
132 
133 #define min(a,b) (((a)<(b))?(a):(b))
134 #define max(a,b) (((a)>(b))?(a):(b))
135 
136 
137 /* names of scanners that are supported because */
138 /* the inquiry_return_block is ok and driver is tested */
139 
140 static char *scanner_str[] = {
141   "DEVCOM", "9636PRO",
142   "DEVCOM", "9636S",
143   "DEVCOM", "9630S",
144   "PIE", "ScanAce 1236S",
145   "PIE", "ScanAce 1230S",
146   "PIE", "ScanAce II",
147   "PIE", "ScanAce III",
148   "PIE", "ScanAce Plus",
149   "PIE", "ScanAce II Plus",
150   "PIE", "ScanAce III Plus",
151   "PIE", "ScanAce V",
152   "PIE", "ScanMedia",
153   "PIE", "ScanMedia II",
154   "PIE", "ScanAce 630S",
155   "PIE", "ScanAce 636S",
156   "AdLib", "JetScan 630",
157   "AdLib", "JetScan 636PRO",
158   "END_OF_LIST"
159 };
160 
161 /* times (in us) to delay after certain commands. Scanner seems to lock up if it returns busy
162  * status and commands are repeatedly reissued (by kernel error handler) */
163 
164 #define DOWNLOAD_GAMMA_WAIT_TIME	(1000000)
165 #define SCAN_WAIT_TIME			(1000000)
166 #define SCAN_WARMUP_WAIT_TIME		(500000)
167 #define TUR_WAIT_TIME			(500000)
168 
169 
170 /* options supported by the scanner */
171 
172 enum Pie_Option
173 {
174   OPT_NUM_OPTS = 0,
175 
176   /* ------------------------------------------- */
177   OPT_MODE_GROUP,
178   OPT_MODE,
179   OPT_RESOLUTION,
180 
181 
182   /* ------------------------------------------- */
183 
184   OPT_GEOMETRY_GROUP,
185   OPT_TL_X,			/* top-left x */
186   OPT_TL_Y,			/* top-left y */
187   OPT_BR_X,			/* bottom-right x */
188   OPT_BR_Y,			/* bottom-right y */
189 
190   /* ------------------------------------------- */
191 
192   OPT_ENHANCEMENT_GROUP,
193 
194   OPT_HALFTONE_PATTERN,
195   OPT_SPEED,
196   OPT_THRESHOLD,
197 
198   OPT_GAMMA_VECTOR,
199   OPT_GAMMA_VECTOR_R,
200   OPT_GAMMA_VECTOR_G,
201   OPT_GAMMA_VECTOR_B,
202 
203   /* ------------------------------------------- */
204 
205   OPT_ADVANCED_GROUP,
206   OPT_PREVIEW,
207 
208   /* must come last: */
209   NUM_OPTIONS
210 };
211 
212 
213 
214 
215 /* This defines the information needed during calibration */
216 
217 struct Pie_cal_info
218 {
219   int cal_type;
220   int receive_bits;
221   int send_bits;
222   int num_lines;
223   int pixels_per_line;
224 };
225 
226 
227 /* This structure holds the information about a physical scanner */
228 
229 typedef struct Pie_Device
230 {
231   struct Pie_Device *next;
232 
233   char *devicename;		/* name of the scanner device */
234 
235   char vendor[9];		/* will be xxxxx */
236   char product[17];		/* e.g. "SuperVista_S12" or so */
237   char version[5];		/* e.g. V1.3 */
238 
239   SANE_Device sane;
240   SANE_Range dpi_range;
241   SANE_Range x_range;
242   SANE_Range y_range;
243 
244   SANE_Range exposure_range;
245   SANE_Range shadow_range;
246   SANE_Range highlight_range;
247 
248   int inquiry_len;		/* length of inquiry return block */
249 
250   int inquiry_x_res;		/* maximum x-resolution */
251   int inquiry_y_res;		/* maximum y-resolution */
252   int inquiry_pixel_resolution;
253   double inquiry_fb_width;	/* flatbed width in inches */
254   double inquiry_fb_length;	/* flatbed length in inches */
255 
256   int inquiry_trans_top_left_x;
257   int inquiry_trans_top_left_y;
258   double inquiry_trans_width;	/* transparency width in inches */
259   double inquiry_trans_length;	/* transparency length in inches */
260 
261   int inquiry_halftones;	/* number of halftones supported */
262   int inquiry_filters;		/* available colour filters */
263   int inquiry_color_depths;	/* available colour depths */
264   int inquiry_color_format;	/* colour format from scanner */
265   int inquiry_image_format;	/* image data format */
266   int inquiry_scan_capability;	/* additional scanner features, number of speeds */
267   int inquiry_optional_devices;	/* optional devices */
268   int inquiry_enhancements;	/* enhancements */
269   int inquiry_gamma_bits;	/* no of bits used for gamma table */
270   int inquiry_fast_preview_res;	/* fast preview resolution */
271   int inquiry_min_highlight;	/* min highlight % that can be used */
272   int inquiry_max_shadow;	/* max shadow % that can be used */
273   int inquiry_cal_eqn;		/* which calibration equation to use */
274   int inquiry_min_exp;		/* min exposure % */
275   int inquiry_max_exp;		/* max exposure % */
276 
277   SANE_String scan_mode_list[7];	/* holds names of types of scan (color, ...) */
278 
279   SANE_String halftone_list[17];	/* holds the names of the halftone patterns from the scanner */
280 
281   SANE_String speed_list[9];	/* holds the names of available speeds */
282 
283   int cal_info_count;		/* number of calibration info sets */
284   struct Pie_cal_info *cal_info;	/* points to the actual calibration information */
285 }
286 Pie_Device;
287 
288 /* This structure holds information about an instance of an 'opened' scanner */
289 
290 typedef struct Pie_Scanner
291 {
292   struct Pie_Scanner *next;
293   Pie_Device *device;		/* pointer to physical scanner */
294 
295   int sfd;			/* scanner file desc. */
296   int bufsize;			/* max scsi buffer size */
297 
298   SANE_Option_Descriptor opt[NUM_OPTIONS];	/* option descriptions for this instance */
299   Option_Value val[NUM_OPTIONS];	/* option settings for this instance */
300   SANE_Int *gamma_table[4];	/* gamma tables for this instance */
301   SANE_Range gamma_range;
302   int gamma_length;		/* size of gamma table */
303 
304   int scanning;			/* true if actually doing a scan */
305   SANE_Parameters params;
306 
307   SANE_Pid reader_pid;
308   int pipe;
309   int reader_fds;
310 
311   int colormode;		/* whether RGB, GRAY, LINEART, HALFTONE */
312   int resolution;
313   int cal_mode;			/* set to value to compare cal_info mode to */
314 
315   int cal_filter;		/* set to indicate which filters will provide data for cal */
316 
317   int filter_offset1;		/* offsets between colors in indexed scan mode */
318   int filter_offset2;
319 
320   int bytes_per_line;		/* number of bytes per line */
321 
322 }
323 Pie_Scanner;
324 
325 static const SANE_Range percentage_range_100 = {
326   0 << SANE_FIXED_SCALE_SHIFT,	/* minimum */
327   100 << SANE_FIXED_SCALE_SHIFT,	/* maximum */
328   0 << SANE_FIXED_SCALE_SHIFT	/* quantization */
329 };
330 
331 static Pie_Device *first_dev = NULL;
332 static Pie_Scanner *first_handle = NULL;
333 static const SANE_Device **devlist = NULL;
334 
335 
336 
337 static SANE_Status pie_wait_scanner (Pie_Scanner * scanner);
338 
339 
340 /* ---------------------------------- PIE DUMP_BUFFER ---------------------------------- */
341 
342 #define DBG_DUMP(level, buf, n)	{ if (DBG_LEVEL >= (level)) pie_dump_buffer(level,buf,n); }
343 
344 
345 static void
pie_dump_buffer(int level,unsigned char * buf,int n)346 pie_dump_buffer (int level, unsigned char *buf, int n)
347 {
348   char s[80], *p = s;
349   int a = 0;
350 
351   while (n--)
352     {
353       if ((a % 16) == 0)
354 	p += sprintf (p, "  %04X  ", a);
355 
356       p += sprintf (p, "%02X ", *buf++);
357 
358       if ((n == 0) || (a % 16) == 15)
359 	{
360 	  DBG (level, "%s\n", s);
361 	  p = s;
362 	}
363       a++;
364     }
365 }
366 
367 /* ---------------------------------- PIE INIT ---------------------------------- */
368 
369 static void
pie_init(Pie_Device * dev)370 pie_init (Pie_Device * dev)	/* pie_init is called once while driver-initialization */
371 {
372   DBG (DBG_proc, "init\n");
373 
374   dev->cal_info_count = 0;
375   dev->cal_info = NULL;
376 
377   dev->devicename = NULL;
378   dev->inquiry_len = 0;
379 
380 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
381   DBG (DBG_info,
382        "variable scsi buffer size (usage of sanei_scsi_open_extended)\n");
383 #else
384   DBG (DBG_info, "fixed scsi buffer size = %d bytes\n",
385        sanei_scsi_max_request_size);
386 #endif
387 }
388 
389 
390 /* ---------------------------- SENSE_HANDLER ------------------------------ */
391 
392 
393 static SANE_Status
sense_handler(__sane_unused__ int scsi_fd,unsigned char * result,__sane_unused__ void * arg)394 sense_handler (__sane_unused__ int scsi_fd, unsigned char *result, __sane_unused__ void *arg)	/* is called by sanei_scsi */
395 {
396   unsigned char asc, ascq, sensekey;
397   int asc_ascq, len;
398   /* Pie_Device *dev = arg; */
399 
400   DBG (DBG_proc, "check condition sense handler\n");
401 
402   sensekey = get_RS_sense_key (result);
403   asc = get_RS_ASC (result);
404   ascq = get_RS_ASCQ (result);
405   asc_ascq = (int) (256 * asc + ascq);
406   len = 7 + get_RS_additional_length (result);
407 
408   if (get_RS_error_code (result) != 0x70)
409     {
410       DBG (DBG_proc, "invalid sense key => handled as DEVICE BUSY!\n");
411       return SANE_STATUS_DEVICE_BUSY;	/* sense key invalid */
412     }
413 
414   DBG (DBG_sense, "check condition sense: %s\n", sense_str[sensekey]);
415 
416   if (get_RS_ILI (result) != 0)
417     {
418       DBG (DBG_sense,
419 	   "-> ILI-ERROR: requested data length is larger than actual length\n");
420     }
421 
422   switch (sensekey)
423     {
424     case 0x00:			/* no sense, could have been busy */
425       return SANE_STATUS_IO_ERROR;
426       break;
427 
428     case 0x02:
429       if (asc_ascq == 0x0401)
430 	DBG (DBG_sense, "-> Not Ready - Warming Up\n");
431       else if (asc_ascq == 0x0483)
432 	DBG (DBG_sense, "-> Not Ready - Need manual service\n");
433       else if (asc_ascq == 0x0881)
434 	DBG (DBG_sense, "-> Not Ready - Communication time out\n");
435       else
436 	DBG (DBG_sense, "-> unknown medium error: asc=%d, ascq=%d\n", asc,
437 	     ascq);
438       break;
439 
440     case 0x03:			/* medium error */
441       if (asc_ascq == 0x5300)
442 	DBG (DBG_sense, "-> Media load or eject failure\n");
443       else if (asc_ascq == 0x3a00)
444 	DBG (DBG_sense, "-> Media not present\n");
445       else if (asc_ascq == 0x3b05)
446 	DBG (DBG_sense, "-> Paper jam\n");
447       else if (asc_ascq == 0x3a80)
448 	DBG (DBG_sense, "-> ADF paper out\n");
449       else
450 	DBG (DBG_sense, "-> unknown medium error: asc=%d, ascq=%d\n", asc,
451 	     ascq);
452       break;
453 
454 
455     case 0x04:			/* hardware error */
456       if (asc_ascq == 0x4081)
457 	DBG (DBG_sense, "-> CPU RAM failure\n");
458       else if (asc_ascq == 0x4082)
459 	DBG (DBG_sense, "-> Scanning system RAM failure\n");
460       else if (asc_ascq == 0x4083)
461 	DBG (DBG_sense, "-> Image buffer failure\n");
462       else if (asc_ascq == 0x0403)
463 	DBG (DBG_sense, "-> Manual intervention required\n");
464       else if (asc_ascq == 0x6200)
465 	DBG (DBG_sense, "-> Scan head position error\n");
466       else if (asc_ascq == 0x6000)
467 	DBG (DBG_sense, "-> Lamp or CCD failure\n");
468       else if (asc_ascq == 0x6081)
469 	DBG (DBG_sense, "-> Transparency lamp failure\n");
470       else if (asc_ascq == 0x8180)
471 	DBG (DBG_sense, "-> DC offset or black level calibration failure\n");
472       else if (asc_ascq == 0x8181)
473 	DBG (DBG_sense,
474 	     "-> Integration time adjustment failure (too light)\n");
475       else if (asc_ascq == 0x8182)
476 	DBG (DBG_sense,
477 	     "-> Integration time adjustment failure (too dark)\n");
478       else if (asc_ascq == 0x8183)
479 	DBG (DBG_sense, "-> Shading curve adjustment failure\n");
480       else if (asc_ascq == 0x8184)
481 	DBG (DBG_sense, "-> Gain adjustment failure\n");
482       else if (asc_ascq == 0x8185)
483 	DBG (DBG_sense, "-> Optical alignment failure\n");
484       else if (asc_ascq == 0x8186)
485 	DBG (DBG_sense, "-> Optical locating failure\n");
486       else if (asc_ascq == 0x8187)
487 	DBG (DBG_sense, "-> Scan pixel map less than 5100 pixels!\n");
488       else if (asc_ascq == 0x4700)
489 	DBG (DBG_sense, "-> Parity error on SCSI bus\n");
490       else if (asc_ascq == 0x4b00)
491 	DBG (DBG_sense, "-> Data phase error\n");
492       else
493 	DBG (DBG_sense, "-> unknown hardware error: asc=%d, ascq=%d\n", asc,
494 	     ascq);
495       return SANE_STATUS_IO_ERROR;
496       break;
497 
498 
499     case 0x05:			/* illegal request */
500       if (asc_ascq == 0x1a00)
501 	DBG (DBG_sense, "-> Parameter list length error\n");
502       else if (asc_ascq == 0x2c01)
503 	DBG (DBG_sense, "-> Too many windows specified\n");
504       else if (asc_ascq == 0x2c02)
505 	DBG (DBG_sense, "-> Invalid combination of windows\n");
506       else if (asc_ascq == 0x2c81)
507 	DBG (DBG_sense, "-> Illegal scanning frame\n");
508       else if (asc_ascq == 0x2400)
509 	DBG (DBG_sense, "-> Invalid field in CDB\n");
510       else if (asc_ascq == 0x2481)
511 	DBG (DBG_sense, "-> Request too many lines of data\n");
512       else if (asc_ascq == 0x2000)
513 	DBG (DBG_sense, "-> Invalid command OP code\n");
514       else if (asc_ascq == 0x2501)
515 	DBG (DBG_sense, "-> LUN not supported\n");
516       else if (asc_ascq == 0x2601)
517 	DBG (DBG_sense, "-> Parameter not supported\n");
518       else if (asc_ascq == 0x2602)
519 	DBG (DBG_sense,
520 	     "-> Parameter value invalid - Parameter not specified\n");
521       else if (asc_ascq == 0x2603)
522 	DBG (DBG_sense, "-> Parameter value invalid - Invalid threshold\n");
523       else if (asc_ascq == 0x2680)
524 	DBG (DBG_sense,
525 	     "-> Parameter value invalid - Control command sequence error\n");
526       else if (asc_ascq == 0x2681)
527 	DBG (DBG_sense,
528 	     "-> Parameter value invalid - Grain setting (halftone pattern\n");
529       else if (asc_ascq == 0x2682)
530 	DBG (DBG_sense,
531 	     "-> Parameter value invalid - Illegal resolution setting\n");
532       else if (asc_ascq == 0x2683)
533 	DBG (DBG_sense,
534 	     "-> Parameter value invalid - Invalid filter assignment\n");
535       else if (asc_ascq == 0x2684)
536 	DBG (DBG_sense,
537 	     "-> Parameter value invalid - Illegal gamma adjustment setting (look-up table)\n");
538       else if (asc_ascq == 0x2685)
539 	DBG (DBG_sense,
540 	     "-> Parameter value invalid - Illegal offset setting (digital brightness)\n");
541       else if (asc_ascq == 0x2686)
542 	DBG (DBG_sense,
543 	     "-> Parameter value invalid - Illegal bits per pixel setting\n");
544       else if (asc_ascq == 0x2687)
545 	DBG (DBG_sense,
546 	     "-> Parameter value invalid - Illegal contrast setting\n");
547       else if (asc_ascq == 0x2688)
548 	DBG (DBG_sense,
549 	     "-> Parameter value invalid - Illegal paper length setting\n");
550       else if (asc_ascq == 0x2689)
551 	DBG (DBG_sense,
552 	     "-> Parameter value invalid - Illegal highlight/shadow setting\n");
553       else if (asc_ascq == 0x268a)
554 	DBG (DBG_sense,
555 	     "-> Parameter value invalid - Illegal exposure time setting (analog brightness)\n");
556       else if (asc_ascq == 0x268b)
557 	DBG (DBG_sense,
558 	     "-> Parameter value invalid - Invalid device select or device not exist\n");
559       else if (asc_ascq == 0x268c)
560 	DBG (DBG_sense,
561 	     "-> Parameter value invalid - Illegal color packing\n");
562       else if (asc_ascq == 0x3d00)
563 	DBG (DBG_sense, "-> Invalid bits in identify field\n");
564 
565 
566 
567       else if (asc_ascq == 0x4900)
568 	DBG (DBG_sense, "-> Invalid message\n");
569       else if (asc_ascq == 0x8101)
570 	DBG (DBG_sense, "-> Not enough memory for color packing\n");
571 
572       if (len >= 0x11)
573 	{
574 	  if (get_RS_SKSV (result) != 0)
575 	    {
576 	      if (get_RS_CD (result) == 0)
577 		{
578 
579 		  DBG (DBG_sense, "-> illegal parameter in CDB\n");
580 		}
581 	      else
582 		{
583 		  DBG (DBG_sense,
584 		       "-> illegal parameter is in the data parameters sent during data out phase\n");
585 		}
586 
587 	      DBG (DBG_sense, "-> error detected in byte %d\n",
588 		   get_RS_field_pointer (result));
589 	    }
590 	}
591       return SANE_STATUS_IO_ERROR;
592       break;
593 
594 
595     case 0x06:			/* unit attention */
596       if (asc_ascq == 0x2900)
597 	DBG (DBG_sense, "-> power on, reset or bus device reset\n");
598       if (asc_ascq == 0x8200)
599 	DBG (DBG_sense,
600 	     "-> unit attention - calibration disable not granted\n");
601       if (asc_ascq == 0x8300)
602 	DBG (DBG_sense, "-> unit attention - calibration will be ignored\n");
603       else
604 	DBG (DBG_sense, "-> unit attention: asc=%d, ascq=%d\n", asc, ascq);
605       break;
606 
607 
608     case 0x09:			/* vendor specific */
609       DBG (DBG_sense, "-> vendor specific sense-code: asc=%d, ascq=%d\n", asc,
610 	   ascq);
611       break;
612 
613     case 0x0b:
614       if (asc_ascq == 0x0006)
615 	DBG (DBG_sense, "-> Received ABORT message from initiator\n");
616       if (asc_ascq == 0x4800)
617 	DBG (DBG_sense, "-> Initiator detected error message received\n");
618       if (asc_ascq == 0x4300)
619 	DBG (DBG_sense, "-> Message error\n");
620       if (asc_ascq == 0x4500)
621 	DBG (DBG_sense, "-> Select or re-select error\n");
622       else
623 	DBG (DBG_sense, "-> aborted command: asc=%d, ascq=%d\n", asc, ascq);
624       break;
625 
626     }
627 
628   return SANE_STATUS_IO_ERROR;
629 }
630 
631 
632 /* -------------------------------- PIE PRINT INQUIRY ------------------------- */
633 
634 
635 static void
pie_print_inquiry(Pie_Device * dev)636 pie_print_inquiry (Pie_Device * dev)
637 {
638   DBG (DBG_inquiry, "INQUIRY:\n");
639   DBG (DBG_inquiry, "========\n");
640   DBG (DBG_inquiry, "\n");
641   DBG (DBG_inquiry, "vendor........................: '%s'\n", dev->vendor);
642   DBG (DBG_inquiry, "product.......................: '%s'\n", dev->product);
643   DBG (DBG_inquiry, "version.......................: '%s'\n", dev->version);
644 
645   DBG (DBG_inquiry, "X resolution..................: %d dpi\n",
646        dev->inquiry_x_res);
647   DBG (DBG_inquiry, "Y resolution..................: %d dpi\n",
648        dev->inquiry_y_res);
649   DBG (DBG_inquiry, "pixel resolution..............: %d dpi\n",
650        dev->inquiry_pixel_resolution);
651   DBG (DBG_inquiry, "fb width......................: %f in\n",
652        dev->inquiry_fb_width);
653   DBG (DBG_inquiry, "fb length.....................: %f in\n",
654        dev->inquiry_fb_length);
655 
656   DBG (DBG_inquiry, "transparency width............: %f in\n",
657        dev->inquiry_trans_width);
658   DBG (DBG_inquiry, "transparency length...........: %f in\n",
659        dev->inquiry_trans_length);
660   DBG (DBG_inquiry, "transparency offset...........: %d,%d\n",
661        dev->inquiry_trans_top_left_x, dev->inquiry_trans_top_left_y);
662 
663   DBG (DBG_inquiry, "# of halftones................: %d\n",
664        dev->inquiry_halftones);
665 
666   DBG (DBG_inquiry, "One pass color................: %s\n",
667        dev->inquiry_filters & INQ_ONE_PASS_COLOR ? "yes" : "no");
668 
669   DBG (DBG_inquiry, "Filters.......................: %s%s%s%s (%02x)\n",
670        dev->inquiry_filters & INQ_FILTER_RED ? "Red " : "",
671        dev->inquiry_filters & INQ_FILTER_GREEN ? "Green " : "",
672        dev->inquiry_filters & INQ_FILTER_BLUE ? "Blue " : "",
673        dev->inquiry_filters & INQ_FILTER_NEUTRAL ? "Neutral " : "",
674        dev->inquiry_filters);
675 
676   DBG (DBG_inquiry, "Color depths..................: %s%s%s%s%s%s (%02x)\n",
677        dev->inquiry_color_depths & INQ_COLOR_DEPTH_16 ? "16 bit " : "",
678        dev->inquiry_color_depths & INQ_COLOR_DEPTH_12 ? "12 bit " : "",
679        dev->inquiry_color_depths & INQ_COLOR_DEPTH_10 ? "10 bit " : "",
680        dev->inquiry_color_depths & INQ_COLOR_DEPTH_8 ? "8 bit " : "",
681        dev->inquiry_color_depths & INQ_COLOR_DEPTH_4 ? "4 bit " : "",
682        dev->inquiry_color_depths & INQ_COLOR_DEPTH_1 ? "1 bit " : "",
683        dev->inquiry_color_depths);
684 
685   DBG (DBG_inquiry, "Color Format..................: %s%s%s (%02x)\n",
686        dev->inquiry_color_format & INQ_COLOR_FORMAT_INDEX ? "Indexed " : "",
687        dev->inquiry_color_format & INQ_COLOR_FORMAT_LINE ? "Line " : "",
688        dev->inquiry_color_format & INQ_COLOR_FORMAT_PIXEL ? "Pixel " : "",
689        dev->inquiry_color_format);
690 
691   DBG (DBG_inquiry, "Image Format..................: %s%s%s%s (%02x)\n",
692        dev->inquiry_image_format & INQ_IMG_FMT_OKLINE ? "OKLine " : "",
693        dev->inquiry_image_format & INQ_IMG_FMT_BLK_ONE ? "BlackOne " : "",
694        dev->inquiry_image_format & INQ_IMG_FMT_MOTOROLA ? "Motorola " : "",
695        dev->inquiry_image_format & INQ_IMG_FMT_INTEL ? "Intel" : "",
696        dev->inquiry_image_format);
697 
698   DBG (DBG_inquiry,
699        "Scan Capability...............: %s%s%s%s%d speeds (%02x)\n",
700        dev->inquiry_scan_capability & INQ_CAP_PWRSAV ? "PowerSave " : "",
701        dev->inquiry_scan_capability & INQ_CAP_EXT_CAL ? "ExtCal " : "",
702        dev->inquiry_scan_capability & INQ_CAP_FAST_PREVIEW ? "FastPreview" :
703        "",
704        dev->inquiry_scan_capability & INQ_CAP_DISABLE_CAL ? "DisCal " : "",
705        dev->inquiry_scan_capability & INQ_CAP_SPEEDS,
706        dev->inquiry_scan_capability);
707 
708   DBG (DBG_inquiry, "Optional Devices..............: %s%s%s%s (%02x)\n",
709        dev->inquiry_optional_devices & INQ_OPT_DEV_MPCL ? "MultiPageLoad " :
710        "",
711        dev->inquiry_optional_devices & INQ_OPT_DEV_TP1 ? "TransModule1 " : "",
712        dev->inquiry_optional_devices & INQ_OPT_DEV_TP ? "TransModule " : "",
713        dev->inquiry_optional_devices & INQ_OPT_DEV_ADF ? "ADF " : "",
714        dev->inquiry_optional_devices);
715 
716   DBG (DBG_inquiry, "Enhancement...................: %02x\n",
717        dev->inquiry_enhancements);
718   DBG (DBG_inquiry, "Gamma bits....................: %d\n",
719        dev->inquiry_gamma_bits);
720 
721   DBG (DBG_inquiry, "Fast Preview Resolution.......: %d\n",
722        dev->inquiry_fast_preview_res);
723   DBG (DBG_inquiry, "Min Highlight.................: %d\n",
724        dev->inquiry_min_highlight);
725   DBG (DBG_inquiry, "Max Shadow....................: %d\n",
726        dev->inquiry_max_shadow);
727   DBG (DBG_inquiry, "Cal Eqn.......................: %d\n",
728        dev->inquiry_cal_eqn);
729   DBG (DBG_inquiry, "Min Exposure..................: %d\n",
730        dev->inquiry_min_exp);
731   DBG (DBG_inquiry, "Max Exposure..................: %d\n",
732        dev->inquiry_max_exp);
733 }
734 
735 
736 /* ------------------------------ PIE GET INQUIRY VALUES -------------------- */
737 
738 
739 static void
pie_get_inquiry_values(Pie_Device * dev,unsigned char * buffer)740 pie_get_inquiry_values (Pie_Device * dev, unsigned char *buffer)
741 {
742   DBG (DBG_proc, "get_inquiry_values\n");
743 
744   dev->inquiry_len = get_inquiry_additional_length (buffer) + 5;
745 
746   get_inquiry_vendor ((char *) buffer, dev->vendor);
747   get_inquiry_product ((char *) buffer, dev->product);
748   get_inquiry_version ((char *) buffer, dev->version);
749 
750   dev->inquiry_x_res = get_inquiry_max_x_res (buffer);
751   dev->inquiry_y_res = get_inquiry_max_y_res (buffer);
752 
753   if (dev->inquiry_y_res < 256)
754     {
755       /* y res is a multiplier */
756       dev->inquiry_pixel_resolution = dev->inquiry_x_res;
757       dev->inquiry_x_res *= dev->inquiry_y_res;
758       dev->inquiry_y_res = dev->inquiry_x_res;
759     }
760   else
761     {
762       /* y res really is resolution */
763       dev->inquiry_pixel_resolution =
764 	min (dev->inquiry_x_res, dev->inquiry_y_res);
765     }
766 
767   dev->inquiry_fb_width =
768     (double) get_inquiry_fb_max_scan_width (buffer) /
769     dev->inquiry_pixel_resolution;
770   dev->inquiry_fb_length =
771     (double) get_inquiry_fb_max_scan_length (buffer) /
772     dev->inquiry_pixel_resolution;
773 
774   dev->inquiry_trans_top_left_x = get_inquiry_trans_x1 (buffer);
775   dev->inquiry_trans_top_left_y = get_inquiry_trans_y1 (buffer);
776 
777   dev->inquiry_trans_width =
778     (double) (get_inquiry_trans_x2 (buffer) -
779 	      get_inquiry_trans_x1 (buffer)) / dev->inquiry_pixel_resolution;
780   dev->inquiry_trans_length =
781     (double) (get_inquiry_trans_y2 (buffer) -
782 	      get_inquiry_trans_y1 (buffer)) / dev->inquiry_pixel_resolution;
783 
784   dev->inquiry_halftones = get_inquiry_halftones (buffer) & 0x0f;
785 
786   dev->inquiry_filters = get_inquiry_filters (buffer);
787   dev->inquiry_color_depths = get_inquiry_color_depths (buffer);
788   dev->inquiry_color_format = get_inquiry_color_format (buffer);
789   dev->inquiry_image_format = get_inquiry_image_format (buffer);
790 
791   dev->inquiry_scan_capability = get_inquiry_scan_capability (buffer);
792   dev->inquiry_optional_devices = get_inquiry_optional_devices (buffer);
793   dev->inquiry_enhancements = get_inquiry_enhancements (buffer);
794   dev->inquiry_gamma_bits = get_inquiry_gamma_bits (buffer);
795   dev->inquiry_fast_preview_res = get_inquiry_fast_preview_res (buffer);
796   dev->inquiry_min_highlight = get_inquiry_min_highlight (buffer);
797   dev->inquiry_max_shadow = get_inquiry_max_shadow (buffer);
798   dev->inquiry_cal_eqn = get_inquiry_cal_eqn (buffer);
799   dev->inquiry_min_exp = get_inquiry_min_exp (buffer);
800   dev->inquiry_max_exp = get_inquiry_max_exp (buffer);
801 
802   pie_print_inquiry (dev);
803 
804   return;
805 }
806 
807 /* ----------------------------- PIE DO INQUIRY ---------------------------- */
808 
809 
810 static void
pie_do_inquiry(int sfd,unsigned char * buffer)811 pie_do_inquiry (int sfd, unsigned char *buffer)
812 {
813   size_t size;
814   SANE_Status status;
815 
816   DBG (DBG_proc, "do_inquiry\n");
817   memset (buffer, '\0', 256);	/* clear buffer */
818 
819   size = 5;
820 
821   set_inquiry_return_size (inquiry.cmd, size);	/* first get only 5 bytes to get size of inquiry_return_block */
822   status = sanei_scsi_cmd (sfd, inquiry.cmd, inquiry.size, buffer, &size);
823   if (status)
824     {
825       DBG (DBG_error, "pie_do_inquiry: command returned status %s\n",
826 	   sane_strstatus (status));
827     }
828 
829   size = get_inquiry_additional_length (buffer) + 5;
830 
831   set_inquiry_return_size (inquiry.cmd, size);	/* then get inquiry with actual size */
832   status = sanei_scsi_cmd (sfd, inquiry.cmd, inquiry.size, buffer, &size);
833   if (status)
834     {
835       DBG (DBG_error, "pie_do_inquiry: command returned status %s\n",
836 	   sane_strstatus (status));
837     }
838 }
839 
840 /* ---------------------- PIE IDENTIFY SCANNER ---------------------- */
841 
842 
843 static int
pie_identify_scanner(Pie_Device * dev,int sfd)844 pie_identify_scanner (Pie_Device * dev, int sfd)
845 {
846   char vendor[9];
847   char product[0x11];
848   char version[5];
849   char *pp;
850   int i = 0;
851   unsigned char inquiry_block[256];
852 
853   DBG (DBG_proc, "identify_scanner\n");
854 
855   pie_do_inquiry (sfd, inquiry_block);	/* get inquiry */
856 
857   if (get_inquiry_periph_devtype (inquiry_block) != IN_periph_devtype_scanner)
858     {
859       return 1;
860     }				/* no scanner */
861 
862   get_inquiry_vendor ((char *) inquiry_block, vendor);
863   get_inquiry_product ((char *) inquiry_block, product);
864   get_inquiry_version ((char *) inquiry_block, version);
865 
866   pp = &vendor[8];
867   vendor[8] = ' ';
868   while (*pp == ' ')
869     {
870       *pp-- = '\0';
871     }
872 
873   pp = &product[0x10];
874   product[0x10] = ' ';
875   while (*pp == ' ')
876     {
877       *pp-- = '\0';
878     }
879 
880   pp = &version[4];
881 
882   version[4] = ' ';
883   while (*pp == ' ')
884     {
885       *pp-- = '\0';
886     }
887 
888   DBG (DBG_info, "Found %s scanner %s version %s on device %s\n", vendor,
889        product, version, dev->devicename);
890 
891   while (strncmp ("END_OF_LIST", scanner_str[2 * i], 11) != 0)	/* Now identify full supported scanners */
892     {
893       if (!strncmp (vendor, scanner_str[2 * i], strlen (scanner_str[2 * i])))
894 	{
895 	  if (!strncmp
896 	      (product, scanner_str[2 * i + 1],
897 	       strlen (scanner_str[2 * i + 1])))
898 	    {
899 	      DBG (DBG_info, "found supported scanner\n");
900 
901 	      pie_get_inquiry_values (dev, inquiry_block);
902 	      return 0;
903 	    }
904 	}
905       i++;
906     }
907 
908   return 1;			/* NO SUPPORTED SCANNER: short inquiry-block and unknown scanner */
909 }
910 
911 
912 /* ------------------------------- GET SPEEDS ----------------------------- */
913 
914 static void
pie_get_speeds(Pie_Device * dev)915 pie_get_speeds (Pie_Device * dev)
916 {
917   int speeds = dev->inquiry_scan_capability & INQ_CAP_SPEEDS;
918 
919   DBG (DBG_proc, "get_speeds\n");
920 
921   if (speeds == 3)
922     {
923       dev->speed_list[0] = strdup ("Normal");
924       dev->speed_list[1] = strdup ("Fine");
925       dev->speed_list[2] = strdup ("Pro");
926       dev->speed_list[3] = NULL;
927     }
928   else
929     {
930       int i;
931       char buf[2];
932 
933       buf[1] = '\0';
934 
935       for (i = 0; i < speeds; i++)
936 	{
937 	  buf[0] = '1' + i;
938 	  dev->speed_list[i] = strdup (buf);
939 	}
940 
941       dev->speed_list[i] = NULL;
942     }
943 }
944 
945 /* ------------------------------- GET HALFTONES ----------------------------- */
946 
947 static void
pie_get_halftones(Pie_Device * dev,int sfd)948 pie_get_halftones (Pie_Device * dev, int sfd)
949 {
950   int i;
951   size_t size;
952   SANE_Status status;
953   unsigned char *data;
954   unsigned char buffer[128];
955 
956   DBG (DBG_proc, "get_halftones\n");
957 
958   for (i = 0; i < dev->inquiry_halftones; i++)
959     {
960       size = 6;
961 
962       set_write_length (swrite.cmd, size);
963 
964       memcpy (buffer, swrite.cmd, swrite.size);
965 
966       data = buffer + swrite.size;
967       memset (data, 0, size);
968 
969       set_command (data, READ_HALFTONE);
970       set_data_length (data, 2);
971       data[4] = i;
972 
973       status = sanei_scsi_cmd (sfd, buffer, swrite.size + size, NULL, NULL);
974       if (status)
975 	{
976 	  DBG (DBG_error,
977 	       "pie_get_halftones: write command returned status %s\n",
978 	       sane_strstatus (status));
979 	}
980       else
981 	{
982 	  /* now read the halftone data */
983 	  memset (buffer, '\0', sizeof buffer);	/* clear buffer */
984 
985 	  size = 128;
986 	  set_read_length (sread.cmd, size);
987 
988 	  DBG (DBG_info, "doing read\n");
989 	  status = sanei_scsi_cmd (sfd, sread.cmd, sread.size, buffer, &size);
990 	  if (status)
991 	    {
992 	      DBG (DBG_error,
993 		   "pie_get_halftones: read command returned status %s\n",
994 		   sane_strstatus (status));
995 	    }
996 	  else
997 	    {
998 	      unsigned char *s;
999 
1000 	      s = buffer + 8 + buffer[6] * buffer[7];
1001 
1002 	      DBG (DBG_info, "halftone %d: %s\n", i, s);
1003 
1004 	      dev->halftone_list[i] = strdup ((char *)s);
1005 	    }
1006 	}
1007     }
1008   dev->halftone_list[i] = NULL;
1009 }
1010 
1011 /* ------------------------------- GET CAL DATA ----------------------------- */
1012 
1013 static void
pie_get_cal_info(Pie_Device * dev,int sfd)1014 pie_get_cal_info (Pie_Device * dev, int sfd)
1015 {
1016   size_t size;
1017   SANE_Status status;
1018   unsigned char *data;
1019   unsigned char buffer[280];
1020 
1021   DBG (DBG_proc, "get_cal_info\n");
1022 
1023   if (!(dev->inquiry_scan_capability & INQ_CAP_EXT_CAL))
1024     return;
1025 
1026   size = 6;
1027 
1028   set_write_length (swrite.cmd, size);
1029 
1030   memcpy (buffer, swrite.cmd, swrite.size);
1031 
1032   data = buffer + swrite.size;
1033   memset (data, 0, size);
1034 
1035   set_command (data, READ_CAL_INFO);
1036 
1037   status = sanei_scsi_cmd (sfd, buffer, swrite.size + size, NULL, NULL);
1038   if (status)
1039     {
1040       DBG (DBG_error, "pie_get_cal_info: write command returned status %s\n",
1041 	   sane_strstatus (status));
1042     }
1043   else
1044     {
1045       /* now read the cal data */
1046       memset (buffer, '\0', sizeof buffer);	/* clear buffer */
1047 
1048       size = 128;
1049       set_read_length (sread.cmd, size);
1050 
1051       DBG (DBG_info, "doing read\n");
1052       status = sanei_scsi_cmd (sfd, sread.cmd, sread.size, buffer, &size);
1053       if (status)
1054 	{
1055 	  DBG (DBG_error,
1056 	       "pie_get_cal_info: read command returned status %s\n",
1057 	       sane_strstatus (status));
1058 	}
1059       else
1060 	{
1061 	  int i;
1062 
1063 	  dev->cal_info_count = buffer[4];
1064 	  dev->cal_info =
1065 	    malloc (sizeof (struct Pie_cal_info) * dev->cal_info_count);
1066 
1067 	  for (i = 0; i < dev->cal_info_count; i++)
1068 	    {
1069 	      dev->cal_info[i].cal_type = buffer[8 + i * buffer[5]];
1070 	      dev->cal_info[i].send_bits = buffer[9 + i * buffer[5]];
1071 	      dev->cal_info[i].receive_bits = buffer[10 + i * buffer[5]];
1072 	      dev->cal_info[i].num_lines = buffer[11 + i * buffer[5]];
1073 	      dev->cal_info[i].pixels_per_line =
1074 		(buffer[13 + i * buffer[5]] << 8) + buffer[12 +
1075 							   i * buffer[5]];
1076 
1077 	      DBG (DBG_info2, "%02x %2d %2d %2d %d\n",
1078 		   dev->cal_info[i].cal_type, dev->cal_info[i].send_bits,
1079 		   dev->cal_info[i].receive_bits, dev->cal_info[i].num_lines,
1080 		   dev->cal_info[i].pixels_per_line);
1081 	    }
1082 	}
1083     }
1084 }
1085 
1086 /* ------------------------------- ATTACH SCANNER ----------------------------- */
1087 
1088 static SANE_Status
attach_scanner(const char * devicename,Pie_Device ** devp)1089 attach_scanner (const char *devicename, Pie_Device ** devp)
1090 {
1091   Pie_Device *dev;
1092   int sfd;
1093   int bufsize;
1094 
1095   DBG (DBG_sane_proc, "attach_scanner: %s\n", devicename);
1096 
1097   for (dev = first_dev; dev; dev = dev->next)
1098     {
1099       if (strcmp (dev->sane.name, devicename) == 0)
1100 	{
1101 	  if (devp)
1102 	    {
1103 	      *devp = dev;
1104 	    }
1105 	  return SANE_STATUS_GOOD;
1106 	}
1107     }
1108 
1109   dev = malloc (sizeof (*dev));
1110   if (!dev)
1111     {
1112       return SANE_STATUS_NO_MEM;
1113     }
1114 
1115   DBG (DBG_info, "attach_scanner: opening %s\n", devicename);
1116 
1117 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
1118   bufsize = 16384;		/* 16KB */
1119 
1120   if (sanei_scsi_open_extended
1121       (devicename, &sfd, sense_handler, dev, &bufsize) != 0)
1122     {
1123       DBG (DBG_error, "attach_scanner: open failed\n");
1124       free (dev);
1125       return SANE_STATUS_INVAL;
1126     }
1127 
1128   if (bufsize < 4096)		/* < 4KB */
1129     {
1130       DBG (DBG_error,
1131 	   "attach_scanner: sanei_scsi_open_extended returned too small scsi buffer (%d)\n",
1132 	   bufsize);
1133       sanei_scsi_close (sfd);
1134       free (dev);
1135       return SANE_STATUS_NO_MEM;
1136     }
1137 
1138   DBG (DBG_info,
1139        "attach_scanner: sanei_scsi_open_extended returned scsi buffer size = %d\n",
1140        bufsize);
1141 #else
1142   bufsize = sanei_scsi_max_request_size;
1143 
1144   if (sanei_scsi_open (devicename, &sfd, sense_handler, dev) != 0)
1145     {
1146       DBG (DBG_error, "attach_scanner: open failed\n");
1147       free (dev);
1148 
1149       return SANE_STATUS_INVAL;
1150 
1151     }
1152 #endif
1153 
1154   pie_init (dev);		/* preset values in structure dev */
1155 
1156   dev->devicename = strdup (devicename);
1157 
1158   if (pie_identify_scanner (dev, sfd) != 0)
1159     {
1160       DBG (DBG_error, "attach_scanner: scanner-identification failed\n");
1161       sanei_scsi_close (sfd);
1162       free (dev);
1163       return SANE_STATUS_INVAL;
1164     }
1165 
1166   pie_get_halftones (dev, sfd);
1167   pie_get_cal_info (dev, sfd);
1168   pie_get_speeds (dev);
1169 
1170   dev->scan_mode_list[0] = COLOR_STR;
1171   dev->scan_mode_list[1] = GRAY_STR;
1172   dev->scan_mode_list[2] = LINEART_STR;
1173   dev->scan_mode_list[3] = HALFTONE_STR;
1174   dev->scan_mode_list[4] = 0;
1175 
1176   sanei_scsi_close (sfd);
1177 
1178   dev->sane.name = dev->devicename;
1179   dev->sane.vendor = dev->vendor;
1180   dev->sane.model = dev->product;
1181   dev->sane.type = "flatbed scanner";
1182 
1183   dev->x_range.min = SANE_FIX (0);
1184   dev->x_range.quant = SANE_FIX (0);
1185   dev->x_range.max = SANE_FIX (dev->inquiry_fb_width * MM_PER_INCH);
1186 
1187   dev->y_range.min = SANE_FIX (0);
1188   dev->y_range.quant = SANE_FIX (0);
1189   dev->y_range.max = SANE_FIX (dev->inquiry_fb_length * MM_PER_INCH);
1190 
1191   dev->dpi_range.min = SANE_FIX (25);
1192   dev->dpi_range.quant = SANE_FIX (1);
1193   dev->dpi_range.max =
1194     SANE_FIX (max (dev->inquiry_x_res, dev->inquiry_y_res));
1195 
1196   dev->shadow_range.min = SANE_FIX (0);
1197   dev->shadow_range.quant = SANE_FIX (1);
1198   dev->shadow_range.max = SANE_FIX (dev->inquiry_max_shadow);
1199 
1200   dev->highlight_range.min = SANE_FIX (dev->inquiry_min_highlight);
1201   dev->highlight_range.quant = SANE_FIX (1);
1202   dev->highlight_range.max = SANE_FIX (100);
1203 
1204   dev->exposure_range.min = SANE_FIX (dev->inquiry_min_exp);
1205   dev->exposure_range.quant = SANE_FIX (1);
1206   dev->exposure_range.max = SANE_FIX (dev->inquiry_max_exp);
1207 
1208 #if 0
1209   dev->analog_gamma_range.min = SANE_FIX (1.0);
1210   dev->analog_gamma_range.quant = SANE_FIX (0.01);
1211   dev->analog_gamma_range.max = SANE_FIX (2.0);
1212 
1213 #endif
1214 
1215   dev->next = first_dev;
1216   first_dev = dev;
1217 
1218   if (devp)
1219     {
1220       *devp = dev;
1221     }
1222 
1223   return SANE_STATUS_GOOD;
1224 }
1225 
1226 /* --------------------------- MAX STRING SIZE ---------------------------- */
1227 
1228 
1229 static size_t
max_string_size(SANE_String_Const strings[])1230 max_string_size (SANE_String_Const strings[])
1231 {
1232   size_t size, max_size = 0;
1233   int i;
1234 
1235   for (i = 0; strings[i]; ++i)
1236     {
1237       size = strlen (strings[i]) + 1;
1238       if (size > max_size)
1239 	{
1240 	  max_size = size;
1241 	}
1242     }
1243 
1244   return max_size;
1245 }
1246 
1247 
1248 /* --------------------------- INIT OPTIONS ------------------------------- */
1249 
1250 
1251 static SANE_Status
init_options(Pie_Scanner * scanner)1252 init_options (Pie_Scanner * scanner)
1253 {
1254   int i;
1255 
1256   DBG (DBG_sane_proc, "init_options\n");
1257 
1258   memset (scanner->opt, 0, sizeof (scanner->opt));
1259   memset (scanner->val, 0, sizeof (scanner->val));
1260 
1261   for (i = 0; i < NUM_OPTIONS; ++i)
1262     {
1263       scanner->opt[i].size = sizeof (SANE_Word);
1264       scanner->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1265     }
1266 
1267   scanner->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
1268   scanner->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
1269   scanner->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
1270   scanner->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
1271   scanner->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
1272 
1273   /* "Mode" group: */
1274   scanner->opt[OPT_MODE_GROUP].title = "Scan Mode";
1275   scanner->opt[OPT_MODE_GROUP].desc = "";
1276   scanner->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
1277   scanner->opt[OPT_MODE_GROUP].cap = 0;
1278   scanner->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1279 
1280   /* scan mode */
1281   scanner->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
1282   scanner->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
1283   scanner->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
1284   scanner->opt[OPT_MODE].type = SANE_TYPE_STRING;
1285   scanner->opt[OPT_MODE].size =
1286     max_string_size ((SANE_String_Const *) scanner->device->scan_mode_list);
1287   scanner->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1288   scanner->opt[OPT_MODE].constraint.string_list =
1289     (SANE_String_Const *) scanner->device->scan_mode_list;
1290   scanner->val[OPT_MODE].s =
1291     (SANE_Char *) strdup (scanner->device->scan_mode_list[0]);
1292 
1293   /* x-resolution */
1294   scanner->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
1295   scanner->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
1296   scanner->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
1297   scanner->opt[OPT_RESOLUTION].type = SANE_TYPE_FIXED;
1298   scanner->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
1299   scanner->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
1300   scanner->opt[OPT_RESOLUTION].constraint.range = &scanner->device->dpi_range;
1301   scanner->val[OPT_RESOLUTION].w = 100 << SANE_FIXED_SCALE_SHIFT;
1302 
1303   /* "Geometry" group: */
1304 
1305   scanner->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
1306   scanner->opt[OPT_GEOMETRY_GROUP].desc = "";
1307   scanner->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
1308   scanner->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
1309   scanner->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1310 
1311   /* top-left x */
1312   scanner->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
1313   scanner->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
1314   scanner->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
1315   scanner->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
1316   scanner->opt[OPT_TL_X].unit = SANE_UNIT_MM;
1317   scanner->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1318   scanner->opt[OPT_TL_X].constraint.range = &(scanner->device->x_range);
1319   scanner->val[OPT_TL_X].w = 0;
1320 
1321   /* top-left y */
1322   scanner->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1323   scanner->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1324   scanner->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1325   scanner->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
1326   scanner->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
1327   scanner->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1328   scanner->opt[OPT_TL_Y].constraint.range = &(scanner->device->y_range);
1329   scanner->val[OPT_TL_Y].w = 0;
1330 
1331   /* bottom-right x */
1332   scanner->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
1333   scanner->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
1334   scanner->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
1335   scanner->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
1336   scanner->opt[OPT_BR_X].unit = SANE_UNIT_MM;
1337   scanner->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
1338   scanner->opt[OPT_BR_X].constraint.range = &(scanner->device->x_range);
1339   scanner->val[OPT_BR_X].w = scanner->device->x_range.max;
1340 
1341   /* bottom-right y */
1342   scanner->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
1343   scanner->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
1344   scanner->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
1345   scanner->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
1346   scanner->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
1347   scanner->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1348   scanner->opt[OPT_BR_Y].constraint.range = &(scanner->device->y_range);
1349   scanner->val[OPT_BR_Y].w = scanner->device->y_range.max;
1350 
1351   /* "enhancement" group: */
1352 
1353   scanner->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
1354   scanner->opt[OPT_ENHANCEMENT_GROUP].desc = "";
1355   scanner->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
1356   scanner->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
1357   scanner->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1358 
1359   /* grayscale gamma vector */
1360   scanner->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
1361   scanner->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
1362   scanner->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
1363   scanner->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
1364   scanner->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
1365   scanner->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
1366   scanner->val[OPT_GAMMA_VECTOR].wa = scanner->gamma_table[0];
1367   scanner->opt[OPT_GAMMA_VECTOR].constraint.range = &scanner->gamma_range;
1368   scanner->opt[OPT_GAMMA_VECTOR].size =
1369     scanner->gamma_length * sizeof (SANE_Word);
1370   scanner->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1371 
1372   /* red gamma vector */
1373   scanner->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
1374   scanner->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
1375   scanner->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
1376   scanner->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
1377   scanner->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
1378   scanner->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
1379   scanner->val[OPT_GAMMA_VECTOR_R].wa = scanner->gamma_table[1];
1380   scanner->opt[OPT_GAMMA_VECTOR_R].constraint.range = &(scanner->gamma_range);
1381   scanner->opt[OPT_GAMMA_VECTOR_R].size =
1382     scanner->gamma_length * sizeof (SANE_Word);
1383 
1384   /* green gamma vector */
1385   scanner->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
1386   scanner->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
1387   scanner->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
1388   scanner->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
1389   scanner->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
1390   scanner->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
1391   scanner->val[OPT_GAMMA_VECTOR_G].wa = scanner->gamma_table[2];
1392   scanner->opt[OPT_GAMMA_VECTOR_G].constraint.range = &(scanner->gamma_range);
1393   scanner->opt[OPT_GAMMA_VECTOR_G].size =
1394     scanner->gamma_length * sizeof (SANE_Word);
1395 
1396 
1397   /* blue gamma vector */
1398   scanner->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
1399   scanner->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
1400   scanner->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
1401   scanner->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
1402   scanner->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
1403   scanner->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
1404   scanner->val[OPT_GAMMA_VECTOR_B].wa = scanner->gamma_table[3];
1405   scanner->opt[OPT_GAMMA_VECTOR_B].constraint.range = &(scanner->gamma_range);
1406   scanner->opt[OPT_GAMMA_VECTOR_B].size =
1407     scanner->gamma_length * sizeof (SANE_Word);
1408 
1409   /* halftone pattern */
1410   scanner->opt[OPT_HALFTONE_PATTERN].name = SANE_NAME_HALFTONE_PATTERN;
1411   scanner->opt[OPT_HALFTONE_PATTERN].title = SANE_TITLE_HALFTONE_PATTERN;
1412   scanner->opt[OPT_HALFTONE_PATTERN].desc = SANE_DESC_HALFTONE_PATTERN;
1413   scanner->opt[OPT_HALFTONE_PATTERN].type = SANE_TYPE_STRING;
1414   scanner->opt[OPT_HALFTONE_PATTERN].size =
1415     max_string_size ((SANE_String_Const *) scanner->device->halftone_list);
1416   scanner->opt[OPT_HALFTONE_PATTERN].constraint_type =
1417     SANE_CONSTRAINT_STRING_LIST;
1418   scanner->opt[OPT_HALFTONE_PATTERN].constraint.string_list =
1419     (SANE_String_Const *) scanner->device->halftone_list;
1420   scanner->val[OPT_HALFTONE_PATTERN].s =
1421     (SANE_Char *) strdup (scanner->device->halftone_list[0]);
1422   scanner->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
1423 
1424   /* speed */
1425   scanner->opt[OPT_SPEED].name = SANE_NAME_SCAN_SPEED;
1426   scanner->opt[OPT_SPEED].title = SANE_TITLE_SCAN_SPEED;
1427   scanner->opt[OPT_SPEED].desc = SANE_DESC_SCAN_SPEED;
1428   scanner->opt[OPT_SPEED].type = SANE_TYPE_STRING;
1429   scanner->opt[OPT_SPEED].size =
1430     max_string_size ((SANE_String_Const *) scanner->device->speed_list);
1431   scanner->opt[OPT_SPEED].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1432   scanner->opt[OPT_SPEED].constraint.string_list =
1433     (SANE_String_Const *) scanner->device->speed_list;
1434   scanner->val[OPT_SPEED].s =
1435     (SANE_Char *) strdup (scanner->device->speed_list[0]);
1436 
1437   /* lineart threshold */
1438   scanner->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
1439   scanner->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
1440   scanner->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
1441   scanner->opt[OPT_THRESHOLD].type = SANE_TYPE_FIXED;
1442   scanner->opt[OPT_THRESHOLD].unit = SANE_UNIT_PERCENT;
1443   scanner->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
1444   scanner->opt[OPT_THRESHOLD].constraint.range = &percentage_range_100;
1445   scanner->val[OPT_THRESHOLD].w = SANE_FIX (50);
1446   scanner->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
1447 
1448   /* "advanced" group: */
1449 
1450   scanner->opt[OPT_ADVANCED_GROUP].title = "Advanced";
1451   scanner->opt[OPT_ADVANCED_GROUP].desc = "";
1452   scanner->opt[OPT_ADVANCED_GROUP].type = SANE_TYPE_GROUP;
1453   scanner->opt[OPT_ADVANCED_GROUP].cap = SANE_CAP_ADVANCED;
1454   scanner->opt[OPT_ADVANCED_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1455 
1456   /* preview */
1457   scanner->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
1458   scanner->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
1459   scanner->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
1460   scanner->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
1461   scanner->val[OPT_PREVIEW].w = SANE_FALSE;
1462 
1463 
1464 
1465   return SANE_STATUS_GOOD;
1466 }
1467 
1468 
1469 /*------------------------- PIE POWER SAVE -----------------------------*/
1470 
1471 static SANE_Status
pie_power_save(Pie_Scanner * scanner,int time)1472 pie_power_save (Pie_Scanner * scanner, int time)
1473 {
1474   unsigned char buffer[128];
1475   size_t size;
1476   SANE_Status status;
1477   unsigned char *data;
1478 
1479   DBG (DBG_proc, "pie_power_save: %d min\n", time);
1480 
1481   size = 6;
1482 
1483   set_write_length (swrite.cmd, size);
1484 
1485   memcpy (buffer, swrite.cmd, swrite.size);
1486 
1487   data = buffer + swrite.size;
1488   memset (data, 0, size);
1489 
1490   set_command (data, SET_POWER_SAVE_CONTROL);
1491   set_data_length (data, size - 4);
1492   data[4] = time & 0x7f;
1493 
1494   status =
1495     sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL);
1496   if (status)
1497     {
1498       DBG (DBG_error, "pie_power_save: write command returned status %s\n",
1499 	   sane_strstatus (status));
1500     }
1501 
1502   return status;
1503 }
1504 
1505 /*------------------------- PIE SEND EXPOSURE ONE -----------------------------*/
1506 
1507 
1508 static SANE_Status
pie_send_exposure_one(Pie_Scanner * scanner,int filter,int value)1509 pie_send_exposure_one (Pie_Scanner * scanner, int filter, int value)
1510 {
1511   unsigned char buffer[128];
1512   size_t size;
1513   SANE_Status status;
1514   unsigned char *data;
1515 
1516   DBG (DBG_proc, "pie_send_exposure_one\n");
1517 
1518   size = 8;
1519 
1520   set_write_length (swrite.cmd, size);
1521 
1522   memcpy (buffer, swrite.cmd, swrite.size);
1523 
1524   data = buffer + swrite.size;
1525   memset (data, 0, size);
1526 
1527   set_command (data, SET_EXP_TIME);
1528   set_data_length (data, size - 4);
1529 
1530   data[4] = filter;
1531 
1532   set_data (data, 6, (int) value, 2);
1533 
1534   status =
1535     sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL);
1536   if (status)
1537     {
1538       DBG (DBG_error,
1539 	   "pie_send_exposure_one: write command returned status %s\n",
1540 	   sane_strstatus (status));
1541     }
1542 
1543   return status;
1544 }
1545 
1546 /*------------------------- PIE SEND EXPOSURE -----------------------------*/
1547 
1548 static SANE_Status
pie_send_exposure(Pie_Scanner * scanner)1549 pie_send_exposure (Pie_Scanner * scanner)
1550 {
1551   SANE_Status status;
1552 
1553   DBG (DBG_proc, "pie_send_exposure\n");
1554 
1555   status = pie_send_exposure_one (scanner, FILTER_RED, 100);
1556   if (status)
1557     return status;
1558 
1559   status = pie_send_exposure_one (scanner, FILTER_GREEN, 100);
1560   if (status)
1561     return status;
1562 
1563   status = pie_send_exposure_one (scanner, FILTER_BLUE, 100);
1564   if (status)
1565     return status;
1566 
1567   return SANE_STATUS_GOOD;
1568 }
1569 
1570 
1571 /*------------------------- PIE SEND HIGHLIGHT/SHADOW ONE -----------------------------*/
1572 
1573 static SANE_Status
pie_send_highlight_shadow_one(Pie_Scanner * scanner,int filter,int highlight,int shadow)1574 pie_send_highlight_shadow_one (Pie_Scanner * scanner, int filter,
1575 			       int highlight, int shadow)
1576 {
1577   unsigned char buffer[128];
1578   size_t size;
1579   SANE_Status status;
1580   unsigned char *data;
1581 
1582   DBG (DBG_proc, "pie_send_highlight_shadow_one\n");
1583 
1584   size = 8;
1585 
1586   set_write_length (swrite.cmd, size);
1587 
1588   memcpy (buffer, swrite.cmd, swrite.size);
1589 
1590   data = buffer + swrite.size;
1591   memset (data, 0, size);
1592 
1593   set_command (data, SET_EXP_TIME);
1594   set_data_length (data, size - 4);
1595 
1596   data[4] = filter;
1597 
1598   data[6] = highlight;
1599   data[7] = shadow;
1600 
1601   status =
1602     sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL);
1603   if (status)
1604     {
1605       DBG (DBG_error,
1606 	   "pie_send_highlight_shadow_one: write command returned status %s\n",
1607 	   sane_strstatus (status));
1608     }
1609 
1610   return status;
1611 }
1612 
1613 /*------------------------- PIE SEND HIGHLIGHT/SHADOW -----------------------------*/
1614 
1615 static SANE_Status
pie_send_highlight_shadow(Pie_Scanner * scanner)1616 pie_send_highlight_shadow (Pie_Scanner * scanner)
1617 {
1618   SANE_Status status;
1619 
1620   DBG (DBG_proc, "pie_send_highlight_shadow\n");
1621 
1622   status = pie_send_highlight_shadow_one (scanner, FILTER_RED, 100, 0);
1623   if (status)
1624     return status;
1625 
1626   status = pie_send_highlight_shadow_one (scanner, FILTER_GREEN, 100, 0);
1627   if (status)
1628     return status;
1629 
1630   status = pie_send_highlight_shadow_one (scanner, FILTER_BLUE, 100, 0);
1631   if (status)
1632     return status;
1633 
1634   return SANE_STATUS_GOOD;
1635 }
1636 
1637 /*------------------------- PIE PERFORM CAL ----------------------------*/
1638 
1639 static SANE_Status
pie_perform_cal(Pie_Scanner * scanner,int cal_index)1640 pie_perform_cal (Pie_Scanner * scanner, int cal_index)
1641 {
1642   long *red_result;
1643   long *green_result;
1644   long *blue_result;
1645   long *neutral_result;
1646   long *result = NULL;
1647   int rcv_length, send_length;
1648   int rcv_lines, rcv_bits, send_bits;
1649   int pixels_per_line;
1650   int i;
1651   unsigned char *rcv_buffer, *rcv_ptr;
1652   unsigned char *send_buffer, *send_ptr;
1653   size_t size;
1654   int fullscale;
1655   int cal_limit;
1656   int k;
1657   int filter;
1658   SANE_Status status;
1659 
1660   DBG (DBG_proc, "pie_perform_cal\n");
1661 
1662   pixels_per_line = scanner->device->cal_info[cal_index].pixels_per_line;
1663   rcv_length = pixels_per_line;
1664   send_length = pixels_per_line;
1665 
1666   rcv_bits = scanner->device->cal_info[cal_index].receive_bits;
1667   if (rcv_bits > 8)
1668     rcv_length *= 2;		/* 2 bytes / sample */
1669 
1670   send_bits = scanner->device->cal_info[cal_index].send_bits;
1671   if (send_bits > 8)
1672     send_length *= 2;		/* 2 bytes / sample */
1673 
1674   rcv_lines = scanner->device->cal_info[cal_index].num_lines;
1675 
1676   send_length += 2;		/* space for filter at start */
1677 
1678   if (scanner->colormode == RGB)
1679     {
1680       rcv_lines *= 3;
1681       send_length *= 3;
1682       rcv_length += 2;		/* 2 bytes for index at front of data (only in RGB??) */
1683     }
1684 
1685   send_length += 4;		/* space for header at start of data */
1686 
1687   /* allocate buffers for the receive data, the result buffers, and for the send data */
1688   rcv_buffer = (unsigned char *) malloc (rcv_length);
1689 
1690   red_result = (long *) calloc (pixels_per_line, sizeof (long));
1691   green_result = (long *) calloc (pixels_per_line, sizeof (long));
1692   blue_result = (long *) calloc (pixels_per_line, sizeof (long));
1693   neutral_result = (long *) calloc (pixels_per_line, sizeof (long));
1694 
1695   if (!rcv_buffer || !red_result || !green_result || !blue_result
1696       || !neutral_result)
1697     {
1698       /* at least one malloc failed, so free all buffers (free accepts NULL) */
1699       free (rcv_buffer);
1700       free (red_result);
1701       free (green_result);
1702       free (blue_result);
1703       free (neutral_result);
1704       return SANE_STATUS_NO_MEM;
1705     }
1706 
1707   /* read the cal data a line at a time, and accumulate into the result arrays */
1708   while (rcv_lines--)
1709     {
1710       /* TUR */
1711       status = pie_wait_scanner (scanner);
1712       if (status)
1713 	{
1714 	  free (rcv_buffer);
1715 	  free (red_result);
1716 	  free (green_result);
1717 	  free (blue_result);
1718 	  free (neutral_result);
1719 	  return status;
1720 	}
1721 
1722       set_read_length (sread.cmd, 1);
1723       size = rcv_length;
1724 
1725       DBG (DBG_info, "pie_perform_cal: reading 1 line (%lu bytes)\n", (u_long) size);
1726 
1727       status =
1728 	sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, rcv_buffer,
1729 			&size);
1730 
1731       if (status)
1732 	{
1733 	  DBG (DBG_error,
1734 	       "pie_perform_cal: read command returned status %s\n",
1735 	       sane_strstatus (status));
1736 	  free (rcv_buffer);
1737 	  free (red_result);
1738 	  free (green_result);
1739 	  free (blue_result);
1740 	  free (neutral_result);
1741 	  return status;
1742 	}
1743 
1744       DBG_DUMP (DBG_dump, rcv_buffer, 32);
1745 
1746       /* which result buffer does this line belong to? */
1747       if (scanner->colormode == RGB)
1748 	{
1749 	  if (*rcv_buffer == 'R')
1750 	    result = red_result;
1751 	  else if (*rcv_buffer == 'G')
1752 	    result = green_result;
1753 	  else if (*rcv_buffer == 'B')
1754 	    result = blue_result;
1755 	  else if (*rcv_buffer == 'N')
1756 	    result = neutral_result;
1757 	  else
1758 	    {
1759 	      DBG (DBG_error, "pie_perform_cal: invalid index byte (%02x)\n",
1760 		   *rcv_buffer);
1761 	      DBG_DUMP (DBG_error, rcv_buffer, 32);
1762 	      free (rcv_buffer);
1763 	      free (red_result);
1764 	      free (green_result);
1765 	      free (blue_result);
1766 	      free (neutral_result);
1767 	      return SANE_STATUS_INVAL;
1768 	    }
1769 	  rcv_ptr = rcv_buffer + 2;
1770 	}
1771       else
1772 	{
1773 	  /* monochrome - no bytes indicating filter here */
1774 	  result = neutral_result;
1775 	  rcv_ptr = rcv_buffer;
1776 	}
1777 
1778       /* now add the values in this line to the result array */
1779       for (i = 0; i < pixels_per_line; i++)
1780 	{
1781 	  result[i] += *rcv_ptr++;
1782 	  if (rcv_bits > 8)
1783 	    {
1784 	      result[i] += (*rcv_ptr++) << 8;
1785 	    }
1786 	}
1787     }
1788 
1789   /* got all the cal data, now process it ready to send back */
1790   free (rcv_buffer);
1791   send_buffer = (unsigned char *) malloc (send_length + swrite.size);
1792 
1793   if (!send_buffer)
1794     {
1795       free (red_result);
1796       free (green_result);
1797       free (blue_result);
1798       free (neutral_result);
1799       return SANE_STATUS_NO_MEM;
1800     }
1801 
1802   rcv_lines = scanner->device->cal_info[cal_index].num_lines;
1803   fullscale = (1 << rcv_bits) - 1;
1804   cal_limit = fullscale / (1 << scanner->device->inquiry_cal_eqn);
1805   k = (1 << scanner->device->inquiry_cal_eqn) - 1;
1806 
1807   /* set up scsi command and data */
1808   size = send_length;
1809 
1810   memcpy (send_buffer, swrite.cmd, swrite.size);
1811   set_write_length (send_buffer, size);
1812 
1813   set_command (send_buffer + swrite.size, SEND_CAL_DATA);
1814   set_data_length (send_buffer + swrite.size, size - 4);
1815 
1816   send_ptr = send_buffer + swrite.size + 4;
1817 
1818   for (filter = FILTER_NEUTRAL; filter <= FILTER_BLUE; filter <<= 1)
1819     {
1820 
1821       /* only send data for filter we expect to send */
1822       if (!(filter & scanner->cal_filter))
1823 	continue;
1824 
1825       set_data (send_ptr, 0, filter, 2);
1826       send_ptr += 2;
1827 
1828       if (scanner->colormode == RGB)
1829 	{
1830 	  switch (filter)
1831 	    {
1832 	    case FILTER_RED:
1833 	      result = red_result;
1834 	      break;
1835 
1836 	    case FILTER_GREEN:
1837 	      result = green_result;
1838 	      break;
1839 
1840 	    case FILTER_BLUE:
1841 	      result = blue_result;
1842 	      break;
1843 
1844 	    case FILTER_NEUTRAL:
1845 	      result = neutral_result;
1846 	      break;
1847 	    }
1848 	}
1849       else
1850 	result = neutral_result;
1851 
1852       /* for each pixel */
1853       for (i = 0; i < pixels_per_line; i++)
1854 	{
1855 	  long x;
1856 
1857 	  /* make average */
1858 	  x = result[i] / rcv_lines;
1859 
1860 	  /* ensure not overflowed */
1861 	  if (x > fullscale)
1862 	    x = fullscale;
1863 
1864 	  /* process according to required calibration equation */
1865 	  if (scanner->device->inquiry_cal_eqn)
1866 	    {
1867 	      if (x <= cal_limit)
1868 		x = fullscale;
1869 	      else
1870 		x = ((fullscale - x) * fullscale) / (x * k);
1871 	    }
1872 
1873 	  if (rcv_bits > send_bits)
1874 	    x >>= (rcv_bits - send_bits);
1875 	  else if (send_bits > rcv_bits)
1876 	    x <<= (send_bits - rcv_bits);
1877 
1878 	  /* put result into send buffer */
1879 	  *send_ptr++ = x;
1880 	  if (send_bits > 8)
1881 	    *send_ptr++ = x >> 8;
1882 	}
1883     }
1884 
1885   /* now send the data back to scanner */
1886 
1887   /* TUR */
1888   status = pie_wait_scanner (scanner);
1889   if (status)
1890     {
1891       free (red_result);
1892       free (green_result);
1893       free (blue_result);
1894       free (neutral_result);
1895       free (send_buffer);
1896       return status;
1897     }
1898 
1899   DBG (DBG_info, "pie_perform_cal: sending cal data (%lu bytes)\n", (u_long) size);
1900   DBG_DUMP (DBG_dump, send_buffer, 64);
1901 
1902   status =
1903     sanei_scsi_cmd (scanner->sfd, send_buffer, swrite.size + size, NULL,
1904 		    NULL);
1905   if (status)
1906     {
1907       DBG (DBG_error, "pie_perform_cal: write command returned status %s\n",
1908 	   sane_strstatus (status));
1909       free (red_result);
1910       free (green_result);
1911       free (blue_result);
1912       free (neutral_result);
1913       free (send_buffer);
1914       return status;
1915     }
1916 
1917   free (red_result);
1918   free (green_result);
1919   free (blue_result);
1920   free (neutral_result);
1921   free (send_buffer);
1922 
1923   return SANE_STATUS_GOOD;
1924 }
1925 
1926 /*------------------------- PIE DO CAL -----------------------------*/
1927 
1928 static SANE_Status
pie_do_cal(Pie_Scanner * scanner)1929 pie_do_cal (Pie_Scanner * scanner)
1930 {
1931   SANE_Status status;
1932   int cal_index;
1933 
1934   DBG (DBG_proc, "pie_do_cal\n");
1935 
1936   if (scanner->device->inquiry_scan_capability & INQ_CAP_EXT_CAL)
1937     {
1938       for (cal_index = 0; cal_index < scanner->device->cal_info_count;
1939 	   cal_index++)
1940 	if (scanner->device->cal_info[cal_index].cal_type ==
1941 	    scanner->cal_mode)
1942 	  {
1943 	    status = pie_perform_cal (scanner, cal_index);
1944 	    if (status != SANE_STATUS_GOOD)
1945 	      return status;
1946 	  }
1947     }
1948 
1949   return SANE_STATUS_GOOD;
1950 }
1951 
1952 /*------------------------- PIE DWNLD GAMMA ONE -----------------------------*/
1953 
1954 static SANE_Status
pie_dwnld_gamma_one(Pie_Scanner * scanner,int filter,SANE_Int * table)1955 pie_dwnld_gamma_one (Pie_Scanner * scanner, int filter, SANE_Int * table)
1956 {
1957   unsigned char *buffer;
1958   size_t size;
1959   SANE_Status status;
1960   unsigned char *data;
1961   int i;
1962 
1963   DBG (DBG_proc, "pie_dwnld_gamma_one\n");
1964 
1965   /* TUR */
1966   status = pie_wait_scanner (scanner);
1967   if (status)
1968     {
1969       return status;
1970     }
1971 
1972   if (scanner->device->inquiry_gamma_bits > 8)
1973     size = scanner->gamma_length * 2 + 6;
1974   else
1975     size = scanner->gamma_length + 6;
1976 
1977   buffer = malloc (size + swrite.size);
1978   if (!buffer)
1979     return SANE_STATUS_NO_MEM;
1980 
1981   set_write_length (swrite.cmd, size);
1982 
1983   memcpy (buffer, swrite.cmd, swrite.size);
1984 
1985   data = buffer + swrite.size;
1986   memset (data, 0, size);
1987 
1988   set_command (data, DWNLD_GAMMA_TABLE);
1989   set_data_length (data, size - 4);
1990 
1991   data[4] = filter;
1992 
1993   for (i = 0; i < scanner->gamma_length; i++)
1994     {
1995       if (scanner->device->inquiry_gamma_bits > 8)
1996 	{
1997 	  set_data (data, 6 + 2 * i, table ? table[i] : i, 2);
1998 	}
1999       else
2000 	{
2001 	  set_data (data, 6 + i, table ? table[i] : i, 1);
2002 	}
2003     }
2004 
2005   DBG_DUMP (DBG_dump, data, 128);
2006 
2007   status =
2008     sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL);
2009   if (status)
2010     {
2011       DBG (DBG_error,
2012 	   "pie_dwnld_gamma_one: write command returned status %s\n",
2013 	   sane_strstatus (status));
2014     }
2015 
2016   free (buffer);
2017 
2018   return status;
2019 }
2020 
2021 /*------------------------- PIE DWNLD GAMMA -----------------------------*/
2022 
2023 static SANE_Status
pie_dwnld_gamma(Pie_Scanner * scanner)2024 pie_dwnld_gamma (Pie_Scanner * scanner)
2025 {
2026   SANE_Status status;
2027 
2028   DBG (DBG_proc, "pie_dwnld_gamma\n");
2029 
2030   if (scanner->colormode == RGB)
2031     {
2032       status =
2033 	pie_dwnld_gamma_one (scanner, FILTER_RED, scanner->gamma_table[1]);
2034       if (status)
2035 	return status;
2036 
2037 
2038       status =
2039 	pie_dwnld_gamma_one (scanner, FILTER_GREEN, scanner->gamma_table[2]);
2040       if (status)
2041 	return status;
2042 
2043       status =
2044 	pie_dwnld_gamma_one (scanner, FILTER_BLUE, scanner->gamma_table[3]);
2045       if (status)
2046 	return status;
2047     }
2048   else
2049     {
2050       SANE_Int *table;
2051 
2052       /* if lineart or half tone, force gamma to be one to one by passing NULL */
2053       if (scanner->colormode == GRAYSCALE)
2054 	table = scanner->gamma_table[0];
2055       else
2056 	table = NULL;
2057 
2058       status = pie_dwnld_gamma_one (scanner, FILTER_GREEN, table);
2059       if (status)
2060 	return status;
2061     }
2062 
2063   usleep (DOWNLOAD_GAMMA_WAIT_TIME);
2064 
2065   return SANE_STATUS_GOOD;
2066 }
2067 
2068 /*------------------------- PIE SET WINDOW -----------------------------*/
2069 
2070 static SANE_Status
pie_set_window(Pie_Scanner * scanner)2071 pie_set_window (Pie_Scanner * scanner)
2072 {
2073   unsigned char buffer[128];
2074   size_t size;
2075   SANE_Status status;
2076   unsigned char *data;
2077   double x, dpmm;
2078 
2079   DBG (DBG_proc, "pie_set_window\n");
2080 
2081   size = 14;
2082 
2083   set_write_length (swrite.cmd, size);
2084 
2085   memcpy (buffer, swrite.cmd, swrite.size);
2086 
2087   data = buffer + swrite.size;
2088   memset (data, 0, size);
2089 
2090   set_command (data, SET_SCAN_FRAME);
2091   set_data_length (data, size - 4);
2092 
2093   data[4] = 0x80;
2094   if (scanner->colormode == HALFTONE)
2095     data[4] |= 0x40;
2096 
2097   dpmm = (double) scanner->device->inquiry_pixel_resolution / MM_PER_INCH;
2098 
2099   x = SANE_UNFIX (scanner->val[OPT_TL_X].w) * dpmm;
2100   set_data (data, 6, (int) x, 2);
2101   DBG (DBG_info, "TL_X: %d\n", (int) x);
2102 
2103   x = SANE_UNFIX (scanner->val[OPT_TL_Y].w) * dpmm;
2104   set_data (data, 8, (int) x, 2);
2105   DBG (DBG_info, "TL_Y: %d\n", (int) x);
2106 
2107   x = SANE_UNFIX (scanner->val[OPT_BR_X].w) * dpmm;
2108   set_data (data, 10, (int) x, 2);
2109   DBG (DBG_info, "BR_X: %d\n", (int) x);
2110 
2111   x = SANE_UNFIX (scanner->val[OPT_BR_Y].w) * dpmm;
2112   set_data (data, 12, (int) x, 2);
2113   DBG (DBG_info, "BR_Y: %d\n", (int) x);
2114 
2115   status =
2116     sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL);
2117   if (status)
2118     {
2119       DBG (DBG_error, "pie_set_window: write command returned status %s\n",
2120 	   sane_strstatus (status));
2121     }
2122 
2123   return status;
2124 }
2125 
2126 
2127 /*------------------------- PIE MODE SELECT -----------------------------*/
2128 
2129 static SANE_Status
pie_mode_select(Pie_Scanner * scanner)2130 pie_mode_select (Pie_Scanner * scanner)
2131 {
2132 
2133   SANE_Status status;
2134   unsigned char buffer[128];
2135   size_t size;
2136   unsigned char *data;
2137   int i;
2138 
2139   DBG (DBG_proc, "pie_mode_select\n");
2140 
2141   size = 14;
2142 
2143   set_mode_length (smode.cmd, size);
2144 
2145   memcpy (buffer, smode.cmd, smode.size);
2146 
2147   data = buffer + smode.size;
2148   memset (data, 0, size);
2149 
2150   /* size of data */
2151   data[1] = size - 2;
2152 
2153   /* set resolution required */
2154   set_data (data, 2, scanner->resolution, 2);
2155 
2156   /* set color filter and color depth */
2157   switch (scanner->colormode)
2158     {
2159     case RGB:
2160       if (scanner->device->inquiry_filters & INQ_ONE_PASS_COLOR)
2161 	{
2162 	  data[4] = INQ_ONE_PASS_COLOR;
2163 	  scanner->cal_filter = FILTER_RED | FILTER_GREEN | FILTER_BLUE;
2164 	}
2165       else
2166 	{
2167 	  DBG (DBG_error,
2168 	       "pie_mode_select: support for multipass color not yet implemented\n");
2169 	  return SANE_STATUS_UNSUPPORTED;
2170 	}
2171       data[5] = INQ_COLOR_DEPTH_8;
2172       break;
2173 
2174     case GRAYSCALE:
2175     case LINEART:
2176     case HALFTONE:
2177       /* choose which filter to use for monochrome mode */
2178       if (scanner->device->inquiry_filters & INQ_FILTER_NEUTRAL)
2179 	{
2180 	  data[4] = FILTER_NEUTRAL;
2181 	  scanner->cal_filter = FILTER_NEUTRAL;
2182 	}
2183       else if (scanner->device->inquiry_filters & INQ_FILTER_GREEN)
2184 	{
2185 	  data[4] = FILTER_GREEN;
2186 	  scanner->cal_filter = FILTER_GREEN;
2187 	}
2188       else if (scanner->device->inquiry_filters & INQ_FILTER_RED)
2189 	{
2190 	  data[4] = FILTER_RED;
2191 	  scanner->cal_filter = FILTER_RED;
2192 	}
2193       else if (scanner->device->inquiry_filters & INQ_FILTER_BLUE)
2194 	{
2195 	  data[4] = FILTER_BLUE;
2196 	  scanner->cal_filter = FILTER_BLUE;
2197 	}
2198       else
2199 	{
2200 	  DBG (DBG_error,
2201 	       "pie_mode_select: scanner doesn't appear to support monochrome\n");
2202 	  return SANE_STATUS_UNSUPPORTED;
2203 	}
2204 
2205       if (scanner->colormode == GRAYSCALE)
2206 	data[5] = INQ_COLOR_DEPTH_8;
2207       else
2208 	data[5] = INQ_COLOR_DEPTH_1;
2209       break;
2210     }
2211 
2212   /* choose color packing method */
2213   if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_LINE)
2214     data[6] = INQ_COLOR_FORMAT_LINE;
2215   else if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_INDEX)
2216     data[6] = INQ_COLOR_FORMAT_INDEX;
2217   else
2218     {
2219       DBG (DBG_error,
2220 	   "pie_mode_select: support for pixel packing not yet implemented\n");
2221       return SANE_STATUS_UNSUPPORTED;
2222     }
2223 
2224   /* choose data format */
2225   if (scanner->device->inquiry_image_format & INQ_IMG_FMT_INTEL)
2226     data[8] = INQ_IMG_FMT_INTEL;
2227   else
2228     {
2229       DBG (DBG_error,
2230 	   "pie_mode_select: support for Motorola format not yet implemented\n");
2231       return SANE_STATUS_UNSUPPORTED;
2232     }
2233 
2234   /* set required speed */
2235   i = 0;
2236   while (scanner->device->speed_list[i] != NULL)
2237     {
2238       if (strcmp (scanner->device->speed_list[i], scanner->val[OPT_SPEED].s)
2239 	  == 0)
2240 	break;
2241       i++;
2242     }
2243 
2244   if (scanner->device->speed_list[i] == NULL)
2245     data[9] = 0;
2246   else
2247     data[9] = i;
2248 
2249   scanner->cal_mode = CAL_MODE_FLATBED;
2250 
2251   /* if preview supported, ask for preview, limit resolution to max for fast preview */
2252   if (scanner->val[OPT_PREVIEW].w
2253       && (scanner->device->inquiry_scan_capability & INQ_CAP_FAST_PREVIEW))
2254     {
2255       DBG (DBG_info, "pie_mode_select: setting preview\n");
2256       scanner->cal_mode |= CAL_MODE_PREVIEW;
2257       data[9] |= INQ_CAP_FAST_PREVIEW;
2258       data[9] &= ~INQ_CAP_SPEEDS;
2259       if (scanner->resolution > scanner->device->inquiry_fast_preview_res)
2260 	set_data (data, 2, scanner->device->inquiry_fast_preview_res, 2);
2261     }
2262 
2263 
2264   /* set required halftone pattern */
2265   i = 0;
2266   while (scanner->device->halftone_list[i] != NULL)
2267     {
2268       if (strcmp
2269 	  (scanner->device->halftone_list[i],
2270 	   scanner->val[OPT_HALFTONE_PATTERN].s) == 0)
2271 	break;
2272       i++;
2273     }
2274 
2275   if (scanner->device->halftone_list[i] == NULL)
2276     data[12] = 0;		/* halftone pattern */
2277   else
2278     data[12] = i;
2279 
2280   data[13] = SANE_UNFIX (scanner->val[OPT_THRESHOLD].w) * 255 / 100;	/* lineart threshold */
2281 
2282   DBG (DBG_info, "pie_mode_select: speed %02x\n", data[9]);
2283   DBG (DBG_info, "pie_mode_select: halftone %d\n", data[12]);
2284   DBG (DBG_info, "pie_mode_select: threshold %02x\n", data[13]);
2285 
2286   status =
2287     sanei_scsi_cmd (scanner->sfd, buffer, smode.size + size, NULL, NULL);
2288   if (status)
2289     {
2290       DBG (DBG_error, "pie_mode_select: write command returned status %s\n",
2291 	   sane_strstatus (status));
2292     }
2293 
2294   return status;
2295 }
2296 
2297 
2298 /*------------------------- PIE SCAN -----------------------------*/
2299 
2300 static SANE_Status
pie_scan(Pie_Scanner * scanner,int start)2301 pie_scan (Pie_Scanner * scanner, int start)
2302 {
2303   SANE_Status status;
2304 
2305   DBG (DBG_proc, "pie_scan\n");
2306 
2307   /* TUR */
2308   status = pie_wait_scanner (scanner);
2309   if (status)
2310     {
2311       return status;
2312     }
2313 
2314   set_scan_cmd (scan.cmd, start);
2315 
2316   do
2317     {
2318       status = sanei_scsi_cmd (scanner->sfd, scan.cmd, scan.size, NULL, NULL);
2319       if (status)
2320 	{
2321 	  DBG (DBG_error, "pie_scan: write command returned status %s\n",
2322 	       sane_strstatus (status));
2323 	  usleep (SCAN_WARMUP_WAIT_TIME);
2324 	}
2325     }
2326   while (start && status);
2327 
2328   usleep (SCAN_WAIT_TIME);
2329 
2330   return status;
2331 }
2332 
2333 
2334 /* --------------------------------------- PIE WAIT SCANNER -------------------------- */
2335 
2336 
2337 static SANE_Status
pie_wait_scanner(Pie_Scanner * scanner)2338 pie_wait_scanner (Pie_Scanner * scanner)
2339 {
2340   SANE_Status status;
2341   int cnt = 0;
2342 
2343   DBG (DBG_proc, "wait_scanner\n");
2344 
2345   do
2346     {
2347       if (cnt > 100)		/* maximal 100 * 0.5 sec = 50 sec */
2348 	{
2349 	  DBG (DBG_warning, "scanner does not get ready\n");
2350 	  return -1;
2351 	}
2352       /* test unit ready */
2353       status =
2354 	sanei_scsi_cmd (scanner->sfd, test_unit_ready.cmd,
2355 			test_unit_ready.size, NULL, NULL);
2356       cnt++;
2357 
2358       if (status)
2359 	{
2360 	  if (cnt == 1)
2361 	    {
2362 	      DBG (DBG_info2, "scanner reports %s, waiting ...\n",
2363 		   sane_strstatus (status));
2364 	    }
2365 
2366 	  usleep (TUR_WAIT_TIME);
2367 	}
2368     }
2369   while (status != SANE_STATUS_GOOD);
2370 
2371   DBG (DBG_info, "scanner ready\n");
2372 
2373 
2374   return status;
2375 }
2376 
2377 
2378 /* -------------------------------------- PIE GET PARAMS -------------------------- */
2379 
2380 
2381 static SANE_Status
pie_get_params(Pie_Scanner * scanner)2382 pie_get_params (Pie_Scanner * scanner)
2383 {
2384   SANE_Status status;
2385   size_t size;
2386   unsigned char buffer[128];
2387 
2388   DBG (DBG_proc, "pie_get_params\n");
2389 
2390   status = pie_wait_scanner (scanner);
2391   if (status)
2392     return status;
2393 
2394   if (scanner->device->inquiry_image_format & INQ_IMG_FMT_OKLINE)
2395     size = 16;
2396   else
2397 
2398     size = 14;
2399 
2400   set_param_length (param.cmd, size);
2401 
2402   status =
2403     sanei_scsi_cmd (scanner->sfd, param.cmd, param.size, buffer, &size);
2404 
2405   if (status)
2406     {
2407       DBG (DBG_error, "pie_get_params: command returned status %s\n",
2408 	   sane_strstatus (status));
2409     }
2410   else
2411     {
2412       DBG (DBG_info, "Scan Width:  %d\n", get_param_scan_width (buffer));
2413       DBG (DBG_info, "Scan Lines:  %d\n", get_param_scan_lines (buffer));
2414       DBG (DBG_info, "Scan bytes:  %d\n", get_param_scan_bytes (buffer));
2415 
2416       DBG (DBG_info, "Offset 1:    %d\n",
2417 	   get_param_scan_filter_offset1 (buffer));
2418       DBG (DBG_info, "Offset 2:    %d\n",
2419 	   get_param_scan_filter_offset2 (buffer));
2420       DBG (DBG_info, "Scan period: %d\n", get_param_scan_period (buffer));
2421       DBG (DBG_info, "Xfer rate:   %d\n", get_param_scsi_xfer_rate (buffer));
2422       if (scanner->device->inquiry_image_format & INQ_IMG_FMT_OKLINE)
2423 	DBG (DBG_info, "Avail lines: %d\n",
2424 	     get_param_scan_available_lines (buffer));
2425 
2426       scanner->filter_offset1 = get_param_scan_filter_offset1 (buffer);
2427       scanner->filter_offset2 = get_param_scan_filter_offset2 (buffer);
2428       scanner->bytes_per_line = get_param_scan_bytes (buffer);
2429 
2430       scanner->params.pixels_per_line = get_param_scan_width (buffer);
2431       scanner->params.lines = get_param_scan_lines (buffer);
2432 
2433       switch (scanner->colormode)
2434 	{
2435 	case RGB:
2436 	  scanner->params.format = SANE_FRAME_RGB;
2437 	  scanner->params.depth = 8;
2438 	  scanner->params.bytes_per_line = 3 * get_param_scan_bytes (buffer);
2439 	  break;
2440 
2441 	case GRAYSCALE:
2442 	  scanner->params.format = SANE_FRAME_GRAY;
2443 	  scanner->params.depth = 8;
2444 	  scanner->params.bytes_per_line = get_param_scan_bytes (buffer);
2445 	  break;
2446 
2447 	case HALFTONE:
2448 	case LINEART:
2449 	  scanner->params.format = SANE_FRAME_GRAY;
2450 	  scanner->params.depth = 1;
2451 	  scanner->params.bytes_per_line = get_param_scan_bytes (buffer);
2452 	  break;
2453 	}
2454 
2455       scanner->params.last_frame = 0;
2456     }
2457 
2458   return status;
2459 }
2460 
2461 
2462 /* -------------------------------------- PIE GRAB SCANNER -------------------------- */
2463 
2464 
2465 static SANE_Status
pie_grab_scanner(Pie_Scanner * scanner)2466 pie_grab_scanner (Pie_Scanner * scanner)
2467 {
2468   SANE_Status status;
2469 
2470   DBG (DBG_proc, "grab_scanner\n");
2471 
2472 
2473   status = pie_wait_scanner (scanner);
2474   if (status)
2475     return status;
2476 
2477   status =
2478     sanei_scsi_cmd (scanner->sfd, reserve_unit.cmd, reserve_unit.size, NULL,
2479 		    NULL);
2480 
2481 
2482   if (status)
2483     {
2484       DBG (DBG_error, "pie_grab_scanner: command returned status %s\n",
2485 	   sane_strstatus (status));
2486     }
2487   else
2488     {
2489       DBG (DBG_info, "scanner reserved\n");
2490     }
2491 
2492   return status;
2493 }
2494 
2495 
2496 /* ------------------------------------ PIE GIVE SCANNER -------------------------- */
2497 
2498 
2499 static SANE_Status
pie_give_scanner(Pie_Scanner * scanner)2500 pie_give_scanner (Pie_Scanner * scanner)
2501 {
2502   SANE_Status status;
2503 
2504   DBG (DBG_info2, "trying to release scanner ...\n");
2505 
2506   status =
2507     sanei_scsi_cmd (scanner->sfd, release_unit.cmd, release_unit.size, NULL,
2508 		    NULL);
2509   if (status)
2510     {
2511       DBG (DBG_error, "pie_give_scanner: command returned status %s\n",
2512 	   sane_strstatus (status));
2513     }
2514   else
2515     {
2516       DBG (DBG_info, "scanner released\n");
2517     }
2518   return status;
2519 }
2520 
2521 
2522 /* ------------------- PIE READER PROCESS INDEXED ------------------- */
2523 
2524 static int
pie_reader_process_indexed(Pie_Scanner * scanner,FILE * fp)2525 pie_reader_process_indexed (Pie_Scanner * scanner, FILE * fp)
2526 {
2527   int status;
2528   int lines;
2529   unsigned char *buffer, *reorder = NULL;
2530   unsigned char *red_buffer = NULL, *green_buffer = NULL;
2531   unsigned char *red_in = NULL, *red_out = NULL;
2532   unsigned char *green_in = NULL, *green_out = NULL;
2533   int red_size = 0, green_size = 0;
2534   int bytes_per_line;
2535   int red_count = 0, green_count = 0;
2536 
2537   size_t size;
2538 
2539   DBG (DBG_read, "reading %d lines of %d bytes/line (indexed)\n",
2540        scanner->params.lines, scanner->params.bytes_per_line);
2541 
2542   lines = scanner->params.lines;
2543   bytes_per_line = scanner->bytes_per_line;
2544 
2545   /* allocate receive buffer */
2546   buffer = malloc (bytes_per_line + 2);
2547   if (!buffer)
2548     {
2549       return SANE_STATUS_NO_MEM;
2550     }
2551 
2552   /* allocate deskew buffers for RGB mode */
2553   if (scanner->colormode == RGB)
2554     {
2555       lines *= 3;
2556 
2557       red_size = bytes_per_line * (scanner->filter_offset1 +
2558 				   scanner->filter_offset2 + 2);
2559       green_size = bytes_per_line * (scanner->filter_offset2 + 2);
2560 
2561       DBG (DBG_info2,
2562 	   "pie_reader_process_indexed: alloc %d lines (%d bytes) for red buffer\n",
2563 	   red_size / bytes_per_line, red_size);
2564       DBG (DBG_info2,
2565 	   "pie_reader_process_indexed: alloc %d lines (%d bytes) for green buffer\n",
2566 	   green_size / bytes_per_line, green_size);
2567 
2568       reorder = malloc (scanner->params.bytes_per_line);
2569       red_buffer = malloc (red_size);
2570       green_buffer = malloc (green_size);
2571 
2572       if (!reorder || !red_buffer || !green_buffer)
2573 	{
2574 	  free (buffer);
2575 	  free (reorder);
2576 	  free (red_buffer);
2577 	  free (green_buffer);
2578 	  return SANE_STATUS_NO_MEM;
2579 	}
2580 
2581       red_in = red_out = red_buffer;
2582       green_in = green_out = green_buffer;
2583     }
2584 
2585   while (lines--)
2586     {
2587       set_read_length (sread.cmd, 1);
2588       size = bytes_per_line + 2;
2589 
2590       do
2591 	{
2592 	  status =
2593 	    sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, buffer,
2594 			    &size);
2595 	}
2596       while (status);
2597 
2598       DBG_DUMP (DBG_dump, buffer, 64);
2599 
2600       if (scanner->colormode == RGB)
2601 	{
2602 	  /* we're assuming that we get red before green before blue here */
2603 	  switch (*buffer)
2604 	    {
2605 	    case 'R':
2606 	      /* copy to red buffer */
2607 	      memcpy (red_in, buffer + 2, bytes_per_line);
2608 
2609 	      /* advance in pointer, and check for wrap */
2610 	      red_in += bytes_per_line;
2611 	      if (red_in >= (red_buffer + red_size))
2612 		red_in = red_buffer;
2613 
2614 	      /* increment red line count */
2615 	      red_count++;
2616 	      DBG (DBG_info2,
2617 		   "pie_reader_process_indexed: got a red line (%d)\n",
2618 		   red_count);
2619 	      break;
2620 
2621 	    case 'G':
2622 	      /* copy to green buffer */
2623 	      memcpy (green_in, buffer + 2, bytes_per_line);
2624 
2625 	      /* advance in pointer, and check for wrap */
2626 	      green_in += bytes_per_line;
2627 	      if (green_in >= (green_buffer + green_size))
2628 		green_in = green_buffer;
2629 
2630 	      /* increment green line count */
2631 	      green_count++;
2632 	      DBG (DBG_info2,
2633 		   "pie_reader_process_indexed: got a green line (%d)\n",
2634 		   green_count);
2635 	      break;
2636 
2637 	    case 'B':
2638 	      /* check we actually have red and green data available */
2639 	      if (!red_count || !green_count)
2640 		{
2641 		  DBG (DBG_error,
2642 		       "pie_reader_process_indexed: deskew buffer empty (%d %d)\n",
2643 		       red_count, green_count);
2644 		  return SANE_STATUS_INVAL;
2645 		}
2646 	      red_count--;
2647 	      green_count--;
2648 
2649 	      DBG (DBG_info2,
2650 		   "pie_reader_process_indexed: got a blue line\n");
2651 
2652 	      {
2653 		int i;
2654 		unsigned char *red, *green, *blue, *dest;
2655 
2656 		/* now pack the pixels lines into RGB format */
2657 		dest = reorder;
2658 		red = red_out;
2659 		green = green_out;
2660 		blue = buffer + 2;
2661 
2662 		for (i = bytes_per_line; i > 0; i--)
2663 		  {
2664 		    *dest++ = *red++;
2665 		    *dest++ = *green++;
2666 		    *dest++ = *blue++;
2667 		  }
2668 		fwrite (reorder, 1, scanner->params.bytes_per_line, fp);
2669 
2670 		/* advance out pointers, and check for wrap */
2671 		red_out += bytes_per_line;
2672 		if (red_out >= (red_buffer + red_size))
2673 		  red_out = red_buffer;
2674 		green_out += bytes_per_line;
2675 		if (green_out >= (green_buffer + green_size))
2676 		  green_out = green_buffer;
2677 	      }
2678 	      break;
2679 
2680 	    default:
2681 	      DBG (DBG_error,
2682 		   "pie_reader_process_indexed: bad filter index\n");
2683 	    }
2684 	}
2685       else
2686 	{
2687 	  DBG (DBG_info2,
2688 	       "pie_reader_process_indexed: got a line (%lu bytes)\n", (u_long) size);
2689 
2690 	  /* just send the data on, assume filter bytes not present as per calibration case */
2691 	  fwrite (buffer, 1, scanner->params.bytes_per_line, fp);
2692 	}
2693     }
2694 
2695   free (buffer);
2696   free (reorder);
2697   free (red_buffer);
2698   free (green_buffer);
2699   return 0;
2700 }
2701 
2702 /* --------------------------------- PIE READER PROCESS ------------------------ */
2703 
2704 static int
pie_reader_process(Pie_Scanner * scanner,FILE * fp)2705 pie_reader_process (Pie_Scanner * scanner, FILE * fp)
2706 {
2707   int status;
2708   int lines;
2709   unsigned char *buffer, *reorder;
2710   size_t size;
2711 
2712   DBG (DBG_read, "reading %d lines of %d bytes/line\n", scanner->params.lines,
2713        scanner->params.bytes_per_line);
2714 
2715   buffer = malloc (scanner->params.bytes_per_line);
2716   reorder = malloc (scanner->params.bytes_per_line);
2717   if (!buffer || !reorder)
2718     {
2719       free (buffer);
2720       free (reorder);
2721       return SANE_STATUS_NO_MEM;
2722     }
2723 
2724   lines = scanner->params.lines;
2725 
2726   while (lines--)
2727     {
2728       set_read_length (sread.cmd, 1);
2729       size = scanner->params.bytes_per_line;
2730 
2731       do
2732 	{
2733 	  status =
2734 	    sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, buffer,
2735 			    &size);
2736 	}
2737       while (status);
2738 
2739       DBG_DUMP (DBG_dump, buffer, 64);
2740 
2741       if (scanner->colormode == RGB)
2742 	{
2743 	  int i;
2744 	  unsigned char *src, *dest;
2745 	  int offset;
2746 
2747 	  dest = reorder;
2748 	  src = buffer;
2749 	  offset = scanner->params.pixels_per_line;
2750 
2751 	  for (i = scanner->params.pixels_per_line; i > 0; i--)
2752 	    {
2753 	      *dest++ = *src;
2754 	      *dest++ = *(src + offset);
2755 	      *dest++ = *(src + 2 * offset);
2756 	      src++;
2757 	    }
2758 	  fwrite (reorder, 1, scanner->params.bytes_per_line, fp);
2759 	}
2760       else
2761 	{
2762 	  fwrite (buffer, 1, scanner->params.bytes_per_line, fp);
2763 	}
2764 
2765       fflush (fp);
2766     }
2767 
2768   free (buffer);
2769   free (reorder);
2770 
2771   return 0;
2772 }
2773 
2774 
2775 
2776 /* --------------------------------- READER PROCESS SIGTERM HANDLER  ------------ */
2777 
2778 
2779 static void
reader_process_sigterm_handler(int signal)2780 reader_process_sigterm_handler (int signal)
2781 {
2782   DBG (DBG_sane_info, "reader_process: terminated by signal %d\n", signal);
2783 
2784 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
2785   sanei_scsi_req_flush_all ();	/* flush SCSI queue */
2786 #else
2787   sanei_scsi_req_flush_all ();	/* flush SCSI queue */
2788 #endif
2789 
2790   _exit (SANE_STATUS_GOOD);
2791 }
2792 
2793 
2794 
2795 /* ------------------------------ READER PROCESS ----------------------------- */
2796 
2797 
2798 static int
reader_process(void * data)2799 reader_process ( void *data )	/* executed as a child process */
2800 {
2801   int status;
2802   FILE *fp;
2803   Pie_Scanner * scanner;
2804   sigset_t ignore_set;
2805   struct SIGACTION act;
2806 
2807   scanner = (Pie_Scanner *)data;
2808 
2809   if (sanei_thread_is_forked ()) {
2810 
2811       close ( scanner->pipe );
2812 
2813       sigfillset (&ignore_set);
2814       sigdelset (&ignore_set, SIGTERM);
2815 #if defined (__APPLE__) && defined (__MACH__)
2816       sigdelset (&ignore_set, SIGUSR2);
2817 #endif
2818       sigprocmask (SIG_SETMASK, &ignore_set, 0);
2819 
2820       memset (&act, 0, sizeof (act));
2821       sigaction (SIGTERM, &act, 0);
2822   }
2823 
2824   DBG (DBG_sane_proc, "reader_process started\n");
2825 
2826   memset (&act, 0, sizeof (act));	/* define SIGTERM-handler */
2827   act.sa_handler = reader_process_sigterm_handler;
2828   sigaction (SIGTERM, &act, 0);
2829 
2830   fp = fdopen (scanner->reader_fds, "w");
2831   if (!fp)
2832     {
2833       return SANE_STATUS_IO_ERROR;
2834     }
2835 
2836   DBG (DBG_sane_info, "reader_process: starting to READ data\n");
2837 
2838   if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_LINE)
2839     status = pie_reader_process (scanner, fp);
2840   else if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_INDEX)
2841     status = pie_reader_process_indexed (scanner, fp);
2842   else
2843     status = SANE_STATUS_UNSUPPORTED;
2844 
2845   fclose (fp);
2846 
2847   DBG (DBG_sane_info, "reader_process: finished reading data\n");
2848 
2849   return status;
2850 }
2851 
2852 
2853 /* -------------------------------- ATTACH_ONE ---------------------------------- */
2854 
2855 
2856 /* callback function for sanei_config_attach_matching_devices(dev_name, attach_one) */
2857 static SANE_Status
attach_one(const char * name)2858 attach_one (const char *name)
2859 {
2860   attach_scanner (name, 0);
2861   return SANE_STATUS_GOOD;
2862 }
2863 
2864 
2865 /* ----------------------------- CLOSE PIPE ---------------------------------- */
2866 
2867 
2868 static SANE_Status
close_pipe(Pie_Scanner * scanner)2869 close_pipe (Pie_Scanner * scanner)
2870 {
2871   DBG (DBG_sane_proc, "close_pipe\n");
2872 
2873   if (scanner->pipe >= 0)
2874     {
2875       close (scanner->pipe);
2876       scanner->pipe = -1;
2877     }
2878 
2879   return SANE_STATUS_EOF;
2880 }
2881 
2882 
2883 
2884 /* ---------------------------- DO CANCEL ---------------------------------- */
2885 
2886 
2887 static SANE_Status
do_cancel(Pie_Scanner * scanner)2888 do_cancel (Pie_Scanner * scanner)
2889 {
2890   DBG (DBG_sane_proc, "do_cancel\n");
2891 
2892   scanner->scanning = SANE_FALSE;
2893 
2894   if (sanei_thread_is_valid (scanner->reader_pid))
2895     {
2896       DBG (DBG_sane_info, "killing reader_process\n");
2897       sanei_thread_kill (scanner->reader_pid);
2898       sanei_thread_waitpid (scanner->reader_pid, 0);
2899       sanei_thread_invalidate (scanner->reader_pid);
2900       DBG (DBG_sane_info, "reader_process killed\n");
2901     }
2902 
2903   if (scanner->sfd >= 0)
2904     {
2905       pie_scan (scanner, 0);
2906 
2907       pie_power_save (scanner, 15);
2908 
2909       pie_give_scanner (scanner);	/* reposition and release scanner */
2910 
2911       DBG (DBG_sane_info, "closing scannerdevice filedescriptor\n");
2912       sanei_scsi_close (scanner->sfd);
2913       scanner->sfd = -1;
2914     }
2915 
2916   return SANE_STATUS_CANCELLED;
2917 }
2918 
2919 
2920 
2921 /* --------------------------------------- SANE INIT ---------------------------------- */
2922 
2923 
2924 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback __sane_unused__ authorize)2925 sane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize)
2926 {
2927   char dev_name[PATH_MAX];
2928   size_t len;
2929   FILE *fp;
2930 
2931   DBG_INIT ();
2932 
2933   DBG (DBG_sane_init, "sane_init() build %d\n", BUILD);
2934 
2935   if (version_code)
2936     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
2937 
2938   fp = sanei_config_open (PIE_CONFIG_FILE);
2939   if (!fp)
2940     {
2941       attach_scanner ("/dev/scanner", 0);	/* no config-file: /dev/scanner */
2942       return SANE_STATUS_GOOD;
2943     }
2944 
2945   while (sanei_config_read (dev_name, sizeof (dev_name), fp))
2946     {
2947       if (dev_name[0] == '#')
2948 	{
2949 	  continue;
2950 	}			/* ignore line comments */
2951 
2952       len = strlen (dev_name);
2953 
2954       if (!len)			/* ignore empty lines */
2955 	{
2956 	  continue;
2957 	}
2958 
2959       sanei_config_attach_matching_devices (dev_name, attach_one);
2960     }
2961 
2962   fclose (fp);
2963 
2964   return SANE_STATUS_GOOD;
2965 }
2966 
2967 
2968 /* ----------------------------------------- SANE EXIT ---------------------------------- */
2969 
2970 
2971 void
sane_exit(void)2972 sane_exit (void)
2973 {
2974   Pie_Device *dev, *next;
2975   int i;
2976 
2977   DBG (DBG_sane_init, "sane_exit()\n");
2978 
2979   for (dev = first_dev; dev; dev = next)
2980     {
2981       next = dev->next;
2982       free (dev->devicename);
2983       free (dev->cal_info);
2984       i = 0;
2985       while (dev->halftone_list[i] != NULL)
2986 	free (dev->halftone_list[i++]);
2987       i = 0;
2988       while (dev->speed_list[i] != NULL)
2989 	free (dev->speed_list[i++]);
2990 
2991       free (dev);
2992     }
2993 
2994   first_dev = NULL;
2995 
2996   if (devlist)
2997     {
2998       free (devlist);
2999       devlist = NULL;
3000     }
3001 }
3002 
3003 
3004 /* ------------------------------------------ SANE GET DEVICES --------------------------- */
3005 
3006 
3007 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool __sane_unused__ local_only)3008 sane_get_devices (const SANE_Device *** device_list, SANE_Bool __sane_unused__ local_only)
3009 {
3010   Pie_Device *dev;
3011   int i;
3012 
3013   DBG (DBG_sane_init, "sane_get_devices\n");
3014 
3015   i = 0;
3016   for (dev = first_dev; dev; dev = dev->next)
3017     i++;
3018 
3019   if (devlist)
3020     {
3021       free (devlist);
3022     }
3023 
3024   devlist = malloc ((i + 1) * sizeof (devlist[0]));
3025   if (!devlist)
3026     {
3027       return SANE_STATUS_NO_MEM;
3028     }
3029 
3030   i = 0;
3031 
3032   for (dev = first_dev; dev; dev = dev->next)
3033     {
3034       devlist[i++] = &dev->sane;
3035     }
3036 
3037   devlist[i] = NULL;
3038 
3039   *device_list = devlist;
3040 
3041   return SANE_STATUS_GOOD;
3042 }
3043 
3044 
3045 /* --------------------------------------- SANE OPEN ---------------------------------- */
3046 
3047 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)3048 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
3049 {
3050   Pie_Device *dev;
3051   SANE_Status status;
3052   Pie_Scanner *scanner;
3053   int i, j;
3054 
3055   DBG (DBG_sane_init, "sane_open(%s)\n", devicename);
3056 
3057   if (devicename[0])		/* search for devicename */
3058     {
3059       for (dev = first_dev; dev; dev = dev->next)
3060 	{
3061 	  if (strcmp (dev->sane.name, devicename) == 0)
3062 	    {
3063 	      break;
3064 	    }
3065 	}
3066 
3067       if (!dev)
3068 	{
3069 	  status = attach_scanner (devicename, &dev);
3070 	  if (status != SANE_STATUS_GOOD)
3071 	    {
3072 	      return status;
3073 	    }
3074 	}
3075     }
3076   else
3077     {
3078       dev = first_dev;		/* empty devicename -> use first device */
3079     }
3080 
3081 
3082   if (!dev)
3083     {
3084       return SANE_STATUS_INVAL;
3085     }
3086 
3087   scanner = malloc (sizeof (*scanner));
3088   if (!scanner)
3089 
3090     {
3091       return SANE_STATUS_NO_MEM;
3092     }
3093 
3094   memset (scanner, 0, sizeof (*scanner));
3095 
3096   scanner->device = dev;
3097   scanner->sfd = -1;
3098   scanner->pipe = -1;
3099 
3100   scanner->gamma_length = 1 << (scanner->device->inquiry_gamma_bits);
3101 
3102   DBG (DBG_sane_info, "Using %d bits for gamma input\n",
3103        scanner->device->inquiry_gamma_bits);
3104 
3105   scanner->gamma_range.min = 0;
3106   scanner->gamma_range.max = scanner->gamma_length - 1;
3107   scanner->gamma_range.quant = 0;
3108 
3109   scanner->gamma_table[0] =
3110     (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int));
3111   scanner->gamma_table[1] =
3112     (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int));
3113   scanner->gamma_table[2] =
3114     (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int));
3115   scanner->gamma_table[3] =
3116     (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int));
3117 
3118   for (i = 0; i < 4; ++i)	/* gamma_table[0,1,2,3] */
3119     {
3120       for (j = 0; j < scanner->gamma_length; ++j)
3121 	{
3122 	  scanner->gamma_table[i][j] = j;
3123 	}
3124     }
3125 
3126   init_options (scanner);
3127 
3128   scanner->next = first_handle;	/* insert newly opened handle into list of open handles: */
3129   first_handle = scanner;
3130 
3131   *handle = scanner;
3132 
3133   return SANE_STATUS_GOOD;
3134 }
3135 
3136 
3137 /* ------------------------------------ SANE CLOSE --------------------------------- */
3138 
3139 
3140 void
sane_close(SANE_Handle handle)3141 sane_close (SANE_Handle handle)
3142 {
3143   Pie_Scanner *prev, *scanner;
3144 
3145   DBG (DBG_sane_init, "sane_close\n");
3146 
3147   /* remove handle from list of open handles: */
3148   prev = 0;
3149 
3150   for (scanner = first_handle; scanner; scanner = scanner->next)
3151     {
3152       if (scanner == handle)
3153 	{
3154 	  break;
3155 	}
3156 
3157       prev = scanner;
3158     }
3159 
3160   if (!scanner)
3161     {
3162       DBG (DBG_error, "close: invalid handle %p\n", handle);
3163       return;			/* oops, not a handle we know about */
3164     }
3165 
3166   if (scanner->scanning)	/* stop scan if still scanning */
3167     {
3168       do_cancel (handle);
3169     }
3170 
3171   if (prev)
3172     {
3173       prev->next = scanner->next;
3174     }
3175   else
3176     {
3177       first_handle = scanner->next;
3178     }
3179 
3180   free (scanner->gamma_table[0]);	/* free custom gamma tables */
3181   free (scanner->gamma_table[1]);
3182   free (scanner->gamma_table[2]);
3183   free (scanner->gamma_table[3]);
3184   free (scanner->val[OPT_MODE].s);
3185   free (scanner->val[OPT_SPEED].s);
3186   free (scanner->val[OPT_HALFTONE_PATTERN].s);
3187 
3188   scanner->bufsize = 0;
3189 
3190   free (scanner);		/* free scanner */
3191 }
3192 
3193 
3194 /* ---------------------------------- SANE GET OPTION DESCRIPTOR ----------------- */
3195 
3196 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)3197 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
3198 {
3199   Pie_Scanner *scanner = handle;
3200 
3201   DBG (DBG_sane_option, "sane_get_option_descriptor %d\n", option);
3202 
3203   if ((unsigned) option >= NUM_OPTIONS)
3204     {
3205       return 0;
3206     }
3207 
3208   return scanner->opt + option;
3209 }
3210 
3211 
3212 /* ---------------------------------- SANE CONTROL OPTION ------------------------ */
3213 
3214 
3215 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)3216 sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
3217 		     void *val, SANE_Int * info)
3218 {
3219   Pie_Scanner *scanner = handle;
3220   SANE_Status status;
3221   SANE_Word cap;
3222   SANE_String_Const name;
3223 
3224   if (info)
3225     {
3226       *info = 0;
3227     }
3228 
3229   if (scanner->scanning)
3230     {
3231       return SANE_STATUS_DEVICE_BUSY;
3232     }
3233 
3234   if ((unsigned) option >= NUM_OPTIONS)
3235     {
3236       return SANE_STATUS_INVAL;
3237     }
3238 
3239   cap = scanner->opt[option].cap;
3240   if (!SANE_OPTION_IS_ACTIVE (cap))
3241     {
3242       return SANE_STATUS_INVAL;
3243     }
3244 
3245   name = scanner->opt[option].name;
3246   if (!name)
3247     {
3248       name = "(no name)";
3249     }
3250 
3251   if (action == SANE_ACTION_GET_VALUE)
3252     {
3253 
3254       DBG (DBG_sane_option, "get %s [#%d]\n", name, option);
3255 
3256       switch (option)
3257 	{
3258 	  /* word options: */
3259 	case OPT_NUM_OPTS:
3260 	case OPT_RESOLUTION:
3261 	case OPT_TL_X:
3262 	case OPT_TL_Y:
3263 	case OPT_BR_X:
3264 	case OPT_BR_Y:
3265 	case OPT_PREVIEW:
3266 	case OPT_THRESHOLD:
3267 	  *(SANE_Word *) val = scanner->val[option].w;
3268 	  return SANE_STATUS_GOOD;
3269 
3270 	  /* word-array options: */
3271 	case OPT_GAMMA_VECTOR:
3272 	case OPT_GAMMA_VECTOR_R:
3273 	case OPT_GAMMA_VECTOR_G:
3274 	case OPT_GAMMA_VECTOR_B:
3275 	  memcpy (val, scanner->val[option].wa, scanner->opt[option].size);
3276 	  return SANE_STATUS_GOOD;
3277 
3278 #if 0
3279 	  /* string options: */
3280 	case OPT_SOURCE:
3281 #endif
3282 	case OPT_MODE:
3283 	case OPT_HALFTONE_PATTERN:
3284 	case OPT_SPEED:
3285 	  strcpy (val, scanner->val[option].s);
3286 	  return SANE_STATUS_GOOD;
3287 	}
3288     }
3289   else if (action == SANE_ACTION_SET_VALUE)
3290     {
3291       switch (scanner->opt[option].type)
3292 	{
3293 	case SANE_TYPE_INT:
3294 	  DBG (DBG_sane_option, "set %s [#%d] to %d\n", name, option,
3295 	       *(SANE_Word *) val);
3296 	  break;
3297 
3298 	case SANE_TYPE_FIXED:
3299 	  DBG (DBG_sane_option, "set %s [#%d] to %f\n", name, option,
3300 	       SANE_UNFIX (*(SANE_Word *) val));
3301 	  break;
3302 
3303 	case SANE_TYPE_STRING:
3304 	  DBG (DBG_sane_option, "set %s [#%d] to %s\n", name, option,
3305 	       (char *) val);
3306 	  break;
3307 
3308 	case SANE_TYPE_BOOL:
3309 	  DBG (DBG_sane_option, "set %s [#%d] to %d\n", name, option,
3310 	       *(SANE_Word *) val);
3311 	  break;
3312 
3313 	default:
3314 	  DBG (DBG_sane_option, "set %s [#%d]\n", name, option);
3315 	}
3316 
3317       if (!SANE_OPTION_IS_SETTABLE (cap))
3318 	{
3319 	  return SANE_STATUS_INVAL;
3320 	}
3321 
3322       status = sanei_constrain_value (scanner->opt + option, val, info);
3323       if (status != SANE_STATUS_GOOD)
3324 	{
3325 	  return status;
3326 	}
3327 
3328       switch (option)
3329 	{
3330 	  /* (mostly) side-effect-free word options: */
3331 	case OPT_RESOLUTION:
3332 	case OPT_TL_X:
3333 	case OPT_TL_Y:
3334 	case OPT_BR_X:
3335 	case OPT_BR_Y:
3336 	  if (info)
3337 	    {
3338 	      *info |= SANE_INFO_RELOAD_PARAMS;
3339 	    }
3340 	  /* fall through */
3341 	case OPT_NUM_OPTS:
3342 	case OPT_PREVIEW:
3343 	case OPT_THRESHOLD:
3344 	  scanner->val[option].w = *(SANE_Word *) val;
3345 	  return SANE_STATUS_GOOD;
3346 
3347 	  /* side-effect-free word-array options: */
3348 	case OPT_GAMMA_VECTOR:
3349 	case OPT_GAMMA_VECTOR_R:
3350 	case OPT_GAMMA_VECTOR_G:
3351 	case OPT_GAMMA_VECTOR_B:
3352 	  memcpy (scanner->val[option].wa, val, scanner->opt[option].size);
3353 	  return SANE_STATUS_GOOD;
3354 
3355 	  /* options with side-effects: */
3356 
3357 	case OPT_MODE:
3358 	  {
3359 	    int halftoning;
3360 
3361 	    if (scanner->val[option].s)
3362 	      {
3363 		free (scanner->val[option].s);
3364 	      }
3365 
3366 	    scanner->val[option].s = (SANE_Char *) strdup (val);
3367 
3368 	    if (info)
3369 	      {
3370 		*info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
3371 	      }
3372 
3373 	    scanner->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
3374 
3375 
3376 	    scanner->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
3377 	    scanner->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
3378 	    scanner->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
3379 	    scanner->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
3380 	    scanner->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
3381 
3382 	    halftoning = (strcmp (val, HALFTONE_STR) == 0);
3383 
3384 	    if (halftoning || strcmp (val, LINEART_STR) == 0)
3385 	      {			/* one bit modes */
3386 		if (halftoning)
3387 		  {		/* halftoning modes */
3388 		    scanner->opt[OPT_HALFTONE_PATTERN].cap &=
3389 		      ~SANE_CAP_INACTIVE;
3390 		  }
3391 		else
3392 		  {		/* lineart modes */
3393 		  }
3394 		scanner->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
3395 	      }
3396 	    else
3397 	      {			/* multi-bit modes(gray or color) */
3398 	      }
3399 
3400 	    if ((strcmp (val, LINEART_STR) == 0)
3401 		|| (strcmp (val, HALFTONE_STR) == 0)
3402 		|| (strcmp (val, GRAY_STR) == 0))
3403 	      {
3404 		scanner->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
3405 	      }
3406 	    else if (strcmp (val, COLOR_STR) == 0)
3407 	      {
3408 		/* scanner->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; */
3409 		scanner->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
3410 		scanner->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
3411 		scanner->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
3412 	      }
3413 	    return SANE_STATUS_GOOD;
3414 	  }
3415 
3416 	case OPT_SPEED:
3417 	case OPT_HALFTONE_PATTERN:
3418 	  {
3419 	    if (scanner->val[option].s)
3420 	      {
3421 		free (scanner->val[option].s);
3422 	      }
3423 
3424 	    scanner->val[option].s = (SANE_Char *) strdup (val);
3425 
3426 	    return SANE_STATUS_GOOD;
3427 	  }
3428 	}
3429     }				/* else */
3430   return SANE_STATUS_INVAL;
3431 }
3432 
3433 
3434 /* ------------------------------------ SANE GET PARAMETERS ------------------------ */
3435 
3436 
3437 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)3438 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
3439 {
3440   Pie_Scanner *scanner = handle;
3441   const char *mode;
3442 
3443   DBG (DBG_sane_info, "sane_get_parameters\n");
3444 
3445   if (!scanner->scanning)
3446     {				/* not scanning, so lets use recent values */
3447       double width, length, x_dpi, y_dpi;
3448 
3449       memset (&scanner->params, 0, sizeof (scanner->params));
3450 
3451       width =
3452 	SANE_UNFIX (scanner->val[OPT_BR_X].w - scanner->val[OPT_TL_X].w);
3453       length =
3454 	SANE_UNFIX (scanner->val[OPT_BR_Y].w - scanner->val[OPT_TL_Y].w);
3455       x_dpi = SANE_UNFIX (scanner->val[OPT_RESOLUTION].w);
3456       y_dpi = x_dpi;
3457 
3458 #if 0
3459       if ((scanner->val[OPT_RESOLUTION_BIND].w == SANE_TRUE)
3460 	  || (scanner->val[OPT_PREVIEW].w == SANE_TRUE))
3461 	{
3462 	  y_dpi = x_dpi;
3463 	}
3464 #endif
3465       if (x_dpi > 0.0 && y_dpi > 0.0 && width > 0.0 && length > 0.0)
3466 	{
3467 	  double x_dots_per_mm = x_dpi / MM_PER_INCH;
3468 	  double y_dots_per_mm = y_dpi / MM_PER_INCH;
3469 
3470 	  scanner->params.pixels_per_line = width * x_dots_per_mm;
3471 	  scanner->params.lines = length * y_dots_per_mm;
3472 	}
3473     }
3474 
3475   mode = scanner->val[OPT_MODE].s;
3476 
3477   if (strcmp (mode, LINEART_STR) == 0 || strcmp (mode, HALFTONE_STR) == 0)
3478     {
3479       scanner->params.format = SANE_FRAME_GRAY;
3480       scanner->params.bytes_per_line =
3481 	(scanner->params.pixels_per_line + 7) / 8;
3482       scanner->params.depth = 1;
3483     }
3484   else if (strcmp (mode, GRAY_STR) == 0)
3485     {
3486       scanner->params.format = SANE_FRAME_GRAY;
3487       scanner->params.bytes_per_line = scanner->params.pixels_per_line;
3488       scanner->params.depth = 8;
3489     }
3490   else				/* RGB */
3491     {
3492       scanner->params.format = SANE_FRAME_RGB;
3493       scanner->params.bytes_per_line = 3 * scanner->params.pixels_per_line;
3494       scanner->params.depth = 8;
3495     }
3496 
3497   scanner->params.last_frame = (scanner->params.format != SANE_FRAME_RED
3498 				&& scanner->params.format !=
3499 				SANE_FRAME_GREEN);
3500 
3501   if (params)
3502     {
3503       *params = scanner->params;
3504     }
3505 
3506   return SANE_STATUS_GOOD;
3507 }
3508 
3509 
3510 /* ----------------------------------------- SANE START --------------------------------- */
3511 
3512 
3513 SANE_Status
sane_start(SANE_Handle handle)3514 sane_start (SANE_Handle handle)
3515 {
3516   Pie_Scanner *scanner = handle;
3517   int fds[2];
3518   const char *mode;
3519   int status;
3520 
3521   DBG (DBG_sane_init, "sane_start\n");
3522 
3523   /* Check for inconsistencies */
3524 
3525   if (scanner->val[OPT_TL_X].w > scanner->val[OPT_BR_X].w)
3526     {
3527       DBG (0, "sane_start: %s (%.1f mm) is bigger than %s (%.1f mm) "
3528               "-- aborting\n",
3529               scanner->opt[OPT_TL_X].title, SANE_UNFIX (scanner->val[OPT_TL_X].w),
3530               scanner->opt[OPT_BR_X].title, SANE_UNFIX (scanner->val[OPT_BR_X].w));
3531       return SANE_STATUS_INVAL;
3532     }
3533   if (scanner->val[OPT_TL_Y].w > scanner->val[OPT_BR_Y].w)
3534     {
3535       DBG (0, "sane_start: %s (%.1f mm) is bigger than %s (%.1f mm) "
3536 	      "-- aborting\n",
3537 	      scanner->opt[OPT_TL_Y].title, SANE_UNFIX (scanner->val[OPT_TL_Y].w),
3538 	      scanner->opt[OPT_BR_Y].title, SANE_UNFIX (scanner->val[OPT_BR_Y].w));
3539       return SANE_STATUS_INVAL;
3540     }
3541 
3542   mode = scanner->val[OPT_MODE].s;
3543 
3544   if (scanner->sfd < 0)		/* first call, don`t run this routine again on multi frame or multi image scan */
3545     {
3546 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
3547       int scsi_bufsize = 131072;	/* 128KB */
3548 
3549       if (sanei_scsi_open_extended
3550 	  (scanner->device->sane.name, &(scanner->sfd), sense_handler,
3551 	   scanner->device, &scsi_bufsize) != 0)
3552 
3553 	{
3554 	  DBG (DBG_error, "sane_start: open failed\n");
3555 	  return SANE_STATUS_INVAL;
3556 	}
3557 
3558       if (scsi_bufsize < 32768)	/* < 32KB */
3559 	{
3560 	  DBG (DBG_error,
3561 	       "sane_start: sanei_scsi_open_extended returned too small scsi buffer (%d)\n",
3562 	       scsi_bufsize);
3563 	  sanei_scsi_close ((scanner->sfd));
3564 	  return SANE_STATUS_NO_MEM;
3565 	}
3566       DBG (DBG_info,
3567 	   "sane_start: sanei_scsi_open_extended returned scsi buffer size = %d\n",
3568 	   scsi_bufsize);
3569 
3570 
3571       scanner->bufsize = scsi_bufsize;
3572 #else
3573       if (sanei_scsi_open
3574 	  (scanner->device->sane.name, &(scanner->sfd), sense_handler,
3575 	   scanner->device) != SANE_STATUS_GOOD)
3576 	{
3577 	  DBG (DBG_error, "sane_start: open of %s failed:\n",
3578 	       scanner->device->sane.name);
3579 	  return SANE_STATUS_INVAL;
3580 	}
3581 
3582       /* there is no need to reallocate the buffer because the size is fixed */
3583 #endif
3584 
3585 #if 0
3586       if (pie_check_values (scanner->device) != 0)
3587 	{
3588 	  DBG (DBG_error, "ERROR: invalid scan-values\n");
3589 	  scanner->scanning = SANE_FALSE;
3590 	  pie_give_scanner (scanner);	/* reposition and release scanner */
3591 	  sanei_scsi_close (scanner->sfd);
3592 	  scanner->sfd = -1;
3593 	  return SANE_STATUS_INVAL;
3594 	}
3595 #endif
3596 #if 0
3597       scanner->params.bytes_per_line = scanner->device->row_len;
3598       scanner->params.pixels_per_line = scanner->device->width_in_pixels;
3599       scanner->params.lines = scanner->device->length_in_pixels;
3600 
3601       sane_get_parameters (scanner, 0);
3602 
3603       DBG (DBG_sane_info, "x_resolution (dpi)      = %u\n",
3604 	   scanner->device->x_resolution);
3605       DBG (DBG_sane_info, "y_resolution (dpi)      = %u\n",
3606 	   scanner->device->y_resolution);
3607       DBG (DBG_sane_info, "x_coordinate_base (dpi) = %u\n",
3608 	   scanner->device->x_coordinate_base);
3609       DBG (DBG_sane_info, "y_coordinate_base (dpi) = %u\n",
3610 	   scanner->device->y_coordinate_base);
3611       DBG (DBG_sane_info, "upper_left_x (xbase)    = %d\n",
3612 	   scanner->device->upper_left_x);
3613       DBG (DBG_sane_info, "upper_left_y (ybase)    = %d\n",
3614 	   scanner->device->upper_left_y);
3615       DBG (DBG_sane_info, "scanwidth    (xbase)    = %u\n",
3616 	   scanner->device->scanwidth);
3617       DBG (DBG_sane_info, "scanlength   (ybase)    = %u\n",
3618 	   scanner->device->scanlength);
3619       DBG (DBG_sane_info, "width in pixels         = %u\n",
3620 	   scanner->device->width_in_pixels);
3621       DBG (DBG_sane_info, "length in pixels        = %u\n",
3622 	   scanner->device->length_in_pixels);
3623       DBG (DBG_sane_info, "bits per pixel/color    = %u\n",
3624 	   scanner->device->bits_per_pixel);
3625       DBG (DBG_sane_info, "bytes per line          = %d\n",
3626 	   scanner->params.bytes_per_line);
3627       DBG (DBG_sane_info, "pixels_per_line         = %d\n",
3628 	   scanner->params.pixels_per_line);
3629       DBG (DBG_sane_info, "lines                   = %d\n",
3630 	   scanner->params.lines);
3631 #endif
3632 
3633       /* grab scanner */
3634       if (pie_grab_scanner (scanner))
3635 	{
3636 	  sanei_scsi_close (scanner->sfd);
3637 	  scanner->sfd = -1;
3638 	  DBG (DBG_warning,
3639 	       "WARNING: unable to reserve scanner: device busy\n");
3640 	  return SANE_STATUS_DEVICE_BUSY;
3641 	}
3642 
3643       scanner->scanning = SANE_TRUE;
3644 
3645       pie_power_save (scanner, 0);
3646     }				/* ------------ end of first call -------------- */
3647 
3648 
3649   if (strcmp (mode, LINEART_STR) == 0)
3650     {
3651       scanner->colormode = LINEART;
3652     }
3653   else if (strcmp (mode, HALFTONE_STR) == 0)
3654     {
3655       scanner->colormode = HALFTONE;
3656     }
3657   else if (strcmp (mode, GRAY_STR) == 0)
3658     {
3659       scanner->colormode = GRAYSCALE;
3660     }
3661   else if (strcmp (mode, COLOR_STR) == 0)
3662     {
3663       scanner->colormode = RGB;
3664     }
3665 
3666   /* get and set geometric values for scanning */
3667   scanner->resolution = SANE_UNFIX (scanner->val[OPT_RESOLUTION].w);
3668 
3669   pie_set_window (scanner);
3670   pie_send_exposure (scanner);
3671   pie_mode_select (scanner);
3672   pie_send_highlight_shadow (scanner);
3673 
3674   pie_scan (scanner, 1);
3675 
3676   status = pie_do_cal (scanner);
3677   if (status)
3678     return status;
3679 
3680   /* send gammacurves */
3681 
3682   pie_dwnld_gamma (scanner);
3683 
3684   pie_get_params (scanner);
3685 
3686   if (pipe (fds) < 0)		/* create a pipe, fds[0]=read-fd, fds[1]=write-fd */
3687     {
3688       DBG (DBG_error, "ERROR: could not create pipe\n");
3689       scanner->scanning = SANE_FALSE;
3690       pie_scan (scanner, 0);
3691       pie_give_scanner (scanner);	/* reposition and release scanner */
3692       sanei_scsi_close (scanner->sfd);
3693       scanner->sfd = -1;
3694       return SANE_STATUS_IO_ERROR;
3695     }
3696 
3697   scanner->pipe       = fds[0];
3698   scanner->reader_fds = fds[1];
3699   scanner->reader_pid = sanei_thread_begin( reader_process, (void*)scanner );
3700 
3701   if (!sanei_thread_is_valid (scanner->reader_pid))
3702     {
3703       DBG (1, "sane_start: sanei_thread_begin failed (%s)\n",
3704              strerror (errno));
3705       return SANE_STATUS_NO_MEM;
3706     }
3707 
3708   if (sanei_thread_is_forked ())
3709     {
3710       close (scanner->reader_fds);
3711       scanner->reader_fds = -1;
3712     }
3713 
3714   return SANE_STATUS_GOOD;
3715 }
3716 
3717 
3718 /* -------------------------------------- SANE READ ---------------------------------- */
3719 
3720 
3721 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)3722 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
3723 	   SANE_Int * len)
3724 {
3725   Pie_Scanner *scanner = handle;
3726   ssize_t nread;
3727 
3728   *len = 0;
3729 
3730   nread = read (scanner->pipe, buf, max_len);
3731   DBG (DBG_sane_info, "sane_read: read %ld bytes\n", (long) nread);
3732 
3733   if (!(scanner->scanning))	/* OOPS, not scanning */
3734     {
3735       return do_cancel (scanner);
3736     }
3737 
3738   if (nread < 0)
3739     {
3740       if (errno == EAGAIN)
3741 	{
3742 	  DBG (DBG_sane_info, "sane_read: EAGAIN\n");
3743 	  return SANE_STATUS_GOOD;
3744 	}
3745       else
3746 	{
3747 	  do_cancel (scanner);	/* we had an error, stop scanner */
3748 	  return SANE_STATUS_IO_ERROR;
3749 	}
3750     }
3751 
3752   *len = nread;
3753 
3754   if (nread == 0)		/* EOF */
3755     {
3756       do_cancel (scanner);
3757 
3758       return close_pipe (scanner);	/* close pipe */
3759     }
3760 
3761   return SANE_STATUS_GOOD;
3762 }
3763 
3764 
3765 /* ------------------------------------- SANE CANCEL -------------------------------- */
3766 
3767 
3768 void
sane_cancel(SANE_Handle handle)3769 sane_cancel (SANE_Handle handle)
3770 {
3771   Pie_Scanner *scanner = handle;
3772 
3773   DBG (DBG_sane_init, "sane_cancel\n");
3774 
3775   if (scanner->scanning)
3776     {
3777       do_cancel (scanner);
3778     }
3779 }
3780 
3781 
3782 /* -------------------------------------- SANE SET IO MODE --------------------------- */
3783 
3784 
3785 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)3786 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
3787 {
3788   Pie_Scanner *scanner = handle;
3789 
3790   DBG (DBG_sane_init, "sane_set_io_mode: non_blocking=%d\n", non_blocking);
3791 
3792   if (!scanner->scanning)
3793     {
3794       return SANE_STATUS_INVAL;
3795     }
3796 
3797   if (fcntl (scanner->pipe, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0)
3798     {
3799       return SANE_STATUS_IO_ERROR;
3800     }
3801 
3802   return SANE_STATUS_GOOD;
3803 }
3804 
3805 
3806 /* --------------------------------------- SANE GET SELECT FD ------------------------- */
3807 
3808 
3809 SANE_Status
sane_get_select_fd(SANE_Handle handle,SANE_Int * fd)3810 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
3811 {
3812   Pie_Scanner *scanner = handle;
3813 
3814   DBG (DBG_sane_init, "sane_get_select_fd\n");
3815 
3816   if (!scanner->scanning)
3817     {
3818       return SANE_STATUS_INVAL;
3819     }
3820   *fd = scanner->pipe;
3821 
3822   return SANE_STATUS_GOOD;
3823 }
3824