• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------------- */
2 /* sane - Scanner Access Now Easy.
3    coolscan.c , version  0.4.4
4 
5    This file is part of the SANE package.
6 
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <https://www.gnu.org/licenses/>.
19 
20    As a special exception, the authors of SANE give permission for
21    additional uses of the libraries contained in this release of SANE.
22 
23    The exception is that, if you link a SANE library with other files
24    to produce an executable, this does not by itself cause the
25    resulting executable to be covered by the GNU General Public
26    License.  Your use of that executable is in no way restricted on
27    account of linking the SANE library code into it.
28 
29    This exception does not, however, invalidate any other reasons why
30    the executable file might be covered by the GNU General Public
31    License.
32 
33    If you submit changes to SANE to the maintainers to be included in
34    a subsequent release, you agree by submitting the changes that
35    those changes may be distributed with this exception intact.
36 
37    If you write modifications of your own for SANE, it is your choice
38    whether to permit this exception to apply to your modifications.
39    If you do not wish that, delete this exception notice.
40 
41    This file implements a SANE backend for COOLSCAN flatbed scanners.  */
42 
43 /* ------------------------------------------------------------------------- */
44 
45 
46 /* SANE-FLOW-DIAGRAMM
47 
48    - sane_init() : initialize backend, attach scanners
49    . - sane_get_devices() : query list of scanner-devices
50    . - sane_open() : open a particular scanner-device
51    . . - sane_set_io_mode : set blocking-mode
52    . . - sane_get_select_fd : get scanner-fd
53    . . - sane_get_option_descriptor() : get option information
54    . . - sane_control_option() : change option values
55    . .
56    . . - sane_start() : start image acquisition
57    . .   - sane_get_parameters() : returns actual scan-parameters
58    . .   - sane_read() : read image-data (from pipe)
59    . .
60    . . - sane_cancel() : cancel operation
61    . - sane_close() : close opened scanner-device
62    - sane_exit() : terminate use of backend
63  */
64 
65 #ifdef _AIX
66 # include "lalloca.h"		/* MUST come first for AIX! */
67 #endif
68 
69 #include "../include/sane/config.h"
70 #include "lalloca.h"
71 
72 #include <errno.h>
73 #include <math.h>
74 #include <fcntl.h>
75 #include <limits.h>
76 #include <signal.h>
77 #include <stdio.h>
78 #include <stdlib.h>
79 #include <string.h>
80 
81 #include <sys/types.h>
82 #include <unistd.h>
83 
84 #include "../include/sane/sane.h"
85 #include "../include/sane/sanei.h"
86 #include "../include/sane/saneopts.h"
87 #include "../include/sane/sanei_scsi.h"
88 #include "../include/sane/sanei_debug.h"
89 #include "../include/sane/sanei_thread.h"
90 
91 #include "../include/sane/sanei_config.h"
92 #define COOLSCAN_CONFIG_FILE "coolscan.conf"
93 #include "../include/sane/sanei_backend.h"
94 
95 #include "coolscan.h"
96 #include "coolscan-scsidef.h"
97 
98 
99 #ifndef PATH_MAX
100 #define PATH_MAX       1024
101 #endif
102 
103 /* ------------------------------------------------------------------------- */
104 static const SANE_Int resolution_list[] =
105 {
106   25,
107   2700, 1350, 900, 675, 540, 450, 385, 337, 300, 270, 245, 225, 207,
108   192, 180, 168, 158, 150, 142, 135, 128, 122, 117, 112, 108
109 };
110 
111 
112 #define coolscan_do_scsi_open(dev, fd, handler) sanei_scsi_open(dev, fd, handler)
113 #define coolscan_do_scsi_close(fd)              sanei_scsi_close(fd)
114 
115 #define	COOLSCAN_MAX_RETRY	25
116 
117 
118 static SANE_Status sense_handler (int scsi_fd, unsigned char * result, void *arg);
119 static int coolscan_check_values (Coolscan_t * s);
120 static int get_internal_info (Coolscan_t *);
121 static void coolscan_get_inquiry_values (Coolscan_t *);
122 static void hexdump (int level, char *comment, unsigned char *p, int l);
123 static int swap_res (Coolscan_t * s);
124 /* --------------------------- COOLSCAN_DO_SCSI_CMD  ----------------------- */
125 static int
do_scsi_cmd(int fd,unsigned char * cmd,int cmd_len,unsigned char * out,size_t out_len)126 do_scsi_cmd (int fd, unsigned char *cmd, int cmd_len, unsigned char *out, size_t out_len)
127 {
128   int ret;
129   size_t ol = out_len;
130 
131   hexdump (20, "", cmd, cmd_len);
132 
133   ret = sanei_scsi_cmd (fd, cmd, cmd_len, out, &ol);
134   if ((out_len != 0) && (out_len != ol))
135     {
136       DBG (1, "sanei_scsi_cmd: asked %lu bytes, got %lu\n",
137 	   (u_long) out_len, (u_long) ol);
138     }
139   if (ret)
140     {
141       DBG (1, "sanei_scsi_cmd: returning 0x%08x\n", ret);
142     }
143   DBG (10, "sanei_scsi_cmd: returning %lu bytes:\n", (u_long) ol);
144   if (out != NULL && out_len != 0)
145     hexdump (15, "", out, (out_len > 0x60) ? 0x60 : out_len);
146 
147   return ret;
148 }
149 
150 
151 static int
request_sense_parse(unsigned char * sensed_data)152 request_sense_parse (unsigned char *sensed_data)
153 {
154   int ret, sense, asc, ascq;
155   sense = get_RS_sense_key (sensed_data);
156   asc = get_RS_ASC (sensed_data);
157   ascq = get_RS_ASCQ (sensed_data);
158 
159   ret = SANE_STATUS_IO_ERROR;
160 
161   switch (sense)
162     {
163     case 0x0:
164       DBG (5, "\t%d/%d/%d: Scanner ready\n", sense, asc, ascq);
165       return SANE_STATUS_GOOD;
166 
167     case 0x1:
168       if ((0x37 == asc) && (0x00 == ascq)) {
169 	DBG (1, "\t%d/%d/%d: Rounded Parameter\n", sense, asc, ascq);
170         ret = SANE_STATUS_GOOD;
171       }
172       else if ((0x61 == asc) && (0x02 == ascq))
173 	DBG (1, "\t%d/%d/%d: Out Of Focus\n", sense, asc, ascq);
174       else
175 	DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
176       break;
177 
178     case 0x2:
179       if ((0x4 == asc) && (0x1 == ascq)) {
180 	DBG (10, "\t%d/%d/%d: Logical unit is in process of becoming ready\n",
181 	     sense, asc, ascq);
182 	ret = SANE_STATUS_DEVICE_BUSY;
183       }
184       else if ((0x3A == asc) && (0x00 == ascq))
185 	{
186 	  DBG (1, "\t%d/%d/%d: No Diapo inserted\n", sense, asc, ascq);
187           ret = SANE_STATUS_GOOD;
188 	}
189       else if ((0x60 == asc) && (0x00 == ascq))
190 	DBG (1, "\t%d/%d/%d: Lamp Failure\n", sense, asc, ascq);
191       else
192 	{
193 	  DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
194           ret = SANE_STATUS_GOOD;
195 	}
196       break;
197 
198     case 0x3:
199       if ((0x3b == asc) && (0xe == ascq))
200 	DBG (1, "\t%d/%d/%d: Medium source element empty\n", sense, asc, ascq);
201       else if ((0x53 == asc) && (0x00 == ascq))
202 	DBG (1, "\t%d/%d/%d: Media Load of Eject Failed\n", sense, asc, ascq);
203       else
204 	DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
205       break;
206 
207     case 0x4:
208       if ((0x15 == asc) && (0x1 == ascq))
209 	DBG (1, "\t%d/%d/%d: Mechanical Positioning Error\n", sense, asc, ascq);
210       else
211 	DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
212       break;
213 
214     case 0x5:
215       if ((0x00 == asc) && (0x5 == ascq))
216 	DBG (1, "\t%d/%d/%d: End-Of-Data Detected\n", sense, asc, ascq);
217       else if ((0x1a == asc) && (0x00 == ascq))
218 	DBG (1, "\t%d/%d/%d: Parameter List Length Error\n", sense, asc, ascq);
219       else if ((0x20 == asc) && (0x00 == ascq))
220 	DBG (1, "\t%d/%d/%d: Invalid Command Operation Code\n", sense, asc, ascq);
221       else if ((0x24 == asc) && (0x00 == ascq))
222 	DBG (1, "\t%d/%d/%d: Invalid Field In CDB\n", sense, asc, ascq);
223       else if ((0x25 == asc) && (0x00 == ascq))
224 	DBG (1, "\t%d/%d/%d: Logical Unit Not Supported\n", sense, asc, ascq);
225       else if ((0x26 == asc) && (0x00 == ascq))
226 	DBG (1, "\t%d/%d/%d: Invalid Field in Parameter List\n", sense, asc, ascq);
227       else if ((0x2c == asc) && (0x00 == ascq))
228 	DBG (1, "\t%d/%d/%d: Command Sequence Error\n", sense, asc, ascq);
229       else if ((0x39 == asc) && (0x00 == ascq))
230 	DBG (1, "\t%d/%d/%d: Saving Parameters Not Supported\n", sense, asc, ascq);
231       else if ((0x3d == asc) && (0x00 == ascq))
232 	DBG (1, "\t%d/%d/%d: Invalid Bits In Identify Message\n", sense, asc, ascq);
233       else
234 	DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
235       break;
236 
237     case 0x6:
238       if ((0x29 == asc) && (0x0 == ascq))
239 	DBG (1, "\t%d/%d/%d: Power On, Reset, or Bus Device Reset Occurred\n", sense, asc, ascq);
240       else if ((0x2a == asc) && (0x1 == ascq))
241 	DBG (1, "\t%d/%d/%d: Mode Parameters Changed\n", sense, asc, ascq);
242       else
243 	DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
244       break;
245 
246     case 0xb:
247       if ((0x43 == asc) && (0x0 == ascq))
248 	DBG (1, "\t%d/%d/%d: Message Error\n", sense, asc, ascq);
249       else if ((0x47 == asc) && (0x0 == ascq))
250 	DBG (1, "\t%d/%d/%d: SCSI Parity Error\n", sense, asc, ascq);
251       else if ((0x48 == asc) && (0x0 == ascq))
252 	DBG (1, "\t%d/%d/%d: Initiator Detected Error Message Received\n", sense, asc, ascq);
253       else if ((0x49 == asc) && (0x0 == ascq))
254 	DBG (1, "\t%d/%d/%d: Invalid Message Error\n", sense, asc, ascq);
255       else if ((0x4e == asc) && (0x0 == ascq))
256 	DBG (1, "\t%d/%d/%d: Overlapped Commands Attempted\n", sense, asc, ascq);
257       else
258 	DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
259       break;
260 
261     default:
262       DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
263       break;
264     }				/* switch */
265   return ret;
266 }
267 
268 /*
269  *  wait_scanner should spin until TEST_UNIT_READY returns 0 (GOOD)
270  *  returns 0 on success,
271  *  returns -1 on error.
272  */
273 static int
wait_scanner(Coolscan_t * s)274 wait_scanner (Coolscan_t * s)
275 {
276   int ret = -1;
277   int cnt = 0;
278   DBG (10, "wait_scanner: Testing if scanner is ready\n");
279 
280   while (ret != 0)
281     {
282       ret = do_scsi_cmd (s->sfd, test_unit_ready.cmd,
283 			 test_unit_ready.size, 0, 0);
284 
285       if (ret == SANE_STATUS_DEVICE_BUSY)
286 	{
287 	  usleep (500000);	/* wait 0.5 seconds */
288 	  if (cnt++ > 40)
289 	    {			/* 20 sec. max (prescan takes up to 15 sec. */
290 	      DBG (1, "wait_scanner: scanner does NOT get ready\n");
291 	      return -1;
292 	    }
293 	}
294       else if (ret == SANE_STATUS_GOOD)
295 	{
296 	  DBG (10, "wait_scanner: scanner is ready\n");
297 	  return ret;
298 	}
299       else
300 	{
301 	  DBG (1, "wait_scanner: test unit ready failed (%s)\n",
302 	       sane_strstatus (ret));
303 	}
304     }
305   return 0;
306 }
307 
308 /* ------------------------- COOLSCAN GRAB SCANNER ----------------------------- */
309 
310 
311 /* coolscan_grab_scanner should go through the following command sequence:
312  * TEST UNIT READY
313  *     CHECK CONDITION  \
314  * REQUEST SENSE         > These should be handled automagically by
315  *     UNIT ATTENTION   /  the kernel if they happen (powerup/reset)
316  * TEST UNIT READY
317  *     GOOD
318  * RESERVE UNIT
319  *     GOOD
320  *
321  * It is then responsible for installing appropriate signal handlers
322  * to call emergency_give_scanner() if user aborts.
323  */
324 
325 static int
coolscan_grab_scanner(Coolscan_t * s)326 coolscan_grab_scanner (Coolscan_t * s)
327 {
328   int ret;
329 
330   DBG (10, "grabbing scanner\n");
331 
332   wait_scanner (s);		/* wait for scanner ready, if not print
333 				   sense and return 1 */
334   ret = do_scsi_cmd (s->sfd, reserve_unit.cmd, reserve_unit.size, NULL, 0);
335   if (ret)
336     return ret;
337 
338   DBG (10, "scanner reserved\n");
339   return 0;
340 }
341 
342 /*
343  * Convert a size in ilu to the units expected by the scanner
344  */
345 
346 static int
resDivToVal(int res_div)347 resDivToVal (int res_div)
348 {
349   if (res_div < 1 || res_div > resolution_list[0])
350     {
351       DBG (1, "Invalid resolution divisor %d \n", res_div);
352       return 2700;
353     }
354   else
355     {
356       return resolution_list[res_div];
357     }
358 }
359 
360 static int
resValToDiv(int res_val)361 resValToDiv (int res_val)
362 {
363   int res_div;
364   int max_res = resolution_list[0];
365   for (res_div = 1; res_div <= max_res; res_div++)
366     {
367       if (resolution_list[res_div] == res_val)
368 	break;
369     }
370   if (res_div > max_res)
371     {
372       DBG (1, "Invalid resolution value\n");
373       return 1;
374     }
375   else
376     {
377       return res_div;
378     }
379 }
380 /*
381  * use mode select to force a measurement divisor of 2700
382  */
383 static unsigned char mode_select[] =
384 {
385   MODE_SELECT, 0x10, 0, 0, 20, 0,
386   0, 0, 0, 8,
387   0, 0, 0, 0, 0, 0, 0, 1,
388   3, 6, 0, 0, 0xA, 0x8C, 0, 0};
389 
390 static int
select_MUD(Coolscan_t * s)391 select_MUD (Coolscan_t * s)
392 {
393   return do_scsi_cmd (s->sfd, mode_select, 26, NULL, 0);
394 }
395 
396 static int
coolscan_autofocus_LS30(Coolscan_t * s)397 coolscan_autofocus_LS30 (Coolscan_t * s)
398 {
399   int x, y;
400 
401   wait_scanner(s);
402   memcpy(s->buffer, autofocusLS30.cmd, autofocusLS30.size);
403   memcpy(s->buffer+ autofocusLS30.size, autofocuspos, 9);
404 
405   x = s->xmaxpix - (s->brx + s->tlx) / 2;
406   y = (s->bry + s->tly) / 2;
407 
408   DBG (10, "Attempting AutoFocus at x=%d, y=%d\n", x, y);
409 
410   do_scsi_cmd (s->sfd, s->buffer,
411 	       autofocusLS30.size  + 9, NULL, 0);
412   /* Trashes when used in combination with scsi-driver AM53C974.o  */
413   do_scsi_cmd (s->sfd, command_c1.cmd,
414 	       command_c1.size, NULL, 0);
415 
416   DBG (10, "\tWaiting end of Autofocus\n");
417   wait_scanner (s);
418   DBG (10, "AutoFocused.\n");
419   return 0;
420 }
421 
422 static int
coolscan_autofocus(Coolscan_t * s)423 coolscan_autofocus (Coolscan_t * s)
424 {
425   int x, y;
426 
427   if(s->LS>=2)
428     { return coolscan_autofocus_LS30(s);
429     }
430 
431   wait_scanner(s);
432   memcpy(s->buffer, autofocus.cmd, autofocus.size);
433 
434   x = s->xmaxpix - (s->brx + s->tlx) / 2;
435   y = (s->bry + s->tly) / 2;
436 
437   DBG (10, "Attempting AutoFocus at x=%d, y=%d\n", x, y);
438 
439   set_AF_XPoint (s->buffer, x);
440   set_AF_YPoint (s->buffer, y);
441 
442   set_AF_transferlength (s->buffer, 0); /* should be 8 !*/
443   do_scsi_cmd (s->sfd, s->buffer,
444 	       autofocus.size  + AF_Point_length, NULL, 0);
445 
446   sleep(5);		 	/* autofocus takes a minimum of 5 sec. */
447 
448   DBG (10, "\tWaiting end of Autofocus\n");
449   wait_scanner (s);
450   DBG (10, "AutoFocused.\n");
451   return 0;
452 }
453 
454 /*
455    static int
456    coolscan_abort_scan (Coolscan_t * s)
457    {
458    int ret;
459 
460    DBG (5, "Aborting scan...\n");
461    ret = do_scsi_cmd (s->sfd, sabort.cmd, sabort.size, NULL, 0);
462    if (ret)
463    DBG (5, "Scan Aborted\n");
464    else
465    DBG (5, "Not scanning\n");
466    return 0;
467    }
468  */
469 static int
coolscan_mode_sense(Coolscan_t * s)470 coolscan_mode_sense (Coolscan_t * s)
471 {
472   int ret, len;
473 
474   DBG (10, "Mode Sense...\n");
475   len = 12;
476   set_MS_DBD (mode_sense.cmd, 1);
477   set_MS_len (mode_sense.cmd, len);
478   ret = do_scsi_cmd (s->sfd, mode_sense.cmd, mode_sense.size,
479 		     s->buffer, len);
480 
481   if (ret == 0)
482     {
483       s->MUD = get_MS_MUD (s->buffer);
484       DBG (10, "\tMode Sensed (MUD is %d)\n", s->MUD);
485     }
486   return ret;
487 }
488 
489 static int
coolscan_object_discharge(Coolscan_t * s)490 coolscan_object_discharge (Coolscan_t * s)
491 {
492   int ret;
493 
494   DBG (10, "Trying to discharge object...\n");
495 
496   memcpy (s->buffer, object_position.cmd, object_position.size);
497   set_OP_autofeed (s->buffer, OP_Discharge);
498   ret = do_scsi_cmd (s->sfd, s->buffer,
499 		     object_position.size, NULL, 0);
500   wait_scanner (s);
501   DBG (10, "Object discharged.\n");
502   return ret;
503 }
504 
505 static int
coolscan_object_feed(Coolscan_t * s)506 coolscan_object_feed (Coolscan_t * s)
507 {
508   int ret;
509   DBG (10, "Trying to feed object...\n");
510   if (!s->asf)
511     {
512       DBG (10, "\tAutofeeder not present.\n");
513       return 0;
514     }
515   memcpy (s->buffer, object_position.cmd, object_position.size);
516   set_OP_autofeed (s->buffer, OP_Feed);
517   ret = do_scsi_cmd (s->sfd, s->buffer,
518 		     object_position.size, NULL, 0);
519   wait_scanner (s);
520   DBG (10, "Object fed.\n");
521   return ret;
522 }
523 
524 /* coolscan_give_scanner should go through the following sequence:
525  * OBJECT POSITION DISCHARGE
526  *     GOOD
527  * RELEASE UNIT
528  *     GOOD
529  */
530 static int
coolscan_give_scanner(Coolscan_t * s)531 coolscan_give_scanner (Coolscan_t * s)
532 {
533   DBG (10, "trying to release scanner ...\n");
534   coolscan_object_discharge (s);
535   wait_scanner (s);
536   do_scsi_cmd (s->sfd, release_unit.cmd, release_unit.size, NULL, 0);
537   DBG (10, "scanner released\n");
538   return 0;
539 }
540 
541 
542 static int
coolscan_set_window_param_LS20(Coolscan_t * s,int prescan)543 coolscan_set_window_param_LS20 (Coolscan_t * s, int prescan)
544 {
545   unsigned char buffer_r[max_WDB_size];
546   int ret;
547 
548   wait_scanner (s);
549   memset (buffer_r, '\0', max_WDB_size);	/* clear buffer */
550   memcpy (buffer_r, window_descriptor_block.cmd,
551 	  window_descriptor_block.size);	/* copy preset data */
552 
553   set_WD_wid (buffer_r, WD_wid_all);	/* window identifier */
554   set_WD_auto (buffer_r, s->set_auto);	/* 0 or 1: don't know what it is */
555 
556   set_WD_negative (buffer_r, s->negative);	/* Negative/positive slide */
557 
558   if (prescan)
559     {
560       set_WD_scanmode (buffer_r, WD_Prescan);
561     }
562   else
563     {
564       set_WD_scanmode (buffer_r, WD_Scan);
565 
566       /* geometry */
567       set_WD_Xres (buffer_r, resDivToVal (s->x_nres));	/* x resolution in dpi */
568       set_WD_Yres (buffer_r, resDivToVal (s->y_nres));	/* y resolution in dpi */
569 
570       /* the coolscan  uses the upper right corner as the origin of coordinates */
571       /* xmax and ymax are given in 1200 dpi */
572       set_WD_ULX (buffer_r, (s->xmaxpix - s->brx));
573       set_WD_ULY (buffer_r, s->tly);	/* upper_edge y */
574       set_WD_width (buffer_r, (s->brx - s->tlx + 1));
575       set_WD_length (buffer_r, (s->bry - s->tly + 1));
576 
577       /* BTC */
578       if (s->brightness == 128)
579 	{
580 	  set_WD_brightness (buffer_r, 0);
581 	}
582       else
583 	{
584 	  set_WD_brightness (buffer_r, s->brightness);	/* brightness */
585 	}
586 
587       if (s->contrast == 128)
588 	{
589 	  set_WD_contrast (buffer_r, 0);
590 	}
591       else
592 	{
593 	  set_WD_contrast (buffer_r, s->contrast);	/* contrast */
594 	}
595 
596       /* scanmode */
597       if (s->colormode == GREYSCALE)
598 	set_WD_composition (buffer_r, WD_comp_grey);	/* GRAY composition */
599       else
600 	set_WD_composition (buffer_r, WD_comp_rgb_full);	/* RGB composition */
601 
602       set_WD_dropoutcolor (buffer_r, s->dropoutcolor);	/* Which color to scan with when grayscale scan */
603       set_WD_transfermode (buffer_r, WD_LineSequence);
604       set_WD_gammaselection (buffer_r, s->gammaselection);	/* monitor/linear */
605 
606       set_WD_shading (buffer_r, WD_Shading_ON);		/* default for non-manufacturing */
607 
608       if (1 == s->LS)
609 	{			/* Analog gamma reserved on LS-1000 */
610 	  set_WD_analog_gamma_R (buffer_r, 0);
611 	  set_WD_analog_gamma_G (buffer_r, 0);
612 	  set_WD_analog_gamma_R (buffer_r, 0);
613 	}
614       else
615 	{
616 	  /* Quote spec: "It is recommended that analog gamma bits 5, 4 and 3 be
617 	   * set to 1 (OFF) when the object type of byte 48 is positive and the
618 	   * gamma specification of byte 51 is linear, and to 0 (ON) in all
619 	   * other cases." */
620 	  /*
621 	  int foo;
622 	  if ((buffer_r[48] == WD_Positive) && (buffer_r[51] == WD_Linear))
623 	    foo = WD_Analog_Gamma_OFF;
624 	  else
625 	    foo = WD_Analog_Gamma_ON;
626 	  set_WD_analog_gamma_R (buffer_r, foo);
627 	  set_WD_analog_gamma_G (buffer_r, foo);
628 	  set_WD_analog_gamma_B (buffer_r, foo);
629 	  */
630 	  set_WD_analog_gamma_R (buffer_r, s->analog_gamma_r);
631 	  set_WD_analog_gamma_G (buffer_r, s->analog_gamma_g);
632 	  set_WD_analog_gamma_B (buffer_r, s->analog_gamma_b);
633 	  if (s->gamma_bind)
634 	    {
635 	      set_WD_LUT_R (buffer_r, 1);
636 	      set_WD_LUT_G (buffer_r, 1);
637 	      set_WD_LUT_B (buffer_r, 1);
638 	    }
639 	  else
640 	    {
641 	      set_WD_LUT_R (buffer_r, 1);
642 	      set_WD_LUT_G (buffer_r, 2);
643 	      set_WD_LUT_B (buffer_r, 3);
644 	    }
645 	}
646       set_WD_averaging (buffer_r, s->averaging);
647 
648       set_WD_brightness_R (buffer_r, s->brightness_R);
649       set_WD_brightness_G (buffer_r, s->brightness_G);
650       set_WD_brightness_B (buffer_r, s->brightness_B);
651 
652       set_WD_contrast_R (buffer_r, s->contrast_R);
653       set_WD_contrast_G (buffer_r, s->contrast_G);
654       set_WD_contrast_B (buffer_r, s->contrast_B);
655 
656       set_WD_exposure_R (buffer_r, s->exposure_R);
657       set_WD_exposure_G (buffer_r, s->exposure_G);
658       set_WD_exposure_B (buffer_r, s->exposure_B);
659       set_WD_shift_R (buffer_r, s->shift_R);
660       set_WD_shift_G (buffer_r, s->shift_G);
661       set_WD_shift_B (buffer_r, s->shift_B);
662 
663 
664       /* FIXME: LUT-[RGB] */
665       /* FIXME: stop on/off */
666     }
667 
668   DBG (10, "\tx_nres=%d, y_nres=%d, upper left-x=%d, upper left-y=%d\n",
669        s->x_nres, s->y_nres, s->tlx, s->tly);
670   DBG (10, "\twindow width=%d, MUD=%d, brx=%d\n",
671        s->brx - s->tlx, s->MUD, s->brx);
672   DBG (10, "\tcolormode=%d, bits per pixel=%d\n",
673        s->colormode, s->bits_per_color);
674   DBG (10, "\tnegative=%d, dropoutcolor=%d, preview=%d, transfermode=%d, gammasel=%d\n",
675        s->negative, s->dropoutcolor, s->preview, s->transfermode,
676        s->gammaselection);
677 
678   /* prepare SCSI-BUFFER */
679   memcpy (s->buffer, set_window.cmd, set_window.size);	/* SET-WINDOW cmd */
680   memcpy ((s->buffer + set_window.size),	/* add WPDB */
681 	  window_parameter_data_block.cmd,
682 	  window_parameter_data_block.size);
683   set_WPDB_wdblen ((s->buffer + set_window.size), used_WDB_size);	/* set WD_len */
684   memcpy (s->buffer + set_window.size + window_parameter_data_block.size,
685 	  buffer_r, window_descriptor_block.size);
686 
687   hexdump (15, "Window set", buffer_r, s->wdb_len);
688 
689   set_SW_xferlen (s->buffer, (window_parameter_data_block.size +
690 			      window_descriptor_block.size));
691 
692   ret = do_scsi_cmd (s->sfd, s->buffer, set_window.size +
693 		     window_parameter_data_block.size +
694 		     window_descriptor_block.size,
695 		     NULL, 0);
696   DBG (10, "window set.\n");
697   return ret;
698 }
699 
700 static int
coolscan_set_window_param_LS30(Coolscan_t * s,int wid,int prescan)701 coolscan_set_window_param_LS30 (Coolscan_t * s, int wid, int prescan)
702 {
703   unsigned char buffer_r[max_WDB_size];
704   int ret;
705 
706   wait_scanner (s);
707   memset (buffer_r, '\0', max_WDB_size);	/* clear buffer */
708   memcpy (buffer_r, window_descriptor_block_LS30.cmd,
709 	  window_descriptor_block_LS30.size);	/* copy preset data */
710 
711   set_WD_wid (buffer_r, wid);          	/* window identifier */
712   set_WD_auto (buffer_r, s->set_auto);	/* 0 or 1: don't know what it is */
713 
714   /* geometry */
715   set_WD_Xres (buffer_r, resDivToVal (s->x_nres));	/* x resolution in dpi */
716   set_WD_Yres (buffer_r, resDivToVal (s->y_nres));	/* y resolution in dpi */
717 
718   if (prescan)
719     {
720       set_WD_scanmode_LS30 (buffer_r, WD_Prescan);
721       set_WD_Xres (buffer_r, resDivToVal (1));	/* x res. in dpi */
722       set_WD_Yres (buffer_r, resDivToVal (1));	/* y res. in dpi */
723       buffer_r[0x29]=0x81;
724       buffer_r[0x2a]=0x04;
725       buffer_r[0x2b]=0x02;
726       buffer_r[0x2c]=0x01;
727       buffer_r[0x2d]=0xff;
728       buffer_r[0x30]=0x00;
729       buffer_r[0x31]=0x00;
730       buffer_r[0x32]=0x00;
731       buffer_r[0x33]=0x00;
732       set_WD_width (buffer_r,(2592));
733       set_WD_length (buffer_r,(3894));
734     }
735   else
736     {
737       set_WD_scanmode_LS30 (buffer_r, WD_Scan);
738 
739       /* the coolscan LS-30 uses the upper left corner
740 	 as the origin of coordinates */
741       /* xmax and ymax are given in 1200 dpi */
742       set_WD_ULX (buffer_r, s->tlx);
743       set_WD_ULY (buffer_r, s->tly);	/* upper_edge y */
744       set_WD_width (buffer_r, (s->brx - s->tlx+1));
745       set_WD_length (buffer_r, (s->bry - s->tly+1));
746 
747       /* BTC */
748       if (s->brightness == 128)
749 	{
750 	  buffer_r[0x32]=0x00;
751 	}
752       else
753 	{
754 	  buffer_r[0x32]=s->brightness;	/* brightness */
755 	}
756 
757       if (s->contrast == 128)
758 	{
759 	  buffer_r[0x33]=0x00;
760 	}
761       else
762 	{
763 	  buffer_r[0x33]=s->contrast;	/* contrast */
764 	}
765 
766       /* scanmode */
767       if (s->colormode == GREYSCALE)
768 	set_WD_composition (buffer_r, WD_comp_grey);	/* GRAY composition */
769       else
770 	set_WD_composition (buffer_r, WD_comp_rgb_full);	/* RGB composition */
771 
772       set_WD_composition (buffer_r, WD_comp_rgb_full);  /* always RGB composition */
773 
774       /* Bits per pixel */
775       set_WD_bitsperpixel(buffer_r, s->bits_per_color);
776 
777       buffer_r[0x29]=0x81;
778       buffer_r[0x2a]=0x01;
779       buffer_r[0x2b]=0x02;
780       buffer_r[0x2c]=0x01;
781       buffer_r[0x2d]=0xff;
782       buffer_r[0x30]=0x00;
783 
784     }
785     set_WD_negative_LS30(buffer_r, s->negative);	/* Negative/positive slide */
786 
787     switch(wid)
788     { case 1:  set_gain_LS30(buffer_r,(s->exposure_R*s->pretv_r)/50);
789                  break;
790       case 2:  set_gain_LS30(buffer_r,(s->exposure_G*s->pretv_g)/50);
791                  break;
792       case 3:  set_gain_LS30(buffer_r,(s->exposure_B*s->pretv_b)/50);
793                  break;
794     }
795 
796   DBG (10, "\texpo_r=%d, expo_g=%d, expob=%d\n",
797        s->exposure_R, s->exposure_G, s->exposure_B);
798   DBG (10, "\tpre_r=%d, pre_g=%d, preb=%d\n",
799        s->pretv_r, s->pretv_g, s->pretv_b);
800   DBG (10, "\tx_nres=%d, y_nres=%d, upper left-x=%d, upper left-y=%d\n",
801        s->x_nres, s->y_nres, s->tlx, s->tly);
802   DBG (10, "\twindow width=%d, MUD=%d, brx=%d\n",
803        s->brx - s->tlx, s->MUD, s->brx);
804   DBG (10, "\tcolormode=%d, bits per pixel=%d\n",
805        s->colormode, s->bits_per_color);
806   DBG (10, "\tnegative=%d, dropoutcolor=%d, preview=%d, transfermode=%d, gammasel=%d\n",
807        s->negative, s->dropoutcolor, s->preview, s->transfermode,
808        s->gammaselection);
809 
810   /* prepare SCSI-BUFFER */
811   memcpy (s->buffer, set_window.cmd, set_window.size);	/* SET-WINDOW cmd */
812   memcpy ((s->buffer + set_window.size),	/* add WPDB */
813 	  window_parameter_data_block.cmd,
814 	  window_parameter_data_block.size);
815   set_WPDB_wdblen ((s->buffer + set_window.size), used_WDB_size_LS30);	/* set WD_len */
816   memcpy (s->buffer + set_window.size + window_parameter_data_block.size,
817 	  buffer_r, window_descriptor_block_LS30.size);
818 
819   hexdump (15, "Window set", buffer_r, s->wdb_len);
820 
821   set_SW_xferlen (s->buffer, (window_parameter_data_block.size +
822 			      window_descriptor_block_LS30.size));
823 
824   ret = do_scsi_cmd (s->sfd, s->buffer, set_window.size +
825 		     window_parameter_data_block.size +
826 		     window_descriptor_block_LS30.size,
827 		     NULL, 0);
828   DBG (10, "window set.\n");
829   return ret;
830 }
831 
832 static int
coolscan_set_window_param(Coolscan_t * s,int prescan)833 coolscan_set_window_param (Coolscan_t * s, int prescan)
834 {
835   int ret;
836   ret=0;
837   DBG (10, "set_window_param\n");
838 
839   if(s->LS<2)                   /* distinguish between old and new scanners */
840   { ret=coolscan_set_window_param_LS20 (s,prescan);
841   }
842   else
843   {  do_scsi_cmd (s->sfd,commande1.cmd,commande1.size,s->buffer,0x0d);
844      wait_scanner (s);
845      wait_scanner (s);
846      coolscan_set_window_param_LS30(s,1,prescan);
847      ret=coolscan_set_window_param_LS30(s,2,prescan);
848      ret=coolscan_set_window_param_LS30(s,3,prescan);
849      if(s->colormode&0x08)
850      { ret=coolscan_set_window_param_LS30(s,9,prescan);
851      }
852   }
853   return ret;
854 }
855 
856 
857 /*
858  * The only purpose of get_window is debugging. None of the return parameters
859  * is currently used.
860  */
861 static int
coolscan_get_window_param_LS30(Coolscan_t * s,int wid,int prescanok)862 coolscan_get_window_param_LS30 (Coolscan_t * s, int wid,int prescanok)
863 {
864   int translen;
865   unsigned char *buf;
866 
867   DBG (10, "GET_WINDOW_PARAM\n");
868   /*  wait_scanner (s); */
869 
870   translen = window_parameter_data_block.size + window_descriptor_block_LS30.size;
871 
872   /* prepare SCSI-BUFFER */
873   memset (s->buffer, '\0', max_WDB_size);	/* clear buffer */
874 
875   set_SW_xferlen (get_window.cmd, translen);	/* Transfer length */
876   get_window.cmd[5]= wid;                     	/* window identifier */
877 
878   hexdump (15, "Get window cmd", get_window.cmd, get_window.size);
879   do_scsi_cmd (s->sfd, get_window.cmd, get_window.size,
880 		     s->buffer, translen);
881 
882   buf = s->buffer + window_parameter_data_block.size;
883   hexdump (10, "Window get", buf, 117);
884 
885   s->brightness = buf[0x32];	/* brightness */
886   s->contrast = buf[0x33];	/* contrast */
887   DBG (10, "\tbrightness=%d, contrast=%d\n", s->brightness, s->contrast);
888 
889   /* Useful? */
890   s->bits_per_color = get_WD_bitsperpixel (buf);	/* bits/pixel (8) */
891 
892   DBG (10, "\tcolormode=%d, bits per pixel=%d\n",
893        s->colormode, s->bits_per_color);
894 
895   if(prescanok)
896   { switch(wid)
897     { case 1: s->pretv_r = get_gain_LS30(buf);
898               break;
899       case 2: s->pretv_g = get_gain_LS30(buf);
900               break;
901       case 3: s->pretv_b = get_gain_LS30(buf);
902             break;
903     }
904   }
905 
906   /* Should this one be set at all, here? */
907   s->transfermode = get_WD_transfermode (buf);
908 
909   s->gammaselection = get_WD_gammaselection (buf);	/* monitor/linear */
910   DBG (10, "\tpre_r=%d, pre_g=%d, preb=%d\n",
911        s->pretv_r, s->pretv_g, s->pretv_b);
912 
913   DBG (5, "\tnegative=%d, dropoutcolor=%d, preview=%d, transfermode=%d, gammasel=%d\n",
914        s->negative, s->dropoutcolor, s->preview, s->transfermode,
915        s->gammaselection);
916 
917   DBG (10, "get_window_param - return\n");
918   return 0;
919 }
920 
921 /*
922  * The only purpose of get_window is debugging. None of the return parameters
923  * is currently used.
924  */
925 static int
coolscan_get_window_param_LS20(Coolscan_t * s)926 coolscan_get_window_param_LS20 (Coolscan_t * s)
927 {
928   int translen;
929   unsigned char *buf;
930 
931   DBG (10, "GET_WINDOW_PARAM\n");
932   wait_scanner (s);
933 
934   translen = window_parameter_data_block.size + window_descriptor_block.size;
935 
936   /* prepare SCSI-BUFFER */
937   memset (s->buffer, '\0', max_WDB_size);	/* clear buffer */
938 
939   set_SW_xferlen (get_window.cmd, translen);	/* Transfer length */
940 
941   hexdump (15, "Get window cmd", get_window.cmd, get_window.size);
942   do_scsi_cmd (s->sfd, get_window.cmd, get_window.size,
943 		     s->buffer, translen);
944 
945   buf = s->buffer + window_parameter_data_block.size;
946   hexdump (10, "Window get", buf, 117);
947 
948   /* BTC */
949   s->brightness = get_WD_brightness (buf);	/* brightness */
950   s->contrast = get_WD_contrast (buf);	/* contrast */
951   DBG (10, "\tbrightness=%d, contrast=%d\n", s->brightness, s->contrast);
952 
953   if (WD_comp_gray == get_WD_composition (buf))
954     s->colormode = GREYSCALE;
955   else
956     s->colormode = RGB;
957 
958   /* Useful? */
959   s->bits_per_color = get_WD_bitsperpixel (buf);	/* bits/pixel (8) */
960 
961   DBG (10, "\tcolormode=%d, bits per pixel=%d\n",
962        s->colormode, s->bits_per_color);
963 
964 
965   s->dropoutcolor = get_WD_dropoutcolor (buf);	/* Which color to scan with when grayscale scan */
966 
967   /* Should this one be set at all, here? */
968   s->transfermode = get_WD_transfermode (buf);
969 
970   s->gammaselection = get_WD_gammaselection (buf);	/* monitor/linear */
971 
972   DBG (5, "\tnegative=%d, dropoutcolor=%d, preview=%d, transfermode=%d, gammasel=%d\n",
973        s->negative, s->dropoutcolor, s->preview, s->transfermode,
974        s->gammaselection);
975 
976   /* Should this one be set at all? */
977   s->shading = get_WD_shading (buf);
978   s->averaging = get_WD_averaging (buf);
979   DBG (10, "get_window_param - return\n");
980   return 0;
981 }
982 
983 /*
984  * The only purpose of get_window is debugging. None of the return parameters
985  * is currently used.
986  */
987 static int
coolscan_get_window_param(Coolscan_t * s,int prescanok)988 coolscan_get_window_param (Coolscan_t * s, int prescanok)
989 {
990   int ret;
991   DBG (10, "get_window_param\n");
992 
993   ret=0;
994   if(s->LS<2)                   /* distinguish between old and new scanners */
995   { ret=coolscan_get_window_param_LS20 (s);
996   }
997   else
998   {
999      ret=coolscan_get_window_param_LS30(s,1,prescanok);
1000      ret=coolscan_get_window_param_LS30(s,2,prescanok);
1001      ret=coolscan_get_window_param_LS30(s,3,prescanok);
1002      if(s->colormode&0x08)
1003      { ret=coolscan_get_window_param_LS30(s,9,prescanok);
1004      }
1005   }
1006   return ret;
1007 }
1008 
1009 static int
coolscan_start_scanLS30(Coolscan_t * s)1010 coolscan_start_scanLS30 (Coolscan_t * s)
1011 { int channels;
1012   DBG (10, "starting scan\n");
1013 
1014   channels=1;
1015   memcpy (s->buffer, scan.cmd, scan.size);
1016   switch(s->colormode)
1017     {  case RGB:
1018        case GREYSCALE:
1019 	       channels=s->buffer[4]=0x03; /* window 1 */
1020                s->buffer[6]=0x01; /* window 1 */
1021 	       s->buffer[7]=0x02; /* window 2 */
1022 	       s->buffer[8]=0x03; /* window 3 */
1023 
1024               break;
1025        case RGBI:
1026 	       channels=s->buffer[4]=0x04; /* window 1 */
1027                s->buffer[6]=0x01; /* window 1 */
1028 	       s->buffer[7]=0x02; /* window 2 */
1029 	       s->buffer[8]=0x03; /* window 3 */
1030 	       s->buffer[9]=0x09; /* window 3 */
1031               break;
1032        case IRED:
1033 	       channels=s->buffer[4]=0x01; /* window 1 */
1034 	       s->buffer[8]=0x09; /* window 3 */
1035               break;
1036     }
1037 
1038   return do_scsi_cmd (s->sfd, s->buffer, scan.size+channels, NULL, 0);
1039 }
1040 
1041 static int
coolscan_start_scan(Coolscan_t * s)1042 coolscan_start_scan (Coolscan_t * s)
1043 {
1044   DBG (10, "starting scan\n");
1045   if(s->LS>=2)
1046     { return coolscan_start_scanLS30(s);
1047     }
1048   return do_scsi_cmd (s->sfd, scan.cmd, scan.size, NULL, 0);
1049 }
1050 
1051 
1052 static int
prescan(Coolscan_t * s)1053 prescan (Coolscan_t * s)
1054 {
1055   int ret;
1056 
1057   DBG (10, "Starting prescan...\n");
1058   if(s->LS<2)
1059   {  coolscan_set_window_param (s, 1);
1060   }
1061   else
1062   {
1063      do_scsi_cmd (s->sfd,commande1.cmd,commande1.size,s->buffer,0x0d);
1064      wait_scanner (s);
1065      wait_scanner (s);
1066      coolscan_set_window_param_LS30 (s,1,1);
1067      coolscan_set_window_param_LS30 (s,2,1);
1068      coolscan_set_window_param_LS30 (s,3,1);
1069 
1070   }
1071   ret = coolscan_start_scan(s);
1072 
1073   sleep(8);			/* prescan takes a minimum of 10 sec. */
1074   wait_scanner (s);
1075   DBG (10, "Prescan done\n");
1076   return ret;
1077 }
1078 
1079 static SANE_Status
do_prescan_now(Coolscan_t * scanner)1080 do_prescan_now (Coolscan_t * scanner)
1081 {
1082 
1083   DBG (10, "do_prescan_now \n");
1084   if (scanner->scanning == SANE_TRUE)
1085     return SANE_STATUS_DEVICE_BUSY;
1086 
1087   if (scanner->sfd < 0)
1088     {				/* first call */
1089       if (sanei_scsi_open (scanner->sane.name,
1090 			   &(scanner->sfd),
1091 			   sense_handler, 0) != SANE_STATUS_GOOD)
1092 	{
1093 	  DBG (1, "do_prescan_now: open of %s failed:\n",
1094 	       scanner->sane.name);
1095 	  return SANE_STATUS_INVAL;
1096 	}
1097     }
1098   scanner->scanning = SANE_TRUE;
1099 
1100 
1101   if (coolscan_check_values (scanner) != 0)
1102     {				/* Verify values */
1103       DBG (1, "ERROR: invalid scan-values\n");
1104       scanner->scanning = SANE_FALSE;
1105       coolscan_give_scanner (scanner);
1106       sanei_scsi_close (scanner->sfd);
1107       scanner->sfd = -1;
1108       return SANE_STATUS_INVAL;
1109     }
1110 
1111   if (coolscan_grab_scanner (scanner))
1112     {
1113       sanei_scsi_close (scanner->sfd);
1114       scanner->sfd = -1;
1115       DBG (5, "WARNING: unable to reserve scanner: device busy\n");
1116       scanner->scanning = SANE_FALSE;
1117       return SANE_STATUS_DEVICE_BUSY;
1118     }
1119 
1120   prescan (scanner);
1121   if(scanner->LS<2)
1122     {	get_internal_info(scanner);
1123     }
1124   coolscan_get_window_param (scanner,1);
1125   scanner->scanning = SANE_FALSE;
1126   coolscan_give_scanner (scanner);
1127   return SANE_STATUS_GOOD;
1128 }
1129 
1130 
1131 static int
send_one_LUT(Coolscan_t * s,SANE_Word * LUT,int reg)1132 send_one_LUT (Coolscan_t * s, SANE_Word * LUT, int reg)
1133 {
1134   int i;
1135   short lutval;
1136   short bytesperval;
1137   unsigned char *gamma, *gamma_p;
1138   unsigned short *gamma_s;
1139 
1140   DBG (10, "send LUT\n");
1141 
1142   if(s->LS<2)
1143   { set_S_datatype_code (send.cmd, R_user_reg_gamma);
1144     bytesperval=1;
1145   }
1146   else
1147   {
1148     send.cmd[0x02]=3;
1149     send.cmd[0x05]=1;
1150     bytesperval=2;
1151   }
1152 
1153   set_S_xfer_length (send.cmd, s->lutlength*bytesperval);
1154   set_S_datatype_qual_upper (send.cmd, reg);
1155 
1156   gamma = alloca (send.size + s->lutlength*2);
1157   memcpy (gamma, send.cmd, send.size);
1158   if(s->LS<2)
1159   { gamma_p = &gamma[send.size];
1160     for (i = 0; i < s->lutlength; i++)
1161     {
1162       if (LUT[i] > 255)
1163 	LUT[i] = 255;		/* broken gtk */
1164       *gamma_p++ = (unsigned char) LUT[i];
1165     }
1166   }
1167   else if(s->LS==2)
1168   { gamma_s = (unsigned short*)( &gamma[send.size]);
1169     for (i = 0; i < s->lutlength; i++)
1170     {
1171        if(s->negative)
1172        {
1173          lutval=(unsigned short)(LUT[(s->lutlength-i)]);
1174        }
1175        else
1176        {
1177 	 lutval=(unsigned short)(LUT[i]);
1178        }
1179        if (LUT[i] >= s->max_lut_val)
1180        LUT[i] = s->max_lut_val-1;	          	/* broken gtk */
1181        if(s->low_byte_first)                                /* if on little endian machine: */
1182        {
1183          lutval=((lutval&0x00ff)<<8)+((lutval&0xff00)>>8); /* inverse byteorder */
1184        }
1185        *gamma_s++ = lutval;
1186     }
1187   }
1188   else if(s->LS==3)
1189   { gamma_s = (unsigned short*)( &gamma[send.size]);
1190     for (i = 0; i < s->lutlength; i++)
1191     {
1192        if(s->negative)
1193        {
1194          lutval=(unsigned short)(LUT[s->lutlength-i]);
1195        }
1196        else
1197        {
1198 	 lutval=(unsigned short)(LUT[i]);
1199        }
1200        if (LUT[i] >= s->max_lut_val)
1201        LUT[i] = s->max_lut_val-1;	          	    /* broken gtk */
1202        if(s->low_byte_first)                                /* if on little endian machine: */
1203        {  lutval=((lutval&0x00ff)<<8)+((lutval&0xff00)>>8); /* inverse byteorder */
1204        }
1205        *gamma_s++ = lutval;
1206     }
1207   }
1208   return do_scsi_cmd (s->sfd, gamma, send.size + s->lutlength*bytesperval, NULL, 0);
1209 }
1210 
1211 
1212 static int
send_LUT(Coolscan_t * s)1213 send_LUT (Coolscan_t * s)
1214 {
1215   wait_scanner (s);
1216   if (s->gamma_bind)
1217     {
1218       send_one_LUT (s, s->gamma, S_DQ_Reg1);
1219       if(s->LS>=2)
1220 	{      send_one_LUT (s, s->gamma, S_DQ_Reg2);
1221 	       send_one_LUT (s, s->gamma, S_DQ_Reg3);
1222                if(s->colormode&0x08)
1223 	       { send_one_LUT (s, s->gamma, S_DQ_Reg9);
1224 	       }
1225 
1226 	}
1227     }
1228   else
1229     {
1230       send_one_LUT (s, s->gamma_r, S_DQ_Reg1);
1231       send_one_LUT (s, s->gamma_g, S_DQ_Reg2);
1232       send_one_LUT (s, s->gamma_b, S_DQ_Reg3);
1233       if(s->colormode&0x08)
1234       { send_one_LUT (s, s->gamma_r, S_DQ_Reg9);
1235       }
1236     }
1237   return 0;
1238 }
1239 
1240 
1241 static int
coolscan_read_data_block(Coolscan_t * s,unsigned int datatype,unsigned int length)1242 coolscan_read_data_block (Coolscan_t * s, unsigned int datatype, unsigned int length)
1243 {
1244   int r;
1245 
1246   DBG (10, "read_data_block (type= %x length = %d)\n",datatype,length);
1247   /*wait_scanner(s); */
1248 
1249   set_R_datatype_code (sread.cmd, datatype);
1250   sread.cmd[4]=00;
1251   sread.cmd[5]=00;
1252   set_R_xfer_length (sread.cmd, length);
1253 
1254   r = do_scsi_cmd (s->sfd, sread.cmd, sread.size, s->buffer, length);
1255   return ((r != 0) ? -1 : (int) length);
1256 }
1257 
1258 
1259 static void
coolscan_do_inquiry(Coolscan_t * s)1260 coolscan_do_inquiry (Coolscan_t * s)
1261 {
1262   int size;
1263 
1264   DBG (10, "do_inquiry\n");
1265   memset (s->buffer, '\0', 256);	/* clear buffer */
1266   size = 36;			/* Hardcoded, and as specified by Nikon */
1267   /* then get inquiry with actual size */
1268   set_inquiry_return_size (inquiry.cmd, size);
1269   do_scsi_cmd (s->sfd, inquiry.cmd, inquiry.size, s->buffer, size);
1270 }
1271 
1272 static int
coolscan_identify_scanner(Coolscan_t * s)1273 coolscan_identify_scanner (Coolscan_t * s)
1274 {
1275   unsigned char vendor[9];
1276   unsigned char product[0x11];
1277   unsigned char version[5];
1278   unsigned char *pp;
1279   int i;
1280 
1281   vendor[8] = product[0x10] = version[4] = 0;
1282   DBG (10, "identify_scanner\n");
1283   coolscan_do_inquiry (s);	/* get inquiry */
1284   if (get_inquiry_periph_devtype (s->buffer) != IN_periph_devtype_scanner)
1285     {
1286       DBG (5, "identify_scanner: not a scanner\n");
1287       return 1;
1288     }				/* no, continue searching */
1289 
1290   coolscan_get_inquiry_values (s);
1291 
1292   get_inquiry_vendor ((char *)s->buffer, (char *)vendor);
1293   get_inquiry_product ((char *)s->buffer, (char *)product);
1294   get_inquiry_version ((char *)s->buffer, (char *)version);
1295 
1296   if (strncmp ("Nikon   ", (char *)vendor, 8))
1297     {
1298       DBG (5, "identify_scanner: \"%s\" isn't a Nikon product\n", vendor);
1299       return 1;
1300     }				/* Not a Nikon product */
1301 
1302   pp = &vendor[8];
1303   vendor[8] = ' ';
1304   while (*pp == ' ')
1305     {
1306       *pp-- = '\0';
1307     }
1308 
1309   pp = &product[0x10];
1310   product[0x10] = ' ';
1311   while (*(pp - 1) == ' ')
1312     {
1313       *pp-- = '\0';
1314     }				/* leave one blank at the end! */
1315 
1316   pp = &version[4];
1317   version[4] = ' ';
1318   while (*pp == ' ')
1319     {
1320       *pp-- = '\0';
1321     }
1322 
1323   DBG (10, "Found Nikon scanner %sversion %s on device %s\n",
1324        product, version, s->devicename);
1325 
1326   /* look for scanners that do not give all inquiry-informations */
1327   /* and if possible use driver-known inquiry-data  */
1328   if (get_inquiry_additional_length (s->buffer) >= 0x1f)
1329     {
1330       /* Now identify full supported scanners */
1331       for (i = 0; i < known_scanners; i++)
1332 	{
1333 	  if (!strncmp ((char *)product, scanner_str[i], strlen (scanner_str[i])))
1334 	    {
1335 	      s->LS = i;
1336 	      return 0;
1337 	    }
1338 	}
1339       if (s->cont)
1340 	return 0;
1341       else
1342 	return 1;
1343     }
1344   else
1345     return 1;
1346 }
1347 
1348 static int
pixels_per_line(Coolscan_t * s)1349 pixels_per_line (Coolscan_t * s)
1350 {
1351   int pic_dot;
1352   if(s->LS<2)
1353   {  pic_dot = (s->brx - s->tlx + s->x_nres) / s->x_nres;
1354   }
1355   else
1356   { pic_dot = (s->brx - s->tlx + 1) / s->x_nres;
1357   }
1358   DBG (10, "pic_dot=%d\n", pic_dot);
1359   return pic_dot;
1360 }
1361 
1362 static int
lines_per_scan(Coolscan_t * s)1363 lines_per_scan (Coolscan_t * s)
1364 {
1365   int pic_line;
1366   if(s->LS<2)
1367   { pic_line = (s->bry - s->tly + s->y_nres) / s->y_nres;
1368   }
1369   else
1370   { pic_line = (( s->bry - s->tly + 1.0 )  / s->y_nres);
1371   }
1372   DBG (10, "pic_line=%d\n", pic_line);
1373   return pic_line;
1374 }
1375 
1376 static int
scan_bytes_per_line(Coolscan_t * s)1377 scan_bytes_per_line (Coolscan_t * s)
1378 { int bpl;
1379   switch(s->colormode)
1380     {  case RGB:
1381        case GREYSCALE:
1382               bpl=pixels_per_line (s) * 3;
1383               if(s->bits_per_color>8) bpl=bpl*2;
1384               return bpl;
1385               break;
1386        case RGBI:
1387        case IRED:
1388               bpl=pixels_per_line (s) * 4;
1389               if(s->bits_per_color>8) bpl=bpl*2;
1390               return bpl;
1391               break;
1392     }
1393     return 0;
1394 }
1395 
1396 static int
write_bytes_per_line(Coolscan_t * s)1397 write_bytes_per_line (Coolscan_t * s)
1398 { int bpl;
1399   switch(s->colormode)
1400     {  case RGB:
1401               bpl=pixels_per_line (s) * 3;
1402               if(s->bits_per_color>8) bpl=bpl*2;
1403               return bpl;
1404               break;
1405        case RGBI:
1406               bpl=pixels_per_line (s) * 4;
1407               if(s->bits_per_color>8) bpl=bpl*2;
1408               return bpl;
1409               break;
1410        case IRED:
1411        case GREYSCALE:
1412               bpl= pixels_per_line (s) ;
1413               if(s->bits_per_color>8) bpl=bpl*2;
1414               return bpl;
1415               break;
1416     }
1417     return 0;
1418 }
1419 
1420 
1421 static void
coolscan_trim_rowbufsize(Coolscan_t * s)1422 coolscan_trim_rowbufsize (Coolscan_t * s)
1423 {
1424   unsigned int row_len;
1425   row_len = scan_bytes_per_line (s);
1426   s->row_bufsize = (s->row_bufsize < row_len) ? s->row_bufsize
1427     : s->row_bufsize - (s->row_bufsize % row_len);
1428   DBG (10, "trim_bufsize to %d\n", s->row_bufsize);
1429 }
1430 
1431 static int
coolscan_check_values(Coolscan_t * s)1432 coolscan_check_values (Coolscan_t * s)
1433 {
1434   DBG (10, "check_values\n");
1435   /* -------------------------- asf --------------------------------- */
1436   if (s->asf != 0)
1437     {
1438       if (s->autofeeder == 0)
1439 	{
1440 	  DBG (1, "ERROR: ASF-MODE NOT SUPPORTED BY SCANNER, ABORTING\n");
1441 	  return (1);
1442 	}
1443     }
1444 
1445   return (0);
1446 }
1447 
1448 /* test_little_endian */
1449 
1450 static SANE_Bool
coolscan_test_little_endian(void)1451 coolscan_test_little_endian(void)
1452 {
1453   SANE_Int testvalue = 255;
1454   unsigned char *firstbyte = (unsigned char *) &testvalue;
1455 
1456   if (*firstbyte == 255)
1457   { return SANE_TRUE;
1458   }
1459   return SANE_FALSE;
1460 }
1461 
1462 static int
get_inquiery_part_LS30(Coolscan_t * s,unsigned char part)1463 get_inquiery_part_LS30 (Coolscan_t * s, unsigned char part)
1464 {
1465   int size;
1466 
1467   /* Get length of response */
1468   inquiry.cmd[1]=0x01;
1469   inquiry.cmd[2]=part;
1470   size=4;
1471   set_inquiry_return_size (inquiry.cmd, size);
1472   do_scsi_cmd (s->sfd, inquiry.cmd, inquiry.size,
1473                s->buffer, size);
1474   size=get_inquiry_length(s->buffer);
1475   size+=4;
1476   /* then get inquiry with actual size */
1477   set_inquiry_return_size (inquiry.cmd, size);
1478   do_scsi_cmd (s->sfd, inquiry.cmd, inquiry.size,
1479                s->buffer, size);
1480   return size;
1481 }
1482 
1483 static int
coolscan_read_var_data_block(Coolscan_t * s,int datatype)1484 coolscan_read_var_data_block (Coolscan_t * s,int datatype)
1485 {
1486   int r;
1487   int size;
1488 
1489   DBG (10, "read_data_block (type= %x)\n",datatype);
1490   /*wait_scanner(s); */
1491 
1492   sread.cmd[2]=datatype;
1493   sread.cmd[4]=00;
1494   sread.cmd[5]=03;
1495   size=6;
1496   set_R_xfer_length (sread.cmd, size);
1497   r = do_scsi_cmd (s->sfd, sread.cmd, sread.size,
1498 		     s->buffer, size);
1499   size=s->buffer[5];
1500   set_R_xfer_length (sread.cmd, size);
1501   r = do_scsi_cmd (s->sfd, sread.cmd, sread.size,
1502 		     s->buffer, size);
1503   return ((r != 0) ? -1 : size);
1504 }
1505 
1506 static int
get_inquiery_LS30(Coolscan_t * s)1507 get_inquiery_LS30 (Coolscan_t * s)
1508 {
1509   unsigned char part;
1510   unsigned char parts[5];
1511   int i;
1512 
1513   /* Get vector of inquiery parts */
1514   get_inquiery_part_LS30(s, (unsigned char) 0);
1515   /* Get the parts of inquiery */
1516   for(i=0;i<5;i++)
1517   { parts[i]=((unsigned char *)s->buffer)[4+11+i];
1518   }
1519   for(i=0;i<5;i++)
1520   { part=parts[i];
1521     get_inquiery_part_LS30 (s, part);
1522     switch(part)
1523     {  case 0x0c1:/* max size and resolution */
1524                     s->adbits = 8;
1525                     s->outputbits = 8;
1526 		    s->maxres = getnbyte(s->buffer+0x12,2)-1;
1527 		    s->xmaxpix = getnbyte(s->buffer+0x53,2)-1;
1528 		    s->ymaxpix = getnbyte(s->buffer+0x3c,2)-1;
1529                   break;
1530        case 0x0d1:
1531                   break;
1532        case 0x0e1:
1533                   break;
1534        case 0x0f0:
1535                   break;
1536        case 0x0f8:
1537                   break;
1538     }
1539   }
1540 
1541   /* get windows */
1542   coolscan_get_window_param_LS30 (s,0,0);
1543    s->xmax = get_WD_width(s->buffer);
1544    s->ymax = get_WD_length(s->buffer);
1545   coolscan_get_window_param_LS30 (s,1,0);
1546   coolscan_get_window_param_LS30 (s,2,0);
1547   coolscan_get_window_param_LS30 (s,3,0);
1548   coolscan_get_window_param_LS30 (s,4,0);
1549   coolscan_get_window_param_LS30 (s,9,0);
1550 
1551   s->analoggamma = 0;
1552   return 1;
1553 }
1554 
1555 static int
get_feeder_type_LS30(Coolscan_t * s)1556 get_feeder_type_LS30 (Coolscan_t * s)
1557 {
1558   int size;
1559   unsigned char *ptr;
1560   int ima;
1561 
1562   /* find out about Film-strip-feeder or Mount-Feeder */
1563   size=get_inquiery_part_LS30(s, (unsigned char) 1);
1564   if(strncmp((char *)s->buffer+5,"Strip",5)==0)
1565   { s->feeder=STRIP_FEEDER;
1566     s->autofeeder = 1;
1567   }
1568   if(strncmp((char *)s->buffer+5,"Mount",5)==0)
1569   { s->feeder=MOUNT_FEEDER;
1570   }
1571   /* find out about Film-strip-feeder positions*/
1572   if(s->feeder==STRIP_FEEDER)
1573   { size=coolscan_read_var_data_block (s,(int)0x88);
1574     if(size>=4)
1575     { s->numima=s->buffer[3];
1576       if(s->numima>6) s->numima=6; /* limit to 6 images for now */
1577       if(s->numima>(size-4)/16) s->numima=(size-4)/16;
1578       ptr=s->buffer+4;
1579       for(ima=0;ima<s->numima;ima++)
1580       {  s->ipos[ima].start=getnbyte(ptr,4);
1581          s->ipos[ima].offset=getnbyte(ptr+4,4);
1582          s->ipos[ima].end=getnbyte(ptr+8,4);
1583          s->ipos[ima].height=getnbyte(ptr+12,4);
1584 	 ptr+=16;
1585       }
1586     }
1587     s->posima=0;
1588   }
1589   return 1;
1590 }
1591 
1592 
1593 static int
get_internal_info_LS20(Coolscan_t * s)1594 get_internal_info_LS20 (Coolscan_t * s)
1595 {
1596   int ret;
1597 
1598   DBG (10, "get_internal_info\n");
1599   wait_scanner (s);
1600   memset (s->buffer, '\0', DI_length);	/* clear buffer */
1601 
1602   set_R_datatype_code (sread.cmd, R_device_internal_info);
1603   set_R_datatype_qual_upper (sread.cmd, R_DQ_none);
1604   set_R_xfer_length (sread.cmd, DI_length);
1605   /* then get inquiry with actual size */
1606   ret = do_scsi_cmd (s->sfd, sread.cmd, sread.size,
1607 		     s->buffer, DI_length);
1608 
1609   s->adbits = get_DI_ADbits (s->buffer);
1610   s->outputbits = get_DI_Outputbits (s->buffer);
1611   s->maxres = get_DI_MaxResolution (s->buffer);
1612   s->xmax = get_DI_Xmax (s->buffer);
1613   s->ymax = get_DI_Ymax (s->buffer);
1614   s->xmaxpix = get_DI_Xmaxpixel (s->buffer);
1615   s->ymaxpix = get_DI_Ymaxpixel (s->buffer);
1616   s->ycurrent = get_DI_currentY (s->buffer);
1617   s->currentfocus = get_DI_currentFocus (s->buffer);
1618   s->currentscanpitch = get_DI_currentscanpitch (s->buffer);
1619   s->autofeeder = get_DI_autofeeder (s->buffer);
1620   s->analoggamma = get_DI_analoggamma (s->buffer);
1621   s->derr[0] = get_DI_deviceerror0 (s->buffer);
1622   s->derr[1] = get_DI_deviceerror1 (s->buffer);
1623   s->derr[2] = get_DI_deviceerror2 (s->buffer);
1624   s->derr[3] = get_DI_deviceerror3 (s->buffer);
1625   s->derr[4] = get_DI_deviceerror4 (s->buffer);
1626   s->derr[5] = get_DI_deviceerror5 (s->buffer);
1627   s->derr[6] = get_DI_deviceerror6 (s->buffer);
1628   s->derr[7] = get_DI_deviceerror7 (s->buffer);
1629   s->wbetr_r = get_DI_WBETR_R (s->buffer);
1630   s->webtr_g = get_DI_WBETR_G (s->buffer);
1631   s->webtr_b = get_DI_WBETR_B (s->buffer);
1632   s->pretv_r = get_DI_PRETV_R (s->buffer);
1633   s->pretv_g = get_DI_PRETV_G (s->buffer);
1634   s->pretv_r = get_DI_PRETV_R (s->buffer);
1635   s->cetv_r = get_DI_CETV_R (s->buffer);
1636   s->cetv_g = get_DI_CETV_G (s->buffer);
1637   s->cetv_b = get_DI_CETV_B (s->buffer);
1638   s->ietu_r = get_DI_IETU_R (s->buffer);
1639   s->ietu_g = get_DI_IETU_G (s->buffer);
1640   s->ietu_b = get_DI_IETU_B (s->buffer);
1641   s->limitcondition = get_DI_limitcondition (s->buffer);
1642   s->offsetdata_r = get_DI_offsetdata_R (s->buffer);
1643   s->offsetdata_g = get_DI_offsetdata_G (s->buffer);
1644   s->offsetdata_b = get_DI_offsetdata_B (s->buffer);
1645   get_DI_poweron_errors (s->buffer, s->power_on_errors);
1646 
1647   DBG (10,
1648        "\tadbits=%d\toutputbits=%d\tmaxres=%d\txmax=%d\tymax=%d\n"
1649        "\txmaxpix=%d\tymaxpix=%d\tycurrent=%d\tcurrentfocus=%d\n"
1650        "\tautofeeder=%s\tanaloggamma=%s\tcurrentscanpitch=%d\n",
1651        s->adbits, s->outputbits, s->maxres, s->xmax, s->ymax,
1652        s->xmaxpix, s->ymaxpix, s->ycurrent, s->currentfocus,
1653        s->autofeeder ? "Yes" : "No", s->analoggamma ? "Yes" : "No",
1654        s->currentscanpitch);
1655   DBG (10,
1656        "\tWhite balance exposure time var [RGB]=\t%d %d %d\n"
1657        "\tPrescan result exposure time var [RGB]=\t%d %d %d\n"
1658        "\tCurrent exposure time var.[RGB]=\t%d %d %d\n"
1659        "\tInternal exposure time unit[RGB]=\t%d %d %d\n",
1660        s->wbetr_r, s->webtr_g, s->webtr_b, s->pretv_r, s->pretv_g,
1661        s->pretv_r, s->cetv_r, s->cetv_g, s->cetv_b, s->ietu_r,
1662        s->ietu_g, s->ietu_b);
1663   DBG (10,
1664        "\toffsetdata_[rgb]=\t0x%x 0x%x 0x%x\n"
1665        "\tlimitcondition=0x%x\n"
1666        "\tdevice error code = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n"
1667        "\tpower-on errors = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1668        s->offsetdata_r, s->offsetdata_g, s->offsetdata_b,
1669        s->limitcondition,
1670        s->derr[0], s->derr[1], s->derr[2], s->derr[3], s->derr[4],
1671        s->derr[5], s->derr[6], s->derr[7],
1672        s->power_on_errors[0], s->power_on_errors[1],
1673        s->power_on_errors[2], s->power_on_errors[3],
1674        s->power_on_errors[4], s->power_on_errors[5],
1675        s->power_on_errors[6], s->power_on_errors[7]);
1676 
1677   return ret;
1678 }
1679 
1680 static int
get_internal_info(Coolscan_t * s)1681 get_internal_info (Coolscan_t * s)
1682 {
1683   int ret;
1684 
1685   DBG (10, "get_internal_info\n");
1686 
1687   if(s->LS<2)                   /* distinguish between old and new scanners */
1688   { ret=get_internal_info_LS20 (s);
1689   }
1690   else
1691   { ret=get_inquiery_LS30 (s);
1692   }
1693   return ret;
1694 }
1695 
1696 static void
coolscan_get_inquiry_values(Coolscan_t * s)1697 coolscan_get_inquiry_values (Coolscan_t * s)
1698 {
1699   unsigned char *inquiry_block;
1700 
1701   DBG (10, "get_inquiry_values\n");
1702 
1703   inquiry_block = (unsigned char *) s->buffer;
1704   s->inquiry_len = 36;
1705 
1706   get_inquiry_vendor ((char *)inquiry_block, (char *)s->vendor);
1707   s->vendor[8] = '\0';
1708   get_inquiry_product ((char *)inquiry_block, (char *)s->product);
1709   s->product[16] = '\0';
1710   get_inquiry_version ((char *)inquiry_block, (char *)s->version);
1711   s->version[4] = '\0';
1712 
1713   if (s->inquiry_len < 36)
1714     {
1715       DBG (1, "WARNING: inquiry return block is unexpected short (%d instead of 36).\n", s->inquiry_len);
1716     }
1717   s->inquiry_wdb_len = 117;
1718   return;
1719 }
1720 
1721 static void
coolscan_initialize_values(Coolscan_t * s)1722 coolscan_initialize_values (Coolscan_t * s)
1723 {
1724   int i;
1725   DBG (10, "initialize_values\n");
1726   /* Initialize us structure */
1727   if(s->LS<2)                   /* LS-20 or LS-10000 */
1728   {  select_MUD (s);		/* must be before mode_sense - not for LS-30*/
1729      coolscan_mode_sense (s);	/* Obtain MUD (Measurement Unit Divisor) */
1730      get_internal_info (s);	/* MUST be called first. */
1731      s->wdb_len = 117;
1732   }
1733   if(s->LS>=2)                  /* LS-30 */
1734   {
1735     get_inquiery_LS30(s);	/* Info about scanner*/
1736     select_MUD (s);		/* must be before mode_sense */
1737     get_feeder_type_LS30(s);
1738     s->wdb_len = 117;
1739   }
1740 
1741   s->cont = 0;			/* do not continue if scanner is unknown */
1742   s->verbose = 2;		/* 1=verbose,2=very verbose */
1743 
1744 
1745   s->x_nres = s->y_nres = 2;	/* 2 => 1350 dpi */
1746   s->x_p_nres = s->y_p_nres = 9;	/* 9 => 300 dpi */
1747   s->tlx = 0;
1748   s->tly = 0;
1749   s->brx = s->xmaxpix;		/* 2700 / 1200; */
1750   s->bry = s->ymaxpix;		/* 2700 / 1200; */
1751 
1752 
1753   s->set_auto = 0;		/* Always 0 on Nikon LS-{100|2}0 */
1754   s->preview = 0;		/* 1 for preview */
1755   s->colormode = RGB;		/* GREYSCALE or RGB */
1756   s->colormode_p = RGB;		/* GREYSCALE or RGB for preview*/
1757   s->asf = 0;			/* 1 if asf shall be used */
1758   s->gammaselection = WD_Linear;
1759 
1760   s->brightness = 128;
1761   s->brightness_R = 128;
1762   s->brightness_G = 128;
1763   s->brightness_B = 128;
1764   s->contrast = 128;
1765   s->contrast_R = 128;
1766   s->contrast_G = 128;
1767   s->contrast_B = 128;
1768 
1769   s->exposure_R = 50;
1770   s->exposure_G = 50;
1771   s->exposure_B = 50;
1772 
1773   s->pretv_r=40000;
1774   s->pretv_g=40000;
1775   s->pretv_b=40000;
1776 
1777   s->shift_R = 128;
1778   s->shift_G = 128;
1779   s->shift_B = 128;
1780 
1781   s->ired_red=60;
1782   s->ired_green=1;
1783   s->ired_blue=1;
1784 
1785   s->prescan = 1;
1786   s->bits_per_color = 8;
1787   s->rgb_control = 0;
1788   s->gamma_bind = 1;
1789   switch(s->LS)
1790   {  case 0:s->lutlength=2048;
1791             s->max_lut_val=256;
1792             break;
1793      case 1:s->lutlength=512;
1794             s->max_lut_val=512;
1795             break;
1796      case 2:s->lutlength=1024;
1797             s->max_lut_val=1024;
1798             break;
1799      case 3:s->lutlength=4096;
1800             s->max_lut_val=4096;
1801             break;
1802   }
1803   for (i = 0; i < s->lutlength; i++)
1804   {
1805      s->gamma[i] =((short)((((double)i)/s->lutlength)*s->max_lut_val));
1806      s->gamma_r[i] = s->gamma[i];
1807      s->gamma_g[i] = s->gamma[i];
1808      s->gamma_b[i] = s->gamma[i];
1809   }
1810 
1811   if (coolscan_test_little_endian() == SANE_TRUE)
1812   {
1813     s->low_byte_first = 1;					        /* in 2 byte mode send lowbyte first */
1814     DBG(10,"backend runs on little endian machine\n");
1815   }
1816   else
1817   {
1818     s->low_byte_first = 0;					       /* in 2 byte mode send highbyte first */
1819     DBG(10,"backend runs on big endian machine\n");
1820   }
1821 }
1822 
1823 static void
hexdump(int level,char * comment,unsigned char * p,int l)1824 hexdump (int level, char *comment, unsigned char *p, int l)
1825 {
1826   int i;
1827   char line[128];
1828   char *ptr;
1829 
1830   DBG (level, "%s\n", comment);
1831   ptr = line;
1832   for (i = 0; i < l; i++, p++)
1833     {
1834       if ((i % 16) == 0)
1835 	{
1836 	  if (ptr != line)
1837 	    {
1838 	      *ptr = '\0';
1839 	      DBG (level, "%s\n", line);
1840 	      ptr = line;
1841 	    }
1842 	  sprintf (ptr, "%3.3d:", i);
1843 	  ptr += 4;
1844 	}
1845       sprintf (ptr, " %2.2x", *p);
1846       ptr += 3;
1847     }
1848   *ptr = '\0';
1849   DBG (level, "%s\n", line);
1850 }
1851 
1852 
1853 static SANE_Status
sense_handler(int scsi_fd,unsigned char * result,void * arg)1854 sense_handler (int scsi_fd, unsigned char * result, void *arg)
1855 {
1856   (void) scsi_fd;
1857   (void) arg;
1858 
1859   if (result[0] != 0x70)
1860     {
1861       return SANE_STATUS_IO_ERROR;	/* we only know about this one  */
1862     }
1863   return request_sense_parse(result);
1864 
1865 }
1866 
1867 
1868 /* ------------------------------------------------------------------------- */
1869 
1870 
1871 /* ilu per mm */
1872 
1873 #define length_quant SANE_UNFIX(SANE_FIX(MM_PER_INCH / 2700.0))
1874 #define mmToIlu(mm) ((mm) / length_quant)
1875 #define iluToMm(ilu) ((ilu) * length_quant)
1876 
1877 #define P_200_TO_255(per) SANE_UNFIX((per + 100) * 255/200 )
1878 #define P_100_TO_255(per) SANE_UNFIX(per * 255/100 )
1879 
1880 static const char negativeStr[] = "Negative";
1881 static const char positiveStr[] = "Positive";
1882 static SANE_String_Const type_list[] =
1883 {
1884   positiveStr,
1885   negativeStr,
1886   0
1887 };
1888 
1889 static const char colorStr[] = SANE_VALUE_SCAN_MODE_COLOR;
1890 static const char grayStr[] = SANE_VALUE_SCAN_MODE_GRAY;
1891 static const char rgbiStr[] = "RGBI";
1892 static const char iredStr[] = "Infrared";
1893 
1894 static SANE_String_Const scan_mode_list_LS20[] =
1895 {
1896   colorStr,
1897   grayStr,
1898   NULL
1899 };
1900 
1901 static SANE_String_Const scan_mode_list_LS30[] =
1902 {
1903   colorStr,
1904   grayStr,
1905 #ifdef HAS_IRED
1906   rgbiStr,
1907 #endif /* HAS_IRED */
1908   NULL
1909 };
1910 
1911 static SANE_Int bit_depth_list[9];
1912 
1913 static const char neverStr[] = "never";
1914 static const char previewStr[] = "before preview";
1915 static const char scanStr[] = "before scan";
1916 static const char preandscanStr[] = "before preview and scan";
1917 static SANE_String_Const autofocus_mode_list[] =
1918 {
1919   neverStr,
1920   previewStr,
1921   scanStr,
1922   preandscanStr,
1923   NULL
1924 };
1925 
1926 static SANE_String_Const source_list[4] =
1927 {NULL, NULL, NULL, NULL};
1928 
1929 static const SANE_Range gamma_range_8 =
1930 {
1931   0,				/* minimum */
1932   255,				/* maximum */
1933   1				/* quantization */
1934 };
1935 
1936 
1937 static const SANE_Range gamma_range_9 =
1938 {
1939   0,				/* minimum */
1940   511,				/* maximum */
1941   1				/* quantization */
1942 };
1943 
1944 static const SANE_Range gamma_range_10 =
1945 {
1946   0,				/* minimum */
1947   1023,				/* maximum */
1948   1				/* quantization */
1949 };
1950 
1951 static const SANE_Range gamma_range_12 =
1952 {
1953   0,				/* minimum */
1954   4096,				/* maximum */
1955   1				/* quantization */
1956 };
1957 
1958 static const SANE_Range brightness_range =
1959 {
1960   -5,
1961   +5,
1962   1
1963 };
1964 
1965 static const SANE_Range contrast_range =
1966 {
1967   -5,
1968   +5,
1969   0
1970 };
1971 
1972 static const SANE_Range exposure_range =
1973 {
1974   24,
1975   400,
1976   2
1977 };
1978 
1979 static const SANE_Range shift_range =
1980 {
1981   -15,
1982   +15,
1983   0
1984 };
1985 
1986 static const SANE_Device **devlist = 0;
1987 static int num_devices;
1988 static Coolscan_t *first_dev;
1989 
1990 
1991 static size_t
max_string_size(const SANE_String_Const strings[])1992 max_string_size (const SANE_String_Const strings[])
1993 {
1994   size_t size, max_size = 0;
1995   int i;
1996 
1997   for (i = 0; strings[i]; ++i)
1998     {
1999       size = strlen (strings[i]) + 1;
2000       if (size > max_size)
2001 	max_size = size;
2002     }
2003   return max_size;
2004 }
2005 
2006 static SANE_Status
do_eof(Coolscan_t * scanner)2007 do_eof (Coolscan_t * scanner)
2008 {
2009   DBG (10, "do_eof\n");
2010 
2011   if (scanner->pipe >= 0)
2012     {
2013       close (scanner->pipe);
2014       scanner->pipe = -1;
2015     }
2016   return SANE_STATUS_EOF;
2017 }
2018 
2019 static SANE_Status
do_cancel(Coolscan_t * scanner)2020 do_cancel (Coolscan_t * scanner)
2021 {
2022   DBG (10, "do_cancel\n");
2023   swap_res (scanner);
2024   scanner->scanning = SANE_FALSE;
2025 
2026   do_eof (scanner);		/* close pipe and reposition scanner */
2027 
2028   if (sanei_thread_is_valid (scanner->reader_pid))
2029     {
2030       int exit_status;
2031 
2032       DBG (10, "do_cancel: kill reader_process\n");
2033 
2034       /* ensure child knows it's time to stop: */
2035       sanei_thread_kill (scanner->reader_pid);
2036       while (sanei_thread_waitpid(scanner->reader_pid, &exit_status) !=
2037                                                         scanner->reader_pid );
2038       sanei_thread_invalidate (scanner->reader_pid);
2039     }
2040 
2041   if (scanner->sfd >= 0)
2042     {
2043       coolscan_give_scanner (scanner);
2044       DBG (10, "do_cancel: close filedescriptor\n");
2045       sanei_scsi_close (scanner->sfd);
2046       scanner->sfd = -1;
2047     }
2048 
2049   return SANE_STATUS_CANCELLED;
2050 }
2051 
2052 static SANE_Status
attach_scanner(const char * devicename,Coolscan_t ** devp)2053 attach_scanner (const char *devicename, Coolscan_t ** devp)
2054 {
2055   Coolscan_t *dev;
2056   int sfd;
2057 
2058   DBG (10, "attach_scanner: %s\n", devicename);
2059 
2060   for (dev = first_dev; dev; dev = dev->next)
2061     {
2062       if (strcmp (dev->sane.name, devicename) == 0)
2063 	{
2064 	  if (devp)
2065 	    {
2066 	      *devp = dev;
2067 	    }
2068 	  DBG (5, "attach_scanner: scanner already attached (is ok)!\n");
2069 	  return SANE_STATUS_GOOD;
2070 	}
2071     }
2072 
2073   DBG (10, "attach_scanner: opening %s\n", devicename);
2074   if (sanei_scsi_open (devicename, &sfd, sense_handler, 0) != 0)
2075     {
2076       DBG (1, "attach_scanner: open failed\n");
2077       return SANE_STATUS_INVAL;
2078     }
2079 
2080   if (NULL == (dev = malloc (sizeof (*dev))))
2081     return SANE_STATUS_NO_MEM;
2082 
2083 
2084   dev->row_bufsize = (sanei_scsi_max_request_size < (64 * 1024)) ?
2085   	sanei_scsi_max_request_size : 64 * 1024;
2086 
2087   if ((dev->buffer = malloc (dev->row_bufsize)) == NULL)
2088 /*  if ((dev->buffer = malloc (sanei_scsi_max_request_size)) == NULL)*/
2089     return SANE_STATUS_NO_MEM;
2090 
2091   if ((dev->obuffer = malloc (dev->row_bufsize)) == NULL)
2092     return SANE_STATUS_NO_MEM;
2093 
2094   dev->devicename = strdup (devicename);
2095   dev->sfd = sfd;
2096 
2097   /* Nikon manual: Step 1 */
2098   if (coolscan_identify_scanner (dev) != 0)
2099     {
2100       DBG (1, "attach_scanner: scanner-identification failed\n");
2101       sanei_scsi_close (dev->sfd);
2102       free (dev->buffer);
2103       free (dev);
2104       return SANE_STATUS_INVAL;
2105     }
2106 
2107   /* Get MUD (via mode_sense), internal info (via get_internal_info), and
2108    * initialize values */
2109   coolscan_initialize_values (dev);
2110 
2111   /* Why? */
2112   sanei_scsi_close (dev->sfd);
2113   dev->sfd = -1;
2114 
2115   dev->sane.name = dev->devicename;
2116   dev->sane.vendor = dev->vendor;
2117   dev->sane.model = dev->product;
2118   dev->sane.type = "slide scanner";
2119 
2120   dev->x_range.min = SANE_FIX (0);
2121   dev->x_range.quant = SANE_FIX (length_quant);
2122   dev->x_range.max = SANE_FIX ((double) ((dev->xmaxpix) * length_quant));
2123 
2124   dev->y_range.min = SANE_FIX (0.0);
2125   dev->y_range.quant = SANE_FIX (length_quant);
2126   dev->y_range.max = SANE_FIX ((double) ((dev->ymaxpix) * length_quant));
2127 
2128   /* ...and this?? */
2129   dev->dpi_range.min = SANE_FIX (108);
2130   dev->dpi_range.quant = SANE_FIX (0);
2131   dev->dpi_range.max = SANE_FIX (dev->maxres);
2132   DBG (10, "attach: dev->dpi_range.max = %f\n",
2133        SANE_UNFIX (dev->dpi_range.max));
2134 
2135   ++num_devices;
2136   dev->next = first_dev;
2137   first_dev = dev;
2138 
2139   if (devp)
2140     {
2141       *devp = dev;
2142     }
2143 
2144   DBG (10, "attach_scanner done\n");
2145 
2146   return SANE_STATUS_GOOD;
2147 }
2148 
2149 static SANE_Status
attach_one(const char * devName)2150 attach_one (const char *devName)
2151 {
2152   return attach_scanner(devName, 0);
2153 }
2154 
2155 static void
sigterm_handler(int signal)2156 sigterm_handler (int signal)
2157 {
2158   (void) signal;
2159   sanei_scsi_req_flush_all ();	/* flush SCSI queue */
2160   _exit (SANE_STATUS_GOOD);
2161 }
2162 
2163 
2164 typedef struct Color_correct_s
2165 { int sum;           /* number of pixels summed so far */
2166   double sumr;          /* sum of red pixel values*/
2167   double sumi;          /* sum of infrared pixel values*/
2168   double sumri;         /* sum of red*ired pixel values*/
2169   double sumii;         /* sum of ired*ired pixel values*/
2170   double sumrr;         /* sum of ired*ired pixel values*/
2171   int  mr;         /* factor between red and ired values (*256) */
2172   int  br;         /* offset of ired values */
2173 } ColorCorrect;
2174 
2175 /* ---------------------------------------------------------------
2176 
2177   function:   RGBIfix
2178 
2179   task:       Correct the infrared channel
2180 
2181   import:     unsigned char * rgbimat - RGBI - matrix from scanner
2182               int size - number of pixels to correct
2183 	      int *lutr - lookup table for red correction
2184 	      int *lutg - lookup table for red correction
2185 	      int *lutb - lookup table for red correction
2186 	      int *lutr - lookup table for red correction
2187 
2188   export:     unsigned char * orgbimat - RGBI - corrected matrix
2189 
2190   written by: Andreas RICK   19.6.1999
2191 
2192   ----------------------------------------------------------------*/
2193 
Calc_fix_LUT(Coolscan_t * s)2194 static int Calc_fix_LUT(Coolscan_t * s)
2195 { int uselutr,uselutg,uselutb,useluti;
2196 /*  static int irmulr= -34*25; */
2197    int irmulr= -64*25;
2198    int irmulg= -1*25;
2199    int irmulb= -0*25;
2200    int irmuli= 256*25;
2201    int div;
2202    int i;
2203 
2204     irmulr=s->ired_red*(25);
2205     irmulg=s->ired_green*(25);
2206     irmulb=s->ired_blue*(25);
2207     irmuli=25*256;
2208 
2209   if(s->LS==2) /* TODO: right conversion factors for 10 and 12 bit */
2210     { div=4;
2211     }
2212   else  if(s->LS==3)
2213     { div=16;
2214     }
2215   else
2216     { return 0;
2217     }
2218 
2219   memset(s->lutr, 0,256*4);
2220   memset(s->lutg, 0,256*4);
2221   memset(s->lutb, 0,256*4);
2222   memset(s->luti, 0,256*4);
2223 
2224   for(i=0;i<s->lutlength;i++)
2225   {  if(s->gamma_bind)
2226      { uselutr=uselutg=uselutb=useluti=s->gamma[i]/div;
2227      }
2228      else
2229      { uselutr=s->gamma_r[i]/div;
2230        uselutg=s->gamma_g[i]/div;
2231        uselutb=s->gamma_b[i]/div;
2232        useluti=s->gamma_r[i]/div;
2233      }
2234      s->lutr[uselutr]=(int)(irmulr*pow((double)i,(double)0.333333));
2235      s->lutg[uselutg]=(int)(irmulg*pow((double)i,(double)0.333333));
2236      s->lutb[uselutb]=(int)(irmulb*pow((double)i,(double)0.333333));
2237      s->luti[useluti]=(int)(irmuli*pow((double)i,(double)0.333333));
2238      if(uselutr<255)
2239      { if(s->lutr[uselutr+1]==0) s->lutr[uselutr+1]=s->lutr[uselutr];
2240      }
2241      if(uselutg<255)
2242      { if(s->lutg[uselutg+1]==0) s->lutg[uselutg+1]=s->lutg[uselutg];
2243      }
2244      if(uselutb<255)
2245      { if(s->lutb[uselutb+1]==0) s->lutb[uselutb+1]=s->lutb[uselutb];
2246      }
2247      if(useluti<255)
2248      { if(s->luti[useluti+1]==0) s->luti[useluti+1]=s->luti[useluti];
2249      }
2250   }
2251   /* DEBUG
2252   for(i=0;i<255;i++)
2253   { fprintf(stderr,"%d %d %d %d\n"
2254 	    ,s->lutr[i],s->lutg[i],s->lutb[i],s->luti[i]);
2255   }
2256   */
2257   return 1;
2258 }
2259 
2260 
2261 
2262 /* ---------------------------------------------------------------
2263 
2264   function:   RGBIfix
2265 
2266   task:       Correct the infrared channel
2267 
2268   import:     unsigned char * rgbimat - RGBI - matrix from scanner
2269               int size - number of pixels to correct
2270 	      int *lutr - lookup table for red correction
2271 	      int *lutg - lookup table for red correction
2272 	      int *lutb - lookup table for red correction
2273 	      int *lutr - lookup table for red correction
2274 
2275   export:     unsigned char * orgbimat - RGBI - corrected matrix
2276 
2277   written by: Andreas RICK   19.6.1999
2278 
2279   ----------------------------------------------------------------*/
2280 
RGBIfix(Coolscan_t * scanner,unsigned char * rgbimat,unsigned char * orgbimat,int size,int * lutr,int * lutg,int * lutb,int * luti)2281 static int RGBIfix(Coolscan_t * scanner,
2282 	   unsigned char* rgbimat,
2283 	   unsigned char* orgbimat,
2284 	    int size,
2285 	    int *lutr,
2286 	    int *lutg,
2287 	    int *lutb,
2288 	    int *luti)
2289 
2290 {
2291   unsigned char *pr,*pg,*pb,*pi;
2292   unsigned char *opr,*opg,*opb,*opi;
2293 
2294    int r,g,b,i;
2295    int ii;
2296    int x;
2297    for(x=0;x<size;x++)
2298    {
2299         pr=rgbimat+x*4;
2300 	pg=pr+1;
2301 	pb=pg+1;
2302 	pi=pb+1;
2303         opr=orgbimat+x*4;
2304 	opg=opr+1;
2305 	opb=opg+1;
2306 	opi=opb+1;
2307 	r=lutr[(*pr)];
2308 	g=lutg[(*pg)];
2309 	b=lutb[(*pb)];
2310 	i=luti[(*pi)];
2311 	ii= i-r-g-b;
2312 	(*opr)=(*pr);
2313 	(*opg)=(*pg);
2314 	(*opb)=(*pb);
2315 	if(ii<0)ii=0;
2316 	if(ii>255*256)ii=255*256;
2317 	if(scanner->negative)
2318 	{
2319 	    (*opi)=(unsigned char)(255-(ii>>8));
2320 	}
2321 	else
2322 	{
2323 	  (*opi)=(unsigned char)(ii>>8);
2324 	}
2325    }
2326    return 1;
2327 }
2328 
2329 /* ---------------------------------------------------------------
2330 
2331   function:   RGBIfix16
2332 
2333   task:       Correct the infrared channel for 16 bit images
2334               (doesn't do anything for now)
2335 
2336   import:     unsigned char * rgbimat - RGBI - matrix from scanner
2337               int size - number of pixels to correct
2338 	      int *lutr - lookup table for red correction
2339 	      int *lutg - lookup table for red correction
2340 	      int *lutb - lookup table for red correction
2341 	      int *lutr - lookup table for red correction
2342 
2343   export:     unsigned char * orgbimat - RGBI - corrected matrix
2344 
2345   written by: Andreas RICK   19.6.1999
2346 
2347   ----------------------------------------------------------------*/
2348 
RGBIfix16(Coolscan_t * scanner,unsigned short * rgbimat,unsigned short * orgbimat,int size,int * lutr,int * lutg,int * lutb,int * luti)2349 static int RGBIfix16(Coolscan_t * scanner,
2350 	      unsigned short* rgbimat,
2351 	      unsigned short* orgbimat,
2352 	      int size,
2353 	      int *lutr,
2354 	      int *lutg,
2355 	      int *lutb,
2356 	      int *luti)
2357 
2358 {
2359   unsigned short *pr,*pg,*pb,*pi;
2360   unsigned short *opr,*opg,*opb,*opi;
2361   int x;
2362 
2363   (void) scanner; (void) lutr; (void) lutg; (void) lutb; (void) luti;
2364 
2365    for(x=0;x<size;x++)
2366    {
2367         pr=rgbimat+x*4;
2368 	pg=pr+1;
2369 	pb=pg+1;
2370 	pi=pb+1;
2371         opr=orgbimat+x*4;
2372 	opg=opr+1;
2373 	opb=opg+1;
2374 	opi=opb+1;
2375 	(*opr)=(((*pr)&0x00ff)<<8)+(((*pr)&0xff00)>>8);
2376       	(*opg)=(((*pg)&0x00ff)<<8)+(((*pg)&0xff00)>>8);
2377 	(*opb)=(((*pb)&0x00ff)<<8)+(((*pb)&0xff00)>>8);
2378 	(*opi)=(((*pi)&0x00ff)<<8)+(((*pi)&0xff00)>>8);
2379    }
2380    return 1;
2381 }
2382 
2383 
2384 /* ---------------------------------------------------------------
2385 
2386   function:   rgb2g
2387 
2388   task:       Convert RGB data to grey
2389 
2390   import:     unsigned char * rgbimat - RGB - matrix from scanner
2391               int size - size of input data (num pixel)
2392 
2393   export:     unsigned char * gomat - Grey matrix
2394 
2395   written by: Andreas RICK   13.7.1999
2396 
2397   ----------------------------------------------------------------*/
2398 #define RtoG ((int)(0.27*256))
2399 #define GtoG ((int)(0.54*256))
2400 #define BtoG ((int)(0.19*256))
2401 
rgb2g(unsigned char * rgbimat,unsigned char * gomat,int size)2402 static int rgb2g(unsigned char* rgbimat,unsigned char* gomat,
2403 	  int size)
2404 
2405 {  unsigned char *pr,*pg,*pb;
2406    unsigned char *opg;
2407 
2408    int g;
2409    int x;
2410    for(x=0;x<size;x++)
2411    {
2412         pr=rgbimat+x*3;
2413 	pg=pr+1;
2414 	pb=pg+1;
2415         opg=gomat+x;
2416 	g= RtoG*(*pr) + GtoG*(*pg) + BtoG*(*pb);
2417 	(*opg)=(unsigned char)(g>>8);
2418    }
2419    return 1;
2420 }
2421 
2422 
2423 /* ---------------------------------------------------------------
2424 
2425   function:   RGBIfix1
2426 
2427   task:       Correct the infrared channel.
2428               The input image data is the output of scanning
2429 	      with LUT. To calculate the original values
2430 	      the lutr and luti is applied.
2431 	      The infrared values is corrected by:
2432 
2433 	      Ir=mr*lutr(r)+luti(i)
2434 
2435   import:     unsigned char * rgbimat - RGBI - matrix from scanner
2436               int size - number of pixels to correct
2437  	      ColorCorrect *cc,
2438 	      int *lutr - lookup table for red correction
2439 	      int *luti - lookup table for ired correction
2440 
2441   export:     unsigned char * orgbimat - RGBI - corrected matrix
2442 
2443   written by: Andreas RICK   3.7.1999
2444 
2445   ----------------------------------------------------------------*/
2446 #if 0
2447 static int RGBIfix1(unsigned char* rgbimat,unsigned char* orgbimat,
2448 	    int size,
2449 	    int *lutr,
2450 	    int *lutg,
2451 	    int *lutb,
2452 	    int *luti)
2453 
2454 {  unsigned char *pr,*pg,*pb,*pi;
2455    unsigned char *opr,*opg,*opb,*opi;
2456    ColorCorrect cc;
2457    int r,i;
2458    static int thresi=100;
2459    int ii;
2460    int x;
2461 
2462    (void) lutg; (void) lutb;
2463 
2464    /* calculate regression between r and ir */
2465    cc.sum=0;
2466    cc.sumr=cc.sumii=cc.sumrr=cc.sumi=cc.sumri=0.0;
2467    for(x=0;x<size;x++)
2468    {    pr=rgbimat+x*4;
2469 	pi=pr+3;
2470 	r=lutr[(*pr)];
2471 	i=luti[(*pi)];
2472 	/*	r=(*pr);
2473 		i=(*pi); */
2474 	if((*pi)>thresi)
2475         { cc.sum++;
2476           cc.sumr+=r;
2477           cc.sumii+=(i*i);
2478           cc.sumrr+=(r*r);
2479           cc.sumi+=i;
2480           cc.sumri+=(i*r);
2481 	}
2482    }
2483    if((cc.sumii!=0)&&(cc.sum!=0))
2484    { double dn,dz,dm;
2485      dz=(cc.sumri-cc.sumr*cc.sumi/cc.sum);
2486      dn=(cc.sumrr-cc.sumr*cc.sumr/cc.sum);
2487      DBG (2, "Reg:dz:%e dn:%e\n",dz,dn);
2488      if(dn!=0)
2489      {  dm=(dz/dn);
2490         cc.mr=(int)(dm*1024);
2491      }
2492      else
2493      { cc.mr=0;
2494        dm=0;
2495      }
2496      cc.br=(int)((cc.sumi-dm*cc.sumr)/cc.sum);
2497    }
2498    else
2499    { cc.mr=0;
2500    }
2501    DBG (2, "Regression: size:%d I=%d/1024*R b:%d s:%d sr:%e si:%e sii:%e sri:%e  srr:%e\n",
2502 	size,cc.mr,cc.br,cc.sum,cc.sumr,cc.sumi,cc.sumii,cc.sumri,cc.sumrr);
2503    for(x=0;x<size;x++)
2504    {
2505 
2506         pr=rgbimat+x*4;
2507 	pg=pr+1;
2508 	pb=pg+1;
2509 	pi=pb+1;
2510         opr=orgbimat+x*4;
2511 	opg=opr+1;
2512 	opb=opg+1;
2513 	opi=opb+1;
2514 	r=lutr[(*pr)];
2515 	i=luti[(*pi)];
2516 	/*	r=(*pr);
2517 		i=(*pi); */
2518 	ii= ((i-((r*cc.mr)>>10)-cc.br)>>2) +128;
2519 	(*opr)=(*pr);
2520 	(*opg)=(*pg);
2521 	(*opb)=(*pb);
2522 	if(ii<0) ii=0;
2523 	if(ii>255) ii=255;
2524 	(*opi)=(unsigned char)(ii);
2525    }
2526    return 1;
2527 }
2528 
2529 #endif
2530 /* This function is executed as a child process. */
2531 static int
reader_process(void * data)2532 reader_process (void *data )
2533 {
2534   int status;
2535   unsigned int i;
2536   unsigned char h;
2537   unsigned int data_left;
2538   unsigned int data_to_read;
2539   unsigned int data_to_write;
2540   FILE *fp;
2541   sigset_t sigterm_set, ignore_set;
2542   struct SIGACTION act;
2543   unsigned int bpl, linesPerBuf, lineOffset;
2544   unsigned char r_data, g_data, b_data;
2545   unsigned int j, line;
2546   Coolscan_t * scanner = (Coolscan_t*)data;
2547 
2548   if (sanei_thread_is_forked ())
2549     {
2550       DBG (10, "reader_process started (forked)\n");
2551       close (scanner->pipe);
2552       scanner->pipe = -1;
2553 
2554       sigfillset ( &ignore_set );
2555       sigdelset  ( &ignore_set, SIGTERM );
2556 #if defined (__APPLE__) && defined (__MACH__)
2557       sigdelset  ( &ignore_set, SIGUSR2 );
2558 #endif
2559       sigprocmask( SIG_SETMASK, &ignore_set, 0 );
2560 
2561       memset (&act, 0, sizeof (act));
2562       sigaction (SIGTERM, &act, 0);
2563     }
2564   else
2565     {
2566       DBG (10, "reader_process started (as thread)\n");
2567     }
2568 
2569   sigemptyset (&sigterm_set);
2570   sigaddset (&sigterm_set, SIGTERM);
2571 
2572   fp = fdopen ( scanner->reader_fds, "w");
2573   if (!fp)
2574     {
2575       DBG (1, "reader_process: couldn't open pipe!\n");
2576       return 1;
2577     }
2578 
2579   DBG (10, "reader_process: starting to READ data\n");
2580 
2581   data_left = scan_bytes_per_line (scanner) *
2582     lines_per_scan (scanner);
2583 
2584   /*scanner->row_bufsize = sanei_scsi_max_request_size;*/
2585   coolscan_trim_rowbufsize (scanner);	/* trim bufsize */
2586 
2587   DBG (10, "reader_process: reading %u bytes in blocks of %u bytes\n",
2588        data_left, scanner->row_bufsize);
2589 
2590   memset (&act, 0, sizeof (act));
2591   act.sa_handler = sigterm_handler;
2592   sigaction (SIGTERM, &act, 0);
2593   /* wait_scanner(scanner); */
2594   do
2595     {
2596       data_to_read = (data_left < scanner->row_bufsize) ?
2597 	data_left : scanner->row_bufsize;
2598 
2599       data_to_write=data_to_read;
2600 
2601       status = coolscan_read_data_block (scanner
2602 					 ,R_datatype_imagedata,data_to_read);
2603       if (status == 0)
2604 	{
2605 	  continue;
2606 	}
2607       if (status == -1)
2608 	{
2609 	  DBG (1, "reader_process: unable to get image data from scanner!\n");
2610 	  fclose (fp);
2611 	  return (-1);
2612 	}
2613 
2614       if (scanner->LS == 1) {	/* mirror image for LS-1000 */
2615 	  bpl = scan_bytes_per_line(scanner);
2616 	  linesPerBuf = data_to_read / bpl;
2617 
2618 	  for (line = 0, lineOffset = 0; line < linesPerBuf;
2619 	       line++, lineOffset += bpl ) {
2620 
2621 	      if (scanner->colormode == RGB) {
2622 		  for (j = 0; j < bpl/2 ; j += 3) {
2623 		      r_data=scanner->buffer[lineOffset + j];
2624 		      g_data=scanner->buffer[lineOffset + j + 1];
2625 		      b_data=scanner->buffer[lineOffset + j + 2];
2626 
2627 		      scanner->buffer[lineOffset + j] =
2628 			  scanner->buffer[lineOffset + bpl -1 - j - 2 ];
2629 		      scanner->buffer[lineOffset + j + 1] =
2630 			  scanner->buffer[lineOffset + bpl -1 - j - 1 ];
2631 		      scanner->buffer[lineOffset + j + 2] =
2632 			  scanner->buffer[lineOffset + bpl -1 - j ];
2633 
2634 		      scanner->buffer[lineOffset + bpl -1 - j - 2 ] = r_data;
2635 		      scanner->buffer[lineOffset + bpl -1 - j - 1] = g_data;
2636 		      scanner->buffer[lineOffset + bpl -1 - j] = b_data;
2637 		  }
2638 	      }
2639 	      else {
2640 		  for (j = 0; j < bpl/2; j++) {
2641 		      r_data=scanner->buffer[lineOffset + j];
2642 		      scanner->buffer[lineOffset + j] =
2643 			  scanner->buffer[lineOffset + bpl - 1 - j];
2644 		      scanner->buffer[lineOffset + bpl - 1 - j] = r_data;
2645 		  }
2646 	      }
2647 	  }
2648       }
2649       if(scanner->colormode==RGBI)
2650       {  /* Correct Infrared Channel */
2651 	if(scanner->bits_per_color>8)
2652 	{
2653 	  RGBIfix16(scanner, (unsigned short * ) scanner->buffer,
2654 		    (unsigned short * )scanner->obuffer,
2655 		 data_to_read/8,scanner->lutr,
2656 		 scanner->lutg,scanner->lutb,scanner->luti);
2657 	}
2658 	else
2659 	{
2660 	  RGBIfix(scanner,scanner->buffer,scanner->obuffer,
2661 		 data_to_read/4,scanner->lutr,
2662 		 scanner->lutg,scanner->lutb,scanner->luti);
2663 	}
2664       }
2665       else if((scanner->colormode==GREYSCALE)&&(scanner->LS>=2))
2666       {  /* Convert to Grey */
2667 	 data_to_write/=3;
2668 	 rgb2g(scanner->buffer,scanner->obuffer,data_to_write);
2669       }
2670       else
2671       { /* or just copy */
2672 	memcpy (scanner->obuffer, scanner->buffer,data_to_read);
2673       }
2674       if((!scanner->low_byte_first)&&(scanner->bits_per_color>8))
2675 	{  for(i=0;i<data_to_write;i++) /* inverse byteorder */
2676            { h=scanner->obuffer[i];
2677              scanner->obuffer[i]=scanner->obuffer[i+1];
2678 	     i++;
2679   	     scanner->obuffer[i]=h;
2680 	   }
2681 	}
2682       fwrite (scanner->obuffer, 1, data_to_write, fp);
2683       fflush (fp);
2684       data_left -= data_to_read;
2685       DBG (10, "reader_process: buffer of %d bytes read; %d bytes to go\n",
2686 	   data_to_read, data_left);
2687     }
2688   while (data_left);
2689 
2690   fclose (fp);
2691 
2692   DBG (10, "reader_process: finished reading data\n");
2693 
2694   return 0;
2695 }
2696 
2697 static SANE_Status
init_options(Coolscan_t * scanner)2698 init_options (Coolscan_t * scanner)
2699 {
2700   int i;
2701   int bit_depths;
2702 
2703   DBG (10, "init_options\n");
2704 
2705   memset (scanner->opt, 0, sizeof (scanner->opt));
2706 
2707   for (i = 0; i < NUM_OPTIONS; ++i)
2708     {
2709       scanner->opt[i].size = sizeof (SANE_Word);
2710       scanner->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2711     }
2712 
2713   scanner->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
2714   scanner->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
2715   scanner->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
2716   scanner->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
2717 
2718   /* "Mode" group: */
2719   scanner->opt[OPT_MODE_GROUP].title = "Scan Mode";
2720   scanner->opt[OPT_MODE_GROUP].desc = "";
2721   scanner->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
2722   scanner->opt[OPT_MODE_GROUP].cap = 0;
2723   scanner->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
2724 
2725   /* scan mode */
2726   scanner->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
2727   scanner->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
2728   scanner->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
2729   scanner->opt[OPT_MODE].type = SANE_TYPE_STRING;
2730   if(scanner->LS<2)
2731   { scanner->opt[OPT_MODE].size = max_string_size (scan_mode_list_LS20);
2732     scanner->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2733     scanner->opt[OPT_MODE].constraint.string_list = scan_mode_list_LS20;
2734   }
2735   else
2736   { scanner->opt[OPT_MODE].size = max_string_size (scan_mode_list_LS30);
2737     scanner->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2738     scanner->opt[OPT_MODE].constraint.string_list = scan_mode_list_LS30;
2739   }
2740 
2741   /* source */
2742   source_list[0] = "Slide";
2743   source_list[1] = "Automatic Slide Feeder";
2744   source_list[2] = NULL;
2745   if (!scanner->autofeeder)
2746     {
2747       scanner->opt[OPT_SOURCE].cap = SANE_CAP_INACTIVE;
2748     }
2749 
2750   scanner->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
2751   scanner->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
2752   scanner->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
2753   scanner->opt[OPT_SOURCE].type = SANE_TYPE_STRING;
2754   scanner->opt[OPT_SOURCE].size = max_string_size (source_list);
2755   scanner->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2756   scanner->opt[OPT_SOURCE].constraint.string_list = source_list;
2757 
2758   /* negative */
2759   scanner->opt[OPT_TYPE].name = "type";
2760   scanner->opt[OPT_TYPE].title = "Film type";
2761   scanner->opt[OPT_TYPE].desc =
2762     "Select the film type (positive (slide) or negative)";
2763   scanner->opt[OPT_TYPE].type = SANE_TYPE_STRING;
2764   scanner->opt[OPT_TYPE].size = max_string_size (type_list);
2765   scanner->opt[OPT_TYPE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2766   scanner->opt[OPT_TYPE].constraint.string_list = type_list;
2767 
2768   scanner->opt[OPT_PRESCAN].name = "prescan";
2769   scanner->opt[OPT_PRESCAN].title = "Prescan";
2770   scanner->opt[OPT_PRESCAN].desc =
2771     "Perform a prescan during preview";
2772   scanner->opt[OPT_PRESCAN].type = SANE_TYPE_BOOL;
2773   scanner->opt[OPT_PRESCAN].unit = SANE_UNIT_NONE;
2774 
2775   scanner->opt[OPT_PRESCAN_NOW].name = "prescan now";
2776   scanner->opt[OPT_PRESCAN_NOW].title = "Prescan now";
2777   scanner->opt[OPT_PRESCAN_NOW].desc =
2778     "Perform a prescan now";
2779   scanner->opt[OPT_PRESCAN_NOW].type = SANE_TYPE_BUTTON;
2780   scanner->opt[OPT_PRESCAN_NOW].unit = SANE_UNIT_NONE;
2781   scanner->opt[OPT_PRESCAN_NOW].size = 0;
2782   scanner->opt[OPT_PRESCAN_NOW].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2783   scanner->opt[OPT_PRESCAN_NOW].constraint_type = SANE_CONSTRAINT_NONE;
2784   scanner->opt[OPT_PRESCAN_NOW].constraint.string_list = 0;
2785 
2786  /* bit depth */
2787 
2788   bit_depths=0;
2789   bit_depth_list[++bit_depths] = 8;
2790   if (scanner->LS==2)
2791   {
2792     bit_depth_list[++bit_depths] = 10;
2793   }
2794   if (scanner->LS==3)
2795   {
2796     bit_depth_list[++bit_depths] = 12;
2797   }
2798 
2799   bit_depth_list[0] = bit_depths;
2800 
2801   scanner->opt[OPT_BIT_DEPTH].name  = SANE_NAME_BIT_DEPTH;
2802   scanner->opt[OPT_BIT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
2803   scanner->opt[OPT_BIT_DEPTH].desc  = SANE_DESC_BIT_DEPTH;
2804   scanner->opt[OPT_BIT_DEPTH].type  = SANE_TYPE_INT;
2805   scanner->opt[OPT_BIT_DEPTH].unit  = SANE_UNIT_BIT;
2806   scanner->opt[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
2807   scanner->opt[OPT_BIT_DEPTH].constraint.word_list = bit_depth_list;
2808 
2809   /* resolution */
2810   scanner->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
2811   scanner->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
2812   scanner->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
2813   scanner->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
2814   scanner->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
2815   scanner->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
2816   scanner->opt[OPT_RESOLUTION].constraint.word_list = resolution_list;
2817 
2818   scanner->opt[OPT_PREVIEW_RESOLUTION].name = "preview-resolution";
2819   scanner->opt[OPT_PREVIEW_RESOLUTION].title = "Preview resolution";
2820   scanner->opt[OPT_PREVIEW_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
2821   scanner->opt[OPT_PREVIEW_RESOLUTION].type = SANE_TYPE_INT;
2822   scanner->opt[OPT_PREVIEW_RESOLUTION].unit = SANE_UNIT_DPI;
2823   scanner->opt[OPT_PREVIEW_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
2824   scanner->opt[OPT_PREVIEW_RESOLUTION].constraint.word_list = resolution_list;
2825 
2826   /* "Geometry" group: */
2827   scanner->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
2828   scanner->opt[OPT_GEOMETRY_GROUP].desc = "";
2829   scanner->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
2830   scanner->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
2831   scanner->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
2832 
2833   /* top-left x */
2834   scanner->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
2835   scanner->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
2836   scanner->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
2837   scanner->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
2838   scanner->opt[OPT_TL_X].unit = SANE_UNIT_MM;
2839   scanner->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
2840   scanner->opt[OPT_TL_X].constraint.range = &(scanner->x_range);
2841 
2842   /* top-left y */
2843   scanner->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
2844   scanner->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
2845   scanner->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
2846   scanner->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
2847   scanner->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
2848   scanner->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
2849   scanner->opt[OPT_TL_Y].constraint.range = &(scanner->y_range);
2850 
2851   /* bottom-right x */
2852   scanner->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
2853   scanner->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
2854   scanner->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
2855   scanner->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
2856   scanner->opt[OPT_BR_X].unit = SANE_UNIT_MM;
2857   scanner->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
2858   scanner->opt[OPT_BR_X].constraint.range = &(scanner->x_range);
2859 
2860   /* bottom-right y */
2861   scanner->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
2862   scanner->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
2863   scanner->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
2864   scanner->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
2865   scanner->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
2866   scanner->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
2867   scanner->opt[OPT_BR_Y].constraint.range = &(scanner->y_range);
2868 
2869 
2870   /* ------------------------------ */
2871 
2872   /* "Enhancement" group: */
2873   scanner->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
2874   scanner->opt[OPT_ENHANCEMENT_GROUP].desc = "";
2875   scanner->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
2876   scanner->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
2877   scanner->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
2878 
2879 
2880   scanner->opt[OPT_GAMMA_BIND].name = "gamma-bind";
2881   scanner->opt[OPT_GAMMA_BIND].title = "Gamma bind";
2882   scanner->opt[OPT_GAMMA_BIND].desc =
2883     "Use same gamma correction for all colours";
2884   scanner->opt[OPT_GAMMA_BIND].type = SANE_TYPE_BOOL;
2885   scanner->opt[OPT_GAMMA_BIND].unit = SANE_UNIT_NONE;
2886 
2887 
2888   scanner->opt[OPT_ANALOG_GAMMA].name = "analog_gamma";
2889   scanner->opt[OPT_ANALOG_GAMMA].title = "Analog Gamma";
2890   scanner->opt[OPT_ANALOG_GAMMA].desc = "Analog Gamma";
2891   scanner->opt[OPT_ANALOG_GAMMA].type = SANE_TYPE_BOOL;
2892   scanner->opt[OPT_ANALOG_GAMMA].unit = SANE_UNIT_NONE;
2893   if (!scanner->analoggamma)
2894     {
2895       scanner->opt[OPT_ANALOG_GAMMA].cap = SANE_CAP_INACTIVE;
2896     }
2897 
2898   scanner->opt[OPT_AVERAGING].name = "averaging";
2899   scanner->opt[OPT_AVERAGING].title = "Averaging";
2900   scanner->opt[OPT_AVERAGING].desc = "Averaging";
2901   scanner->opt[OPT_AVERAGING].type = SANE_TYPE_BOOL;
2902   scanner->opt[OPT_AVERAGING].unit = SANE_UNIT_NONE;
2903 
2904 
2905   scanner->opt[OPT_RGB_CONTROL].name = "rgb-control";
2906   scanner->opt[OPT_RGB_CONTROL].title = "RGB control";
2907   scanner->opt[OPT_RGB_CONTROL].desc =
2908     "toggles brightness/contrast control over individual colours";
2909   scanner->opt[OPT_RGB_CONTROL].type = SANE_TYPE_BOOL;
2910   scanner->opt[OPT_RGB_CONTROL].unit = SANE_UNIT_NONE;
2911   if(scanner->LS>=2)
2912   {  scanner->opt[OPT_RGB_CONTROL].cap |= SANE_CAP_INACTIVE;
2913   }
2914 
2915 
2916 
2917   /* brightness */
2918   scanner->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
2919   scanner->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
2920   scanner->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
2921   scanner->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
2922   scanner->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE;
2923   scanner->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
2924   scanner->opt[OPT_BRIGHTNESS].constraint.range = &brightness_range;
2925   if(scanner->LS>=2)
2926   {  scanner->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
2927   }
2928 
2929 
2930   scanner->opt[OPT_R_BRIGHTNESS].name = "red-brightness";
2931   scanner->opt[OPT_R_BRIGHTNESS].title = "Red brightness";
2932   scanner->opt[OPT_R_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
2933   scanner->opt[OPT_R_BRIGHTNESS].type = SANE_TYPE_INT;
2934   scanner->opt[OPT_R_BRIGHTNESS].unit = SANE_UNIT_NONE;
2935   scanner->opt[OPT_R_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
2936   scanner->opt[OPT_R_BRIGHTNESS].constraint.range = &brightness_range;
2937   scanner->opt[OPT_R_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
2938 
2939   scanner->opt[OPT_G_BRIGHTNESS].name = "green-brightness";
2940   scanner->opt[OPT_G_BRIGHTNESS].title = "Green brightness";
2941   scanner->opt[OPT_G_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
2942   scanner->opt[OPT_G_BRIGHTNESS].type = SANE_TYPE_INT;
2943   scanner->opt[OPT_G_BRIGHTNESS].unit = SANE_UNIT_NONE;
2944   scanner->opt[OPT_G_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
2945   scanner->opt[OPT_G_BRIGHTNESS].constraint.range = &brightness_range;
2946   scanner->opt[OPT_G_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
2947 
2948   scanner->opt[OPT_B_BRIGHTNESS].name = "blue-brightness";
2949   scanner->opt[OPT_B_BRIGHTNESS].title = "Blue brightness";
2950   scanner->opt[OPT_B_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
2951   scanner->opt[OPT_B_BRIGHTNESS].type = SANE_TYPE_INT;
2952   scanner->opt[OPT_B_BRIGHTNESS].unit = SANE_UNIT_NONE;
2953   scanner->opt[OPT_B_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
2954   scanner->opt[OPT_B_BRIGHTNESS].constraint.range = &brightness_range;
2955   scanner->opt[OPT_B_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
2956 
2957   /* contrast */
2958   scanner->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
2959   scanner->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
2960   scanner->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST;
2961   scanner->opt[OPT_CONTRAST].type = SANE_TYPE_INT;
2962   scanner->opt[OPT_CONTRAST].unit = SANE_UNIT_NONE;
2963   scanner->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
2964   scanner->opt[OPT_CONTRAST].constraint.range = &contrast_range;
2965   if(scanner->LS>=2)
2966   {  scanner->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
2967   }
2968 
2969 
2970   scanner->opt[OPT_R_CONTRAST].name = "red-contrast";
2971   scanner->opt[OPT_R_CONTRAST].title = "Red contrast";
2972   scanner->opt[OPT_R_CONTRAST].desc = SANE_DESC_CONTRAST;
2973   scanner->opt[OPT_R_CONTRAST].type = SANE_TYPE_INT;
2974   scanner->opt[OPT_R_CONTRAST].unit = SANE_UNIT_NONE;
2975   scanner->opt[OPT_R_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
2976   scanner->opt[OPT_R_CONTRAST].constraint.range = &contrast_range;
2977   scanner->opt[OPT_R_CONTRAST].cap |= SANE_CAP_INACTIVE;
2978 
2979   scanner->opt[OPT_G_CONTRAST].name = "green-contrast";
2980   scanner->opt[OPT_G_CONTRAST].title = "Green contrast";
2981   scanner->opt[OPT_G_CONTRAST].desc = SANE_DESC_CONTRAST;
2982   scanner->opt[OPT_G_CONTRAST].type = SANE_TYPE_INT;
2983   scanner->opt[OPT_G_CONTRAST].unit = SANE_UNIT_NONE;
2984   scanner->opt[OPT_G_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
2985   scanner->opt[OPT_G_CONTRAST].constraint.range = &contrast_range;
2986   scanner->opt[OPT_G_CONTRAST].cap |= SANE_CAP_INACTIVE;
2987 
2988   scanner->opt[OPT_B_CONTRAST].name = "blue-contrast";
2989   scanner->opt[OPT_B_CONTRAST].title = "Blue contrast";
2990   scanner->opt[OPT_B_CONTRAST].desc = SANE_DESC_CONTRAST;
2991   scanner->opt[OPT_B_CONTRAST].type = SANE_TYPE_INT;
2992   scanner->opt[OPT_B_CONTRAST].unit = SANE_UNIT_NONE;
2993   scanner->opt[OPT_B_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
2994   scanner->opt[OPT_B_CONTRAST].constraint.range = &contrast_range;
2995   scanner->opt[OPT_B_CONTRAST].cap |= SANE_CAP_INACTIVE;
2996 
2997   scanner->opt[OPT_EXPOSURE].name = "exposure";
2998   scanner->opt[OPT_EXPOSURE].title = "Exposure";
2999   scanner->opt[OPT_EXPOSURE].desc = "";
3000   scanner->opt[OPT_EXPOSURE].type = SANE_TYPE_INT;
3001   scanner->opt[OPT_EXPOSURE].cap &= ~SANE_CAP_INACTIVE;
3002   scanner->opt[OPT_EXPOSURE].unit = SANE_UNIT_PERCENT;
3003   scanner->opt[OPT_EXPOSURE].constraint_type = SANE_CONSTRAINT_RANGE;
3004   scanner->opt[OPT_EXPOSURE].constraint.range = &exposure_range;
3005 
3006   scanner->opt[OPT_R_EXPOSURE].name = "red-exposure";
3007   scanner->opt[OPT_R_EXPOSURE].title = "Red exposure";
3008   scanner->opt[OPT_R_EXPOSURE].desc = "";
3009   scanner->opt[OPT_R_EXPOSURE].type = SANE_TYPE_INT;
3010   scanner->opt[OPT_R_EXPOSURE].cap |= SANE_CAP_INACTIVE;
3011   scanner->opt[OPT_R_EXPOSURE].unit = SANE_UNIT_PERCENT;
3012   scanner->opt[OPT_R_EXPOSURE].constraint_type = SANE_CONSTRAINT_RANGE;
3013   scanner->opt[OPT_R_EXPOSURE].constraint.range = &exposure_range;
3014 
3015   scanner->opt[OPT_G_EXPOSURE].name = "green-exposure";
3016   scanner->opt[OPT_G_EXPOSURE].title = "Green exposure";
3017   scanner->opt[OPT_G_EXPOSURE].desc = "";
3018   scanner->opt[OPT_G_EXPOSURE].type = SANE_TYPE_INT;
3019   scanner->opt[OPT_G_EXPOSURE].unit = SANE_UNIT_PERCENT;
3020   scanner->opt[OPT_G_EXPOSURE].constraint_type = SANE_CONSTRAINT_RANGE;
3021   scanner->opt[OPT_G_EXPOSURE].constraint.range = &exposure_range;
3022   scanner->opt[OPT_G_EXPOSURE].cap |= SANE_CAP_INACTIVE;
3023 
3024   scanner->opt[OPT_B_EXPOSURE].name = "blue-exposure";
3025   scanner->opt[OPT_B_EXPOSURE].title = "Blue exposre";
3026   scanner->opt[OPT_B_EXPOSURE].desc = "";
3027   scanner->opt[OPT_B_EXPOSURE].type = SANE_TYPE_INT;
3028   scanner->opt[OPT_B_EXPOSURE].unit = SANE_UNIT_PERCENT;
3029   scanner->opt[OPT_B_EXPOSURE].constraint_type = SANE_CONSTRAINT_RANGE;
3030   scanner->opt[OPT_B_EXPOSURE].constraint.range = &exposure_range;
3031   scanner->opt[OPT_B_EXPOSURE].cap |= SANE_CAP_INACTIVE;
3032   if(scanner->LS>=2)
3033   {  scanner->opt[OPT_R_EXPOSURE].cap &= ~SANE_CAP_INACTIVE;
3034      scanner->opt[OPT_G_EXPOSURE].cap &= ~SANE_CAP_INACTIVE;
3035      scanner->opt[OPT_B_EXPOSURE].cap &= ~SANE_CAP_INACTIVE;
3036      scanner->opt[OPT_EXPOSURE].cap |= SANE_CAP_INACTIVE;
3037   }
3038 
3039   scanner->opt[OPT_R_SHIFT].name = "red-shift";
3040   scanner->opt[OPT_R_SHIFT].title = "Red shift";
3041   scanner->opt[OPT_R_SHIFT].desc = "";
3042   scanner->opt[OPT_R_SHIFT].type = SANE_TYPE_INT;
3043   scanner->opt[OPT_R_SHIFT].unit = SANE_UNIT_NONE;
3044   scanner->opt[OPT_R_SHIFT].constraint_type = SANE_CONSTRAINT_RANGE;
3045   scanner->opt[OPT_R_SHIFT].constraint.range = &shift_range;
3046   if(scanner->LS>=2)
3047   {  scanner->opt[OPT_R_SHIFT].cap |= SANE_CAP_INACTIVE;
3048   }
3049 
3050 
3051   scanner->opt[OPT_G_SHIFT].name = "green-shift";
3052   scanner->opt[OPT_G_SHIFT].title = "Green shift";
3053   scanner->opt[OPT_G_SHIFT].desc = "";
3054   scanner->opt[OPT_G_SHIFT].type = SANE_TYPE_INT;
3055   scanner->opt[OPT_G_SHIFT].unit = SANE_UNIT_NONE;
3056   scanner->opt[OPT_G_SHIFT].constraint_type = SANE_CONSTRAINT_RANGE;
3057   scanner->opt[OPT_G_SHIFT].constraint.range = &shift_range;
3058   if(scanner->LS>=2)
3059   {  scanner->opt[OPT_G_SHIFT].cap |= SANE_CAP_INACTIVE;
3060   }
3061 
3062 
3063   scanner->opt[OPT_B_SHIFT].name = "blue-shift";
3064   scanner->opt[OPT_B_SHIFT].title = "Blue shift";
3065   scanner->opt[OPT_B_SHIFT].desc = "";
3066   scanner->opt[OPT_B_SHIFT].type = SANE_TYPE_INT;
3067   scanner->opt[OPT_B_SHIFT].unit = SANE_UNIT_NONE;
3068   scanner->opt[OPT_B_SHIFT].constraint_type = SANE_CONSTRAINT_RANGE;
3069   scanner->opt[OPT_B_SHIFT].constraint.range = &shift_range;
3070   if(scanner->LS>=2)
3071   {  scanner->opt[OPT_B_SHIFT].cap |= SANE_CAP_INACTIVE;
3072   }
3073 
3074   /* R+G+B gamma vector */
3075   scanner->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
3076   scanner->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
3077   scanner->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
3078   scanner->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
3079   if (scanner->LS == 1)
3080     {
3081       scanner->opt[OPT_GAMMA_VECTOR].cap = SANE_CAP_INACTIVE;
3082     }
3083   scanner->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
3084   switch(scanner->LS)
3085   {  case 0:
3086            scanner->opt[OPT_GAMMA_VECTOR].constraint.range = &gamma_range_8;
3087            scanner->lutlength=2048;
3088            break;
3089      case 1:
3090            scanner->opt[OPT_GAMMA_VECTOR].constraint.range = &gamma_range_9;
3091            scanner->lutlength=512;
3092            break;
3093      case 2:
3094            scanner->opt[OPT_GAMMA_VECTOR].constraint.range = &gamma_range_10;
3095            scanner->lutlength=1024;
3096            break;
3097      case 3:
3098            scanner->opt[OPT_GAMMA_VECTOR].constraint.range = &gamma_range_12;
3099            scanner->lutlength=4096;
3100            break;
3101   }
3102   scanner->opt[OPT_GAMMA_VECTOR].size = scanner->lutlength * sizeof (SANE_Word);
3103   scanner->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
3104 
3105   /* red gamma vector */
3106   scanner->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
3107   scanner->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
3108   scanner->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
3109   scanner->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
3110   scanner->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
3111   scanner->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
3112   switch(scanner->LS)
3113   {  case 0:
3114            scanner->opt[OPT_GAMMA_VECTOR_R].constraint.range = &gamma_range_8;
3115            scanner->lutlength=2048;
3116            break;
3117      case 1:
3118            scanner->opt[OPT_GAMMA_VECTOR_R].constraint.range = &gamma_range_9;
3119            scanner->lutlength=512;
3120            break;
3121      case 2:
3122            scanner->opt[OPT_GAMMA_VECTOR_R].constraint.range = &gamma_range_10;
3123            scanner->lutlength=1024;
3124            break;
3125      case 3:
3126            scanner->opt[OPT_GAMMA_VECTOR_R].constraint.range = &gamma_range_12;
3127            scanner->lutlength=4096;
3128            break;
3129   }
3130   scanner->opt[OPT_GAMMA_VECTOR_R].size = scanner->lutlength * sizeof (SANE_Word);
3131   scanner->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
3132 
3133   /* green gamma vector */
3134   scanner->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
3135   scanner->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
3136   scanner->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
3137   scanner->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
3138   scanner->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
3139   scanner->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
3140   switch(scanner->LS)
3141   {  case 0:
3142            scanner->opt[OPT_GAMMA_VECTOR_G].constraint.range = &gamma_range_8;
3143            scanner->lutlength=2048;
3144            break;
3145      case 1:
3146            scanner->opt[OPT_GAMMA_VECTOR_G].constraint.range = &gamma_range_9;
3147            scanner->lutlength=512;
3148            break;
3149      case 2:
3150            scanner->opt[OPT_GAMMA_VECTOR_G].constraint.range = &gamma_range_10;
3151            scanner->lutlength=1024;
3152            break;
3153      case 3:
3154            scanner->opt[OPT_GAMMA_VECTOR_G].constraint.range = &gamma_range_12;
3155            scanner->lutlength=4096;
3156            break;
3157   }
3158   scanner->opt[OPT_GAMMA_VECTOR_G].size = scanner->lutlength * sizeof (SANE_Word);
3159   scanner->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
3160 
3161   /* blue gamma vector */
3162   scanner->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
3163   scanner->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
3164   scanner->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
3165   scanner->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
3166   scanner->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
3167   scanner->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
3168   switch(scanner->LS)
3169   {  case 0:
3170            scanner->opt[OPT_GAMMA_VECTOR_B].constraint.range = &gamma_range_8;
3171            scanner->lutlength=2048;
3172            break;
3173      case 1:
3174            scanner->opt[OPT_GAMMA_VECTOR_B].constraint.range = &gamma_range_9;
3175            scanner->lutlength=512;
3176            break;
3177      case 2:
3178            scanner->opt[OPT_GAMMA_VECTOR_B].constraint.range = &gamma_range_10;
3179            scanner->lutlength=1024;
3180            break;
3181      case 3:
3182            scanner->opt[OPT_GAMMA_VECTOR_B].constraint.range = &gamma_range_12;
3183            scanner->lutlength=4096;
3184            break;
3185   }
3186   scanner->opt[OPT_GAMMA_VECTOR_B].size = scanner->lutlength * sizeof (SANE_Word);
3187   scanner->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
3188 
3189 
3190   /* ------------------------------ */
3191 
3192   /* "Advanced" group: */
3193   scanner->opt[OPT_ADVANCED_GROUP].title = "Advanced";
3194   scanner->opt[OPT_ADVANCED_GROUP].desc = "";
3195   scanner->opt[OPT_ADVANCED_GROUP].type = SANE_TYPE_GROUP;
3196   scanner->opt[OPT_ADVANCED_GROUP].cap = SANE_CAP_ADVANCED;
3197   scanner->opt[OPT_ADVANCED_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
3198 
3199   /* preview */
3200   scanner->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
3201   scanner->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
3202   scanner->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
3203   scanner->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
3204 
3205   /* Autofocus */
3206   scanner->opt[OPT_AUTOFOCUS].name = "Autofocus";
3207   scanner->opt[OPT_AUTOFOCUS].title ="Autofocus";
3208   scanner->opt[OPT_AUTOFOCUS].desc = "When to do autofocussing";
3209   scanner->opt[OPT_AUTOFOCUS].type = SANE_TYPE_STRING;
3210   scanner->opt[OPT_AUTOFOCUS].size = max_string_size (autofocus_mode_list);
3211   scanner->opt[OPT_AUTOFOCUS].constraint_type = SANE_CONSTRAINT_STRING_LIST;
3212   scanner->opt[OPT_AUTOFOCUS].constraint.string_list = autofocus_mode_list;
3213 
3214   scanner->opt[OPT_IRED_RED].name = "IRED cor. red";
3215   scanner->opt[OPT_IRED_RED].title ="IRED cor. red";
3216   scanner->opt[OPT_IRED_RED].desc = "Correction of infrared from red";
3217   scanner->opt[OPT_IRED_RED].type = SANE_TYPE_INT;
3218   scanner->opt[OPT_IRED_RED].unit = SANE_UNIT_NONE;
3219   scanner->opt[OPT_IRED_RED].constraint_type = SANE_CONSTRAINT_RANGE;
3220   scanner->opt[OPT_IRED_RED].constraint.range = &gamma_range_8;
3221   scanner->opt[OPT_IRED_RED].cap |= SANE_CAP_ADVANCED;
3222   if(scanner->LS<2)
3223   {  scanner->opt[OPT_IRED_RED].cap |= SANE_CAP_INACTIVE;
3224   }
3225 
3226 
3227 
3228   /*  scanner->opt[OPT_PREVIEW].cap   = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; */
3229   return SANE_STATUS_GOOD;
3230 }
3231 
3232 
3233 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback authorize)3234 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
3235 {
3236   char dev_name[PATH_MAX];
3237   size_t len;
3238   FILE *fp;
3239 
3240   (void) authorize;
3241 
3242   DBG_INIT ();
3243   sanei_thread_init ();
3244 
3245   DBG (10, "sane_init\n");
3246   if (version_code)
3247       *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
3248 
3249   fp = sanei_config_open (COOLSCAN_CONFIG_FILE);
3250   if (!fp)
3251     {
3252       attach_scanner ("/dev/scanner", 0); /* no config-file: /dev/scanner */
3253       return SANE_STATUS_GOOD;
3254     }
3255 
3256   while (sanei_config_read (dev_name, sizeof (dev_name), fp))
3257     {
3258       if (dev_name[0] == '#')
3259 	continue;		/* ignore line comments */
3260       len = strlen (dev_name);
3261 
3262       if (!len)
3263 	continue;		/* ignore empty lines */
3264 
3265       sanei_config_attach_matching_devices (dev_name, attach_one);
3266       /*attach_scanner (dev_name, 0);*/
3267     }
3268   fclose (fp);
3269   return SANE_STATUS_GOOD;
3270 }
3271 
3272 void
sane_exit(void)3273 sane_exit (void)
3274 {
3275   Coolscan_t *dev, *next;
3276 
3277   DBG (10, "sane_exit\n");
3278 
3279   for (dev = first_dev; dev; dev = next)
3280     {
3281       next = dev->next;
3282       free (dev->devicename);
3283       free (dev->buffer);
3284       free (dev->obuffer);
3285       free (dev);
3286     }
3287 
3288   if (devlist)
3289     free (devlist);
3290 }
3291 
3292 /* ----------------------------- SANE GET DEVICES -------------------------- */
3293 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)3294 sane_get_devices (const SANE_Device *** device_list,
3295 		  SANE_Bool local_only)
3296 {
3297   Coolscan_t *dev;
3298   int i;
3299 
3300   (void) local_only;
3301 
3302   DBG (10, "sane_get_devices\n");
3303 
3304   if (devlist)
3305     free (devlist);
3306 
3307   devlist = calloc (num_devices + 1, sizeof (devlist[0]));
3308   if (!devlist)
3309     return SANE_STATUS_NO_MEM;
3310 
3311   i = 0;
3312 
3313   for (dev = first_dev; i < num_devices; dev = dev->next)
3314     devlist[i++] = &dev->sane;
3315 
3316   devlist[i++] = 0;
3317 
3318   *device_list = devlist;
3319 
3320   return SANE_STATUS_GOOD;
3321 }
3322 
3323 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)3324 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
3325 {
3326   Coolscan_t *dev;
3327   SANE_Status status;
3328 
3329   DBG (10, "sane_open\n");
3330 
3331   if (devicename[0])
3332     {				/* search for devicename */
3333       for (dev = first_dev; dev; dev = dev->next)
3334 	{
3335 	  if (strcmp (dev->sane.name, devicename) == 0)
3336 	    {
3337 	      break;
3338 	    }
3339 	}
3340 
3341       if (!dev)
3342 	{
3343 	  status = attach_scanner (devicename, &dev);
3344 	  if (status != SANE_STATUS_GOOD)
3345 	    {
3346 	      return status;
3347 	    }
3348 	}
3349     }
3350   else
3351     {
3352       dev = first_dev;		/* empty devicname -> use first device */
3353     }
3354 
3355   if (!dev)
3356     return SANE_STATUS_INVAL;
3357 
3358   dev->sfd = -1;
3359   dev->pipe = -1;
3360   dev->scanning = SANE_FALSE;
3361 
3362   init_options (dev);
3363   *handle = dev;
3364   return SANE_STATUS_GOOD;
3365 }
3366 
3367 void
sane_close(SANE_Handle handle)3368 sane_close (SANE_Handle handle)
3369 {
3370   DBG (10, "sane_close\n");
3371   if (((Coolscan_t *) handle)->scanning)
3372     do_cancel (handle);
3373 }
3374 
3375 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)3376 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
3377 {
3378   Coolscan_t *scanner = handle;
3379 
3380   DBG (10, "sane_get_option_descriptor %d\n", option);
3381 
3382   if ((unsigned) option >= NUM_OPTIONS)
3383     return 0;
3384   return &scanner->opt[option];
3385 }
3386 
3387 /*
3388    static void
3389    worddump(char *comment, SANE_Word * p, int l)
3390    {
3391    int i;
3392    char line[128];
3393    char *ptr;
3394 
3395    DBG (5, "%s\n", comment);
3396    ptr = line;
3397    for (i = 0; i < l; i++, p++)
3398    {
3399    if ((i % 8) == 0)
3400    {
3401    if (ptr != line)
3402    {
3403    *ptr = '\0';
3404    DBG (5, "%s\n", line);
3405    ptr = line;
3406    }
3407    sprintf (ptr, "%3.3d:", i);
3408    ptr += 4;
3409    }
3410    sprintf (ptr, " %4.4d", *p);
3411    ptr += 5;
3412    }
3413    *ptr = '\0';
3414    DBG (5, "%s\n", line);
3415    }
3416  */
3417 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)3418 sane_control_option (SANE_Handle handle, SANE_Int option,
3419 		     SANE_Action action, void *val,
3420 		     SANE_Int * info)
3421 {
3422   Coolscan_t *scanner = handle;
3423   SANE_Status status;
3424   SANE_Word cap;
3425 
3426   if (info)
3427     *info = 0;
3428 
3429   if (scanner->scanning)
3430     return SANE_STATUS_DEVICE_BUSY;
3431 
3432   if (option >= NUM_OPTIONS)
3433     return SANE_STATUS_INVAL;
3434 
3435   cap = scanner->opt[option].cap;
3436 
3437 
3438   if (action == SANE_ACTION_GET_VALUE)
3439     {
3440       DBG (10, "sane_control_option %d, get value\n", option);
3441       switch (option)
3442 	{
3443 	  /* word options: */
3444 	case OPT_TL_X:
3445 	  *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->tlx));
3446 	  return SANE_STATUS_GOOD;
3447 
3448 	case OPT_TL_Y:
3449 	  *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->tly));
3450 	  return SANE_STATUS_GOOD;
3451 
3452 	case OPT_BR_X:
3453 	  *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->brx));
3454 	  return SANE_STATUS_GOOD;
3455 
3456 	case OPT_BR_Y:
3457 	  *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->bry));
3458 	  return SANE_STATUS_GOOD;
3459 
3460 	case OPT_PREVIEW:
3461 	  *(SANE_Word *) val = scanner->preview;
3462 	  return SANE_STATUS_GOOD;
3463 
3464 	case OPT_AUTOFOCUS:
3465 	  switch(scanner->autofocus)
3466 	    {  case AF_NEVER: strcpy (val,neverStr);
3467   	                 break;
3468 	       case AF_PREVIEW:strcpy (val,previewStr);
3469   	                 break;
3470                case AF_SCAN:if(scanner->LS>=2) strcpy (val,scanStr);
3471   	                 break;
3472 	       case AF_PREANDSCAN:if(scanner->LS>=2) strcpy (val,preandscanStr);
3473   	                 break;
3474 	    }
3475 	  return SANE_STATUS_GOOD;
3476 
3477 	case OPT_NUM_OPTS:
3478 	  *(SANE_Word *) val = NUM_OPTIONS;
3479 	  return SANE_STATUS_GOOD;
3480 
3481 	case OPT_RESOLUTION:
3482 	  *(SANE_Word *) val = resDivToVal (scanner->x_nres);
3483 	  return SANE_STATUS_GOOD;
3484 
3485 	case OPT_PREVIEW_RESOLUTION:
3486 	  *(SANE_Word *) val = resDivToVal (scanner->x_p_nres);
3487 	  return SANE_STATUS_GOOD;
3488 
3489 	case OPT_BIT_DEPTH:
3490 	  *(SANE_Word *) val = scanner->bits_per_color;
3491 	  return SANE_STATUS_GOOD;
3492 
3493 	case OPT_CONTRAST:
3494 	  *(SANE_Word *) val = scanner->contrast - 128;
3495 	  return SANE_STATUS_GOOD;
3496 
3497 	case OPT_R_CONTRAST:
3498 	  *(SANE_Word *) val = scanner->contrast_R - 128;
3499 	  return SANE_STATUS_GOOD;
3500 
3501 	case OPT_G_CONTRAST:
3502 	  *(SANE_Word *) val = scanner->contrast_G - 128;
3503 	  return SANE_STATUS_GOOD;
3504 
3505 	case OPT_B_CONTRAST:
3506 	  *(SANE_Word *) val = scanner->contrast_B - 128;
3507 	  return SANE_STATUS_GOOD;
3508 
3509 	case OPT_BRIGHTNESS:
3510 	  *(SANE_Word *) val = scanner->brightness - 128;
3511 	  return SANE_STATUS_GOOD;
3512 
3513 	case OPT_R_BRIGHTNESS:
3514 	  *(SANE_Word *) val = scanner->brightness_R - 128;
3515 	  return SANE_STATUS_GOOD;
3516 
3517 	case OPT_G_BRIGHTNESS:
3518 	  *(SANE_Word *) val = scanner->brightness_G - 128;
3519 	  return SANE_STATUS_GOOD;
3520 
3521 	case OPT_B_BRIGHTNESS:
3522 	  *(SANE_Word *) val = scanner->brightness_B - 128;
3523 	  return SANE_STATUS_GOOD;
3524 
3525 	case OPT_EXPOSURE:
3526 	  *(SANE_Word *) val = scanner->exposure_R * 2;
3527 	  return SANE_STATUS_GOOD;
3528 
3529 	case OPT_R_EXPOSURE:
3530 	  *(SANE_Word *) val = scanner->exposure_R * 2;
3531 	  return SANE_STATUS_GOOD;
3532 
3533 	case OPT_G_EXPOSURE:
3534 	  *(SANE_Word *) val = scanner->exposure_G * 2;
3535 	  return SANE_STATUS_GOOD;
3536 
3537 	case OPT_B_EXPOSURE:
3538 	  *(SANE_Word *) val = scanner->exposure_B * 2;
3539 	  return SANE_STATUS_GOOD;
3540 
3541 	case OPT_R_SHIFT:
3542 	  *(SANE_Word *) val = scanner->shift_R - 128;
3543 	  return SANE_STATUS_GOOD;
3544 
3545 	case OPT_G_SHIFT:
3546 	  *(SANE_Word *) val = scanner->shift_G - 128;
3547 	  return SANE_STATUS_GOOD;
3548 
3549 	case OPT_B_SHIFT:
3550 	  *(SANE_Word *) val = scanner->shift_B - 128;
3551 	  return SANE_STATUS_GOOD;
3552 
3553 
3554 	case OPT_IRED_RED:
3555 	  *(SANE_Word *) val = scanner->ired_red;
3556 	  return SANE_STATUS_GOOD;
3557 
3558 	  /* string options: */
3559 	case OPT_TYPE:
3560 	  strcpy (val, ((scanner->negative) ? negativeStr : positiveStr));
3561 	  return SANE_STATUS_GOOD;
3562 
3563 	case OPT_MODE:
3564 	  switch(scanner->colormode)
3565 	    {  case RGB: strcpy (val,colorStr);
3566   	                 break;
3567 	       case GREYSCALE:strcpy (val,grayStr);
3568   	                 break;
3569                case RGBI:if(scanner->LS>=2) strcpy (val,rgbiStr);
3570 		         else strcpy (val,colorStr);
3571   	                 break;
3572 	       case IRED:if(scanner->LS>=2) strcpy (val,iredStr);
3573 	                 else strcpy (val,grayStr);
3574   	                 break;
3575 	    }
3576  	    if (info)
3577 	    {
3578 	      *info |= SANE_INFO_RELOAD_PARAMS;
3579 	    }
3580 
3581 	  return SANE_STATUS_GOOD;
3582 
3583 	case OPT_PRESCAN:
3584 	  *(SANE_Word *) val = (scanner->prescan) ? SANE_TRUE : SANE_FALSE;
3585 	  return SANE_STATUS_GOOD;
3586 
3587 	case OPT_PRESCAN_NOW:
3588 	  return SANE_STATUS_GOOD;
3589 
3590 	case OPT_RGB_CONTROL:
3591 	  *(SANE_Word *) val = (scanner->rgb_control) ? SANE_TRUE : SANE_FALSE;
3592 	  return SANE_STATUS_GOOD;
3593 
3594 	case OPT_GAMMA_BIND:
3595 	  *(SANE_Word *) val = (scanner->gamma_bind) ? SANE_TRUE : SANE_FALSE;
3596 	  return SANE_STATUS_GOOD;
3597 
3598 	case OPT_ANALOG_GAMMA:
3599 	  *(SANE_Word *) val =
3600 	    (scanner->analog_gamma_r) ? SANE_TRUE : SANE_FALSE;
3601 	  return SANE_STATUS_GOOD;
3602 
3603 	case OPT_AVERAGING:
3604 	  *(SANE_Word *) val = (scanner->averaging) ? SANE_TRUE : SANE_FALSE;
3605 	  return SANE_STATUS_GOOD;
3606 
3607 	case OPT_GAMMA_VECTOR:
3608 	  memcpy (val, scanner->gamma, scanner->opt[option].size);
3609 	  return SANE_STATUS_GOOD;
3610 	case OPT_GAMMA_VECTOR_R:
3611 	  memcpy (val, scanner->gamma_r, scanner->opt[option].size);
3612 	  return SANE_STATUS_GOOD;
3613 	case OPT_GAMMA_VECTOR_G:
3614 	  memcpy (val, scanner->gamma_g, scanner->opt[option].size);
3615 	  return SANE_STATUS_GOOD;
3616 	case OPT_GAMMA_VECTOR_B:
3617 	  memcpy (val, scanner->gamma_b, scanner->opt[option].size);
3618 	  return SANE_STATUS_GOOD;
3619 
3620 	case OPT_SOURCE:
3621 	  if (strcmp (val, "Automatic Slide Feeder") == 0)
3622 	    {
3623 	      /* Feed/Discharge/update filename/etc */
3624 	    }
3625 	  else
3626 	    {
3627 	      /* Reset above */
3628 	    }
3629 	  if (info)
3630 	    {
3631 	      *info |= SANE_INFO_RELOAD_PARAMS;
3632 	    }
3633 	}
3634 
3635     }
3636   else if (action == SANE_ACTION_SET_VALUE)
3637     {
3638       DBG (10, "sane_control_option %d, set value\n", option);
3639 
3640       if (!SANE_OPTION_IS_ACTIVE (cap))
3641 	return SANE_STATUS_INVAL;
3642 
3643       if (!SANE_OPTION_IS_SETTABLE (cap))
3644 	return SANE_STATUS_INVAL;
3645 
3646       status = sanei_constrain_value (scanner->opt + option, val, info);
3647       if (status != SANE_STATUS_GOOD)
3648 	return status;
3649 
3650       switch (option)
3651 	{
3652 	case OPT_GAMMA_BIND:
3653 	  scanner->gamma_bind = (*(SANE_Word *) val == SANE_TRUE);
3654 	  if (scanner->LS != 1)
3655 	    {
3656 	      if (scanner->gamma_bind)
3657 		{
3658 		  scanner->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
3659 		  scanner->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
3660 		  scanner->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
3661 		  scanner->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
3662 
3663 		}
3664 	      else
3665 		{
3666 		  scanner->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
3667 		  scanner->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
3668 		  scanner->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
3669 		  scanner->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
3670 
3671 		}
3672 	    }
3673 	  if (info)
3674 	    {
3675 	      *info |= SANE_INFO_RELOAD_OPTIONS;
3676 	    }
3677 	  return SANE_STATUS_GOOD;
3678 
3679 	case OPT_ANALOG_GAMMA:
3680 	  scanner->analog_gamma_r = scanner->analog_gamma_g =
3681 	    scanner->analog_gamma_b = (*(SANE_Word *) val == SANE_TRUE);
3682 	  return SANE_STATUS_GOOD;
3683 
3684 	case OPT_AVERAGING:
3685 	  scanner->averaging = (*(SANE_Word *) val == SANE_TRUE);
3686 	  return SANE_STATUS_GOOD;
3687 
3688 	case OPT_PRESCAN:
3689 	  scanner->prescan = (*(SANE_Word *) val == SANE_TRUE);
3690 	  return SANE_STATUS_GOOD;
3691 
3692 	case OPT_PRESCAN_NOW:
3693 	   do_prescan_now(scanner);
3694 	  return SANE_STATUS_GOOD;
3695 
3696 	case OPT_BIT_DEPTH:
3697 	   scanner->bits_per_color=(*(SANE_Word *)val);
3698  	  if (info)
3699 	    *info |= SANE_INFO_RELOAD_PARAMS;
3700 	  return SANE_STATUS_GOOD;
3701 
3702 
3703 	case OPT_RGB_CONTROL:
3704 	  scanner->rgb_control = (*(SANE_Word *) val == SANE_TRUE);
3705 	  if (scanner->rgb_control)
3706 	    {
3707 	      scanner->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
3708 	      scanner->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
3709 	      scanner->opt[OPT_EXPOSURE].cap |= SANE_CAP_INACTIVE;
3710 
3711 	      scanner->opt[OPT_R_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
3712 	      scanner->opt[OPT_G_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
3713 	      scanner->opt[OPT_B_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
3714 
3715 	      scanner->opt[OPT_R_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
3716 	      scanner->opt[OPT_G_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
3717 	      scanner->opt[OPT_B_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
3718 
3719 	      scanner->opt[OPT_R_EXPOSURE].cap &= ~SANE_CAP_INACTIVE;
3720 	      scanner->opt[OPT_G_EXPOSURE].cap &= ~SANE_CAP_INACTIVE;
3721 	      scanner->opt[OPT_B_EXPOSURE].cap &= ~SANE_CAP_INACTIVE;
3722 
3723 	      scanner->contrast_R = 128;
3724 	      scanner->contrast_G = 128;
3725 	      scanner->contrast_B = 128;
3726 	      scanner->brightness_R = 128;
3727 	      scanner->brightness_G = 128;
3728 	      scanner->brightness_B = 128;
3729 	      scanner->exposure_R = 50;
3730 	      scanner->exposure_G = 50;
3731 	      scanner->exposure_B = 50;
3732 	    }
3733 	  else
3734 	    {
3735 	      scanner->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
3736 	      scanner->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
3737 	      scanner->opt[OPT_EXPOSURE].cap &= ~SANE_CAP_INACTIVE;
3738 
3739 	      scanner->contrast = 128;
3740 	      scanner->brightness = 128;
3741 	      scanner->exposure_R = 50;
3742 	      scanner->exposure_G = 50;
3743 	      scanner->exposure_B = 50;
3744 
3745 	      scanner->opt[OPT_R_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
3746 	      scanner->opt[OPT_G_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
3747 	      scanner->opt[OPT_B_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
3748 
3749 	      scanner->opt[OPT_R_CONTRAST].cap |= SANE_CAP_INACTIVE;
3750 	      scanner->opt[OPT_G_CONTRAST].cap |= SANE_CAP_INACTIVE;
3751 	      scanner->opt[OPT_B_CONTRAST].cap |= SANE_CAP_INACTIVE;
3752 
3753 	      scanner->opt[OPT_R_EXPOSURE].cap |= SANE_CAP_INACTIVE;
3754 	      scanner->opt[OPT_G_EXPOSURE].cap |= SANE_CAP_INACTIVE;
3755 	      scanner->opt[OPT_B_EXPOSURE].cap |= SANE_CAP_INACTIVE;
3756 	    }
3757 	  if (info)
3758 	    {
3759 	      *info |= SANE_INFO_RELOAD_OPTIONS;
3760 	    }
3761 	  return SANE_STATUS_GOOD;
3762 
3763 	case OPT_RESOLUTION:
3764 	  scanner->y_nres = scanner->x_nres =
3765 	    resValToDiv (*(SANE_Word *) val);
3766 
3767 	  if (info)
3768 	    *info |= SANE_INFO_RELOAD_PARAMS;
3769 	  return SANE_STATUS_GOOD;
3770 
3771 	case OPT_PREVIEW_RESOLUTION:
3772 	  scanner->y_p_nres = scanner->x_p_nres =
3773 	    resValToDiv (*(SANE_Word *) val);
3774 
3775 	  if (info)
3776 	    *info |= SANE_INFO_RELOAD_PARAMS;
3777 	  return SANE_STATUS_GOOD;
3778 
3779 	case OPT_TL_X:
3780 	  scanner->tlx = mmToIlu (SANE_UNFIX (*(SANE_Word *) val));
3781 	  if (info)
3782 	    *info |= SANE_INFO_RELOAD_PARAMS;
3783 
3784 	  return SANE_STATUS_GOOD;
3785 
3786 	case OPT_TL_Y:
3787 	  scanner->tly = mmToIlu (SANE_UNFIX (*(SANE_Word *) val));
3788 	  if (info)
3789 	    *info |= SANE_INFO_RELOAD_PARAMS;
3790 	  return SANE_STATUS_GOOD;
3791 
3792 	case OPT_BR_X:
3793 	  scanner->brx = mmToIlu (SANE_UNFIX (*(SANE_Word *) val));
3794 	  if (info)
3795 	    *info |= SANE_INFO_RELOAD_PARAMS;
3796 	  return SANE_STATUS_GOOD;
3797 
3798 	case OPT_BR_Y:
3799 	  scanner->bry = mmToIlu (SANE_UNFIX (*(SANE_Word *) val));
3800 	  if (info)
3801 	    *info |= SANE_INFO_RELOAD_PARAMS;
3802 	  return SANE_STATUS_GOOD;
3803 
3804 	case OPT_NUM_OPTS:
3805 	  return SANE_STATUS_GOOD;
3806 
3807 	case OPT_PREVIEW:
3808 	  scanner->preview = *(SANE_Word *) val;
3809 	  return SANE_STATUS_GOOD;
3810 
3811 	case OPT_AUTOFOCUS:
3812 	  if(strcmp(val,neverStr)==0)
3813 	    {    scanner->autofocus=AF_NEVER;
3814 	    }
3815 	  if(strcmp(val,previewStr)==0)
3816 	    {    scanner->autofocus=AF_PREVIEW;
3817 	    }
3818 	  if(strcmp(val,scanStr)==0)
3819 	    {    scanner->autofocus=AF_SCAN;
3820 	    }
3821 	  if(strcmp(val,preandscanStr)==0)
3822 	    {    scanner->autofocus=AF_PREANDSCAN;;
3823 	    }
3824 	  return SANE_STATUS_GOOD;
3825 
3826 	case OPT_CONTRAST:
3827 	  scanner->contrast = *(SANE_Word *) val + 128;
3828 	  return SANE_STATUS_GOOD;
3829 	case OPT_R_CONTRAST:
3830 	  scanner->contrast_R = *(SANE_Word *) val + 128;
3831 	  return SANE_STATUS_GOOD;
3832 	case OPT_G_CONTRAST:
3833 	  scanner->contrast_G = *(SANE_Word *) val + 128;
3834 	  return SANE_STATUS_GOOD;
3835 	case OPT_B_CONTRAST:
3836 	  scanner->contrast_B = *(SANE_Word *) val + 128;
3837 	  return SANE_STATUS_GOOD;
3838 
3839 	case OPT_BRIGHTNESS:
3840 	  scanner->brightness = *(SANE_Word *) val + 128;
3841 	  return SANE_STATUS_GOOD;
3842 	case OPT_R_BRIGHTNESS:
3843 	  scanner->brightness_R = *(SANE_Word *) val + 128;
3844 	  return SANE_STATUS_GOOD;
3845 	case OPT_G_BRIGHTNESS:
3846 	  scanner->brightness_G = *(SANE_Word *) val + 128;
3847 	  return SANE_STATUS_GOOD;
3848 	case OPT_B_BRIGHTNESS:
3849 	  scanner->brightness_B = *(SANE_Word *) val + 128;
3850 	  return SANE_STATUS_GOOD;
3851 
3852 	case OPT_EXPOSURE:
3853 	  scanner->exposure_R = *(SANE_Word *) val / 2;
3854 	  scanner->exposure_G = *(SANE_Word *) val / 2;
3855 	  scanner->exposure_B = *(SANE_Word *) val / 2;
3856 	  return SANE_STATUS_GOOD;
3857 	case OPT_R_EXPOSURE:
3858 	  scanner->exposure_R = *(SANE_Word *) val / 2;
3859 	  return SANE_STATUS_GOOD;
3860 	case OPT_G_EXPOSURE:
3861 	  scanner->exposure_G = *(SANE_Word *) val / 2;
3862 	  return SANE_STATUS_GOOD;
3863 	case OPT_B_EXPOSURE:
3864 	  scanner->exposure_B = *(SANE_Word *) val / 2;
3865 	  return SANE_STATUS_GOOD;
3866 
3867 	case OPT_R_SHIFT:
3868 	  scanner->shift_R = *(SANE_Word *) val + 128;
3869 	  return SANE_STATUS_GOOD;
3870 	case OPT_G_SHIFT:
3871 	  scanner->shift_G = *(SANE_Word *) val + 128;
3872 	  return SANE_STATUS_GOOD;
3873 	case OPT_B_SHIFT:
3874 	  scanner->shift_B = *(SANE_Word *) val + 128;
3875 	  return SANE_STATUS_GOOD;
3876 
3877 	case OPT_IRED_RED:
3878 	  scanner->ired_red= *(SANE_Word *) val;
3879 	  return SANE_STATUS_GOOD;
3880 
3881 	case OPT_SOURCE:
3882 	  scanner->asf = (strcmp (val, "Automatic...") == 0);
3883 	  return SANE_STATUS_GOOD;
3884 
3885 	case OPT_TYPE:
3886 	  scanner->negative = (strcmp (val, negativeStr) == 0);
3887 	  if (info)
3888 	    {
3889 	      *info |= SANE_INFO_RELOAD_PARAMS;
3890 	    }
3891 	  return SANE_STATUS_GOOD;
3892 	case OPT_MODE:
3893 	  if(strcmp(val,colorStr)==0)
3894 	    {    scanner->colormode=RGB;
3895 	         scanner->colormode_p=RGB;
3896 	    }
3897 	  if(strcmp(val,grayStr)==0)
3898 	    {    scanner->colormode=GREYSCALE;
3899 	         scanner->colormode_p=GREYSCALE;
3900 	    }
3901 	  if(strcmp(val,rgbiStr)==0)
3902 	    {    scanner->colormode=RGBI;
3903 	         scanner->colormode_p=RGB;
3904 	    }
3905 	  if(strcmp(val,iredStr)==0)
3906 	    {    scanner->colormode=IRED;
3907 	         scanner->colormode_p=GREYSCALE;
3908 	    }
3909 	  if (info)
3910 	    {
3911 	      *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
3912 	    }
3913 	  return SANE_STATUS_GOOD;
3914 
3915 	case OPT_GAMMA_VECTOR:
3916 	  memcpy (scanner->gamma, val, scanner->opt[option].size);
3917 	  if(scanner->LS>2)  Calc_fix_LUT(scanner);
3918 	  return SANE_STATUS_GOOD;
3919 
3920 	case OPT_GAMMA_VECTOR_R:
3921 	  memcpy (scanner->gamma_r, val, scanner->opt[option].size);
3922 	  if(scanner->LS>2)  Calc_fix_LUT(scanner);
3923 	  return SANE_STATUS_GOOD;
3924 
3925 	case OPT_GAMMA_VECTOR_G:
3926 	  memcpy (scanner->gamma_g, val, scanner->opt[option].size);
3927 	  if(scanner->LS>2)  Calc_fix_LUT(scanner);
3928 	  return SANE_STATUS_GOOD;
3929 
3930 	case OPT_GAMMA_VECTOR_B:
3931 	  memcpy (scanner->gamma_b, val, scanner->opt[option].size);
3932 	  if(scanner->LS>2)  Calc_fix_LUT(scanner);
3933 	  return SANE_STATUS_GOOD;
3934 
3935 	}			/* switch */
3936     }				/* else */
3937   return SANE_STATUS_INVAL;
3938 }
3939 
3940 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)3941 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
3942 {
3943   Coolscan_t *scanner = handle;
3944 
3945   DBG (10, "sane_get_parameters");
3946   switch(scanner->colormode)
3947     {  case RGB:
3948               params->format =  SANE_FRAME_RGB;
3949               break;
3950 #ifdef HAS_IRED
3951        case RGBI:
3952               params->format =  SANE_FRAME_RGBA;
3953               break;
3954 #endif /* HAS_RGBI */
3955        case GREYSCALE:
3956               params->format =  SANE_FRAME_GRAY;
3957               break;
3958     }
3959 
3960   params->depth = scanner->bits_per_color>8?16:8;
3961   params->pixels_per_line = pixels_per_line (scanner);
3962   params->lines = lines_per_scan (scanner);
3963   params->bytes_per_line = write_bytes_per_line (scanner);
3964   params->last_frame = 1;
3965   return SANE_STATUS_GOOD;
3966 }
3967 static int
swap_res(Coolscan_t * s)3968 swap_res (Coolscan_t * s)
3969 {
3970   if (s->preview)
3971     {
3972       /* swap preview/scan resolutions */
3973       int xres, yres, cmode;
3974       xres = s->x_nres;
3975       yres = s->y_nres;
3976       s->x_nres = s->x_p_nres;
3977       s->y_nres = s->y_p_nres;
3978 
3979       s->x_p_nres = xres;
3980       s->y_p_nres = yres;
3981       cmode=s->colormode;
3982       s->colormode=s->colormode_p;
3983       s->colormode_p=cmode;
3984     }
3985   return 0;
3986 }
3987 SANE_Status
sane_start(SANE_Handle handle)3988 sane_start (SANE_Handle handle)
3989 {
3990   Coolscan_t *scanner = handle;
3991   int fds[2];
3992 
3993   DBG (10, "sane_start\n");
3994   if (scanner->scanning == SANE_TRUE)
3995     return SANE_STATUS_DEVICE_BUSY;
3996 
3997   if (scanner->sfd < 0)
3998     {				/* first call */
3999       if (sanei_scsi_open (scanner->sane.name,
4000 			   &(scanner->sfd),
4001 			   sense_handler, 0) != SANE_STATUS_GOOD)
4002 	{
4003 	  DBG (1, "sane_start: open of %s failed:\n",
4004 	       scanner->sane.name);
4005 	  return SANE_STATUS_INVAL;
4006 	}
4007     }
4008   scanner->scanning = SANE_TRUE;
4009 
4010 
4011   if (coolscan_check_values (scanner) != 0)
4012     {				/* Verify values */
4013       DBG (1, "ERROR: invalid scan-values\n");
4014       scanner->scanning = SANE_FALSE;
4015       coolscan_give_scanner (scanner);
4016       sanei_scsi_close (scanner->sfd);
4017       scanner->sfd = -1;
4018       return SANE_STATUS_INVAL;
4019     }
4020 
4021   if (coolscan_grab_scanner (scanner))
4022     {
4023       sanei_scsi_close (scanner->sfd);
4024       scanner->sfd = -1;
4025       DBG (5, "WARNING: unable to reserve scanner: device busy\n");
4026       scanner->scanning = SANE_FALSE;
4027       return SANE_STATUS_DEVICE_BUSY;
4028     }
4029 
4030   /* hoho, step 2c, -perm */
4031   coolscan_object_feed (scanner);
4032 
4033   swap_res (scanner);
4034   if (!scanner->preview)
4035   { if(scanner->autofocus & 0x02)
4036     {  coolscan_autofocus (scanner);
4037     }
4038   }
4039   else
4040     {
4041       if(scanner->autofocus & 0x01)
4042       {  coolscan_autofocus (scanner);
4043       }
4044       if (scanner->prescan) {
4045 	prescan (scanner);
4046 	if(scanner->LS<2)
4047         {	get_internal_info(scanner);
4048 	}
4049         coolscan_get_window_param (scanner,1);
4050       }
4051     }
4052   /*read_LUT(scanner); */
4053   if(scanner->LS<2)
4054   {  send_LUT (scanner);
4055      coolscan_set_window_param (scanner, 0);
4056      coolscan_get_window_param (scanner,0);
4057      coolscan_start_scan (scanner);
4058   }
4059   else
4060   {  coolscan_set_window_param (scanner, 0);
4061      send_LUT (scanner);
4062      Calc_fix_LUT(scanner);
4063      coolscan_start_scan (scanner);
4064      wait_scanner (scanner);
4065      coolscan_get_window_param (scanner,0);
4066   }
4067 
4068   DBG (10, "bytes per line        = %d\n", scan_bytes_per_line (scanner));
4069   DBG (10, "pixels_per_line       = %d\n", pixels_per_line (scanner));
4070   DBG (10, "lines                 = %d\n", lines_per_scan (scanner));
4071   DBG (10, "negative              = %d\n", scanner->negative);
4072   DBG (10, "brightness (halftone) = %d\n", scanner->brightness);
4073   DBG (10, "contrast   (halftone) = %d\n", scanner->contrast);
4074   DBG (10, "fast preview function = %d\n", scanner->preview);
4075 
4076   /* create a pipe, fds[0]=read-fd, fds[1]=write-fd */
4077   if (pipe (fds) < 0)
4078     {
4079       DBG (1, "ERROR: could not create pipe\n");
4080 
4081       swap_res (scanner);
4082       scanner->scanning = SANE_FALSE;
4083       coolscan_give_scanner (scanner);
4084       sanei_scsi_close (scanner->sfd);
4085       scanner->sfd = -1;
4086       return SANE_STATUS_IO_ERROR;
4087     }
4088 
4089   scanner->pipe       = fds[0];
4090   scanner->reader_fds = fds[1];
4091   scanner->reader_pid = sanei_thread_begin( reader_process, (void*)scanner );
4092   if (!sanei_thread_is_valid (scanner->reader_pid))
4093     {
4094       DBG (1, "sane_start: sanei_thread_begin failed (%s)\n",
4095              strerror (errno));
4096       return SANE_STATUS_NO_MEM;
4097     }
4098 
4099   if (sanei_thread_is_forked ())
4100     {
4101       close (scanner->reader_fds);
4102       scanner->reader_fds = -1;
4103     }
4104 
4105   return SANE_STATUS_GOOD;
4106 }
4107 
4108 
4109 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)4110 sane_read (SANE_Handle handle, SANE_Byte * buf,
4111 	   SANE_Int max_len, SANE_Int * len)
4112 {
4113   Coolscan_t *scanner = handle;
4114   ssize_t nread;
4115 
4116   *len = 0;
4117 
4118   nread = read (scanner->pipe, buf, max_len);
4119   DBG (10, "sane_read: read %ld bytes\n", (long) nread);
4120 
4121   if (!(scanner->scanning))
4122     {
4123       return do_cancel (scanner);
4124     }
4125 
4126   if (nread < 0)
4127     {
4128       if (errno == EAGAIN)
4129 	{
4130 	  return SANE_STATUS_GOOD;
4131 	}
4132       else
4133 	{
4134 	  do_cancel (scanner);
4135 	  return SANE_STATUS_IO_ERROR;
4136 	}
4137     }
4138 
4139   *len = nread;
4140 
4141   if (nread == 0)
4142     return do_eof (scanner);	/* close pipe */
4143 
4144   return SANE_STATUS_GOOD;
4145 }
4146 
4147 void
sane_cancel(SANE_Handle handle)4148 sane_cancel (SANE_Handle handle)
4149 {
4150   Coolscan_t *s = handle;
4151 
4152   if (sanei_thread_is_valid (s->reader_pid))
4153     {
4154       sanei_thread_kill   ( s->reader_pid );
4155       sanei_thread_waitpid( s->reader_pid, NULL );
4156       sanei_thread_invalidate (s->reader_pid);
4157     }
4158   swap_res (s);
4159   s->scanning = SANE_FALSE;
4160 }
4161 
4162 
4163 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)4164 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
4165 {
4166   Coolscan_t *scanner = handle;
4167 
4168   DBG (10, "sane_set_io_mode: non_blocking=%d\n", non_blocking);
4169 
4170   if (!scanner->scanning)
4171     return SANE_STATUS_INVAL;
4172 
4173   if (fcntl (scanner->pipe, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0)
4174     return SANE_STATUS_IO_ERROR;
4175 
4176   return SANE_STATUS_GOOD;
4177 }
4178 
4179 SANE_Status
sane_get_select_fd(SANE_Handle handle,SANE_Int * fd)4180 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
4181 {
4182   Coolscan_t *scanner = handle;
4183 
4184   DBG (10, "sane_get_select_fd\n");
4185 
4186   if (!scanner->scanning)
4187     {
4188       return SANE_STATUS_INVAL;
4189     }
4190   *fd = scanner->pipe;
4191 
4192   return SANE_STATUS_GOOD;
4193 }
4194