• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* sane - Scanner Access Now Easy.
2 
3    This file (C) 1997 Ingo Schneider
4              (C) 1998 Karl Anders Øygard
5 
6    This file is part of the SANE package.
7 
8    SANE is free software; you can redistribute it and/or modify it under
9    the terms of the GNU General Public License as published by the Free
10    Software Foundation; either version 2 of the License, or (at your
11    option) any later version.
12 
13    SANE is distributed in the hope that it will be useful, but WITHOUT
14    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16    for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with sane; see the file COPYING.
20    If not, see <https://www.gnu.org/licenses/>.
21 
22    This file implements a SANE backend for AGFA Focus flatbed scanners.  */
23 
24 #include "../include/sane/config.h"
25 
26 #include <signal.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <sys/types.h>
33 
34 #include "../include/sane/sane.h"
35 #include "../include/sane/sanei.h"
36 #include "../include/sane/sanei_config.h"
37 #include "../include/sane/saneopts.h"
38 #include "../include/sane/sanei_scsi.h"
39 #include "../include/sane/sanei_thread.h"
40 
41 #define BACKEND_NAME	agfafocus
42 #include "../include/sane/sanei_backend.h"
43 
44 #include "agfafocus.h"
45 
46 #ifndef PATH_MAX
47 # define PATH_MAX	1024
48 #endif
49 
50 
51 #undef Byte
52 #define Byte SANE_Byte
53 
54 static const SANE_Device **devlist = 0;
55 static int num_devices;
56 static AgfaFocus_Device *agfafocus_devices;
57 
58 static const SANE_String_Const focus_mode_list[] =
59 {
60   "Lineart", "Gray (6 bit)",
61   0
62 };
63 
64 static const SANE_String_Const focusii_mode_list[] =
65 {
66   "Lineart", "Gray (6 bit)", "Gray (8 bit)",
67   0
68 };
69 
70 static const SANE_String_Const focuscolor_mode_list[] =
71 {
72   "Lineart", "Gray (6 bit)", "Gray (8 bit)", "Color (18 bit)", "Color (24 bit)",
73   0
74 };
75 
76 static const SANE_String_Const halftone_list[] =
77 {
78   "None", "Dispersed dot 4x4", "Round (Clustered dot 4x4)", "Diamond (Clustered dot 4x4)",
79   0
80 };
81 
82 static const SANE_String_Const halftone_upload_list[] =
83 {
84   "None", "Dispersed dot 4x4", "Round (Clustered dot 4x4)", "Diamond (Clustered dot 4x4)",
85   0
86 };
87 
88 static const SANE_String_Const source_list[] =
89 {
90   "Opaque/Normal", "Transparency",
91   0
92 };
93 
94 static const SANE_String_Const quality_list[] =
95 {
96   "Low", "Normal", "High",
97   0
98 };
99 
100 static size_t
max_string_size(const SANE_String_Const strings[])101 max_string_size (const SANE_String_Const strings[])
102 {
103   size_t size, max_size = 0;
104   int i;
105   DBG (11, ">> max_string_size\n");
106 
107   for (i = 0; strings[i]; ++i)
108     {
109       size = strlen (strings[i]) + 1;
110       if (size > max_size)
111         max_size = size;
112     }
113 
114   DBG (11, "<< max_string_size\n");
115   return max_size;
116 }
117 
118 /* sets loc_s bytes long value at offset loc in scsi command to value size  */
119 static void
set_size(Byte * loc,int loc_s,size_t size)120 set_size (Byte * loc, int loc_s, size_t size)
121 {
122   int i;
123 
124   for (i = 0; i < loc_s; i++)
125     {
126       loc[loc_s - i - 1] = (size >> (i * 8)) & 0xff;
127     }
128 }
129 
130 /* gets loc_s bytes long value from loc in scsi command */
131 static int
get_size(Byte * loc,int loc_s)132 get_size (Byte * loc, int loc_s)
133 {
134   int i;
135   int j = 0;
136 
137   for (i = 0; i < loc_s; i++)
138     {
139       j = (j << 8) + (loc[i] & 0xff);
140     }
141 
142   return j;
143 }
144 
145 static long
reserve_unit(int fd)146 reserve_unit (int fd)
147 {
148   struct
149   {
150     /* Command */
151     Byte cmd;
152     Byte lun;
153     Byte res[2];
154     Byte tr_len;
155     Byte ctrl;
156   }
157   scsi_reserve;
158 
159   memset (&scsi_reserve, 0, sizeof (scsi_reserve));
160 
161   scsi_reserve.cmd = 0x16; /* RELEASE */
162 
163   DBG (3, "reserve_unit()\n");
164   return sanei_scsi_cmd (fd, &scsi_reserve, sizeof (scsi_reserve), 0, 0);
165 }
166 
167 static long
release_unit(int fd)168 release_unit (int fd)
169 {
170   struct
171   {
172     /* Command */
173     Byte cmd;
174     Byte lun;
175     Byte res[2];
176     Byte tr_len;
177     Byte ctrl;
178   }
179   scsi_release;
180 
181   memset (&scsi_release, 0, sizeof (scsi_release));
182 
183   scsi_release.cmd = 0x17; /* RELEASE */
184 
185   DBG (3, "release_unit()\n");
186   return sanei_scsi_cmd (fd, &scsi_release, sizeof (scsi_release), 0, 0);
187 }
188 
189 static SANE_Status
test_ready(int fd)190 test_ready (int fd)
191 {
192   SANE_Status status;
193   int try;
194 
195   struct
196   {
197     /* Command */
198     Byte cmd;
199     Byte lun;
200     Byte res[2];
201     Byte tr_len;
202     Byte ctrl;
203   }
204   scsi_test_ready;
205 
206   memset (&scsi_test_ready, 0, sizeof (scsi_test_ready));
207 
208   scsi_test_ready.cmd = 0x00; /* TEST UNIT READY */
209 
210   for (try = 0; try < 1000; ++try)
211     {
212       DBG (3, "test_ready: sending TEST_UNIT_READY\n");
213       status = sanei_scsi_cmd (fd, &scsi_test_ready, sizeof (scsi_test_ready),
214 			       0, 0);
215 
216       switch (status)
217 	{
218 	case SANE_STATUS_DEVICE_BUSY:
219 	  usleep (100000);	/* retry after 100ms */
220 	  break;
221 
222 	case SANE_STATUS_GOOD:
223 	  return status;
224 
225 	default:
226 	  DBG (1, "test_ready: test unit ready failed (%s)\n",
227 	       sane_strstatus (status));
228 	  return status;
229 	}
230     }
231 
232   DBG (1, "test_ready: timed out after %d attempts\n", try);
233   return SANE_STATUS_IO_ERROR;
234 }
235 
236 static SANE_Status
sense_handler(int scsi_fd,u_char * result,void * arg)237 sense_handler (int scsi_fd, u_char *result, void *arg)
238 {
239   (void) scsi_fd;			/* silence gcc */
240   (void) arg;				/* silence gcc */
241 
242   if (result[0])
243     {
244       DBG (0, "sense_handler() : sense code = %02x\n", result[0]);
245       return SANE_STATUS_IO_ERROR;
246     }
247   else
248     {
249       return SANE_STATUS_GOOD;
250     }
251 }
252 
253 static SANE_Status
stop_scan(int fd)254 stop_scan (int fd)
255 {
256   (void) fd;				/* silence gcc */
257 
258   /* XXX don't know how to stop the scanner. To be tested ! */
259 #if 0
260   const Byte scsi_rewind[] =
261   {
262     0x01, 0x00, 0x00, 0x00, 0x00, 0x00
263   };
264   DBG (1, "Trying to stop scanner...\n");
265   return sanei_scsi_cmd (fd, scsi_rewind, sizeof (scsi_rewind), 0, 0);
266 #else
267   return SANE_STATUS_GOOD;
268 #endif
269 }
270 
271 
272 static SANE_Status
start_scan(int fd,SANE_Bool cont)273 start_scan (int fd, SANE_Bool cont)
274 {
275   struct
276   {
277     /* Command */
278     Byte cmd;
279     Byte lun;
280     Byte res[2];
281     Byte tr_len;
282     Byte ctrl;
283 
284     /* Data */
285     Byte wid;
286   }
287   scsi_start_scan;
288 
289   memset (&scsi_start_scan, 0, sizeof (scsi_start_scan));
290 
291   scsi_start_scan.cmd = 0x1b; /* SCAN */
292   scsi_start_scan.tr_len = 1;
293   scsi_start_scan.wid = 0;
294   scsi_start_scan.ctrl = (cont == SANE_TRUE) ? 0x80 : 0x00;
295 
296   DBG (1, "Starting scanner ...\n");
297   return sanei_scsi_cmd (fd, &scsi_start_scan, sizeof (scsi_start_scan), 0, 0);
298 }
299 
300 static void
wait_ready(int fd)301 wait_ready (int fd)
302 {
303   struct
304   {
305     Byte bytes[2];		/* Total # of bytes */
306     Byte scan[2];		/* ms to complete - driver sleep time */
307   } result;
308 
309   size_t size = sizeof (result);
310   SANE_Status status;
311 
312   struct {
313     Byte cmd;
314     Byte lun;
315     Byte data_type;
316     Byte re1[3];
317     Byte tr_len[3];
318     Byte ctrl;
319   } cmd;
320 
321   memset (&cmd, 0, sizeof (cmd));
322 
323   cmd.cmd = 0x28;       /* READ */
324   cmd.data_type = 0x80; /* get scan time */
325 
326   set_size (cmd.tr_len, 3, sizeof (result));
327 
328   while (1)
329     {
330       status = sanei_scsi_cmd (fd, &cmd, sizeof (cmd),
331 			       &result, &size);
332 
333       if (status != SANE_STATUS_GOOD || size != sizeof (result))
334 	{
335 	  /*
336 	     Command failed, the assembler code of the windows scan library
337 	     ignores this condition, and so do I
338 	   */
339 	  break;
340 	}
341       else
342 	{
343 	  /* left is the amount of seconds left till the scanner is
344              ready * 100 */
345 	  int left = get_size (result.scan, 2);
346 
347 	  DBG (1, "wait_ready() : %d left...\n", left);
348 
349 	  if (!left)
350 	    break;
351 	  /* We delay only for half the given time */
352 	  else if (left < 200)
353 	    usleep (left * 5000);
354 	  else
355 	    sleep (left / 200);
356 	}
357     }
358 
359   return;
360 }
361 
362 static SANE_Status
get_read_sizes(int fd,int * lines_available,int * bpl,int * total_lines)363 get_read_sizes (int fd, int *lines_available, int *bpl, int *total_lines)
364 {
365   struct {
366     Byte reserved1[8];
367     Byte line_width[2];
368     Byte total_lines[2];
369     Byte cur_line[2];
370     Byte lines_this_block[2];
371     Byte reserved[8];
372   } read_sizes;
373 
374   const Byte scsi_read[] =
375   {
376     0x28, 0x00,				/* opcode, lun */
377     0x81,				/* data type 81 == read time left */
378     0x00, 0x00, 0x00,			/* reserved */
379     0x00, 0x00, sizeof (read_sizes),	/* transfer length */
380     0x00,				/* control byte */
381   };
382 
383   size_t size = sizeof (read_sizes);
384   SANE_Status status;
385 
386   status = sanei_scsi_cmd (fd, scsi_read, sizeof (scsi_read), &read_sizes, &size);
387 
388   if (status != SANE_STATUS_GOOD || size != sizeof (read_sizes))
389     {
390       /* Command failed */
391       return SANE_STATUS_IO_ERROR;
392     }
393   else
394     {
395       *lines_available = get_size (read_sizes.lines_this_block, 2);
396       *bpl = get_size (read_sizes.cur_line, 2);
397       if (total_lines)
398 	*total_lines = get_size (read_sizes.total_lines, 2);
399     }
400 
401   DBG (1, "get_read_sizes() : %d of %d, %d\n",
402        *lines_available, total_lines ? *total_lines : -1, *bpl);
403 
404   return SANE_STATUS_GOOD;
405 }
406 
407 static SANE_Status
set_window(AgfaFocus_Scanner * s)408 set_window (AgfaFocus_Scanner * s)
409 /* This function sets and sends the window for scanning */
410 {
411   double pixels_per_mm = (double) s->val[OPT_RESOLUTION].w / MM_PER_INCH;
412 
413   SANE_Bool auto_bright = s->val[OPT_AUTO_BRIGHTNESS].b;
414   SANE_Bool auto_contr = s->val[OPT_AUTO_CONTRAST].b;
415 
416   /* ranges down 255 (dark) down to 1(bright) */
417   int brightness = auto_bright ? 0 : (SANE_UNFIX (s->val[OPT_BRIGHTNESS].w)
418 				      * -1.27 + 128.5);
419   /* ranges from 1 (little contrast) up to 255 (much contrast) */
420   int contrast = auto_contr ? 0 : (SANE_UNFIX (s->val[OPT_CONTRAST].w)
421 				   * 1.27 + 128.5);
422 
423   int width;
424 
425   /* ranges from 40 (dark) down to 0 (bright) */
426   int bright_adjust = (SANE_UNFIX (s->val[OPT_BRIGHTNESS].w) * -20.0) / 100.0 + 20.0;
427 
428   /* ranges from 20 (little contrast) down to -20 = 235 (much contrast) */
429   int contr_adjust = (SANE_UNFIX (s->val[OPT_CONTRAST].w) * -20.0) / 100.0;
430 
431   /* Warning ! The following structure SEEMS to be a valid SCSI-2 SET_WINDOW
432      command.  But e.g. the limits for the window are only 2 Bytes instead
433      of 4.  The scanner was built at about 1990, so SCSI-2 wasn't available
434      for development...  */
435 
436   struct
437     {
438       Byte cmd;
439       Byte lun;
440       Byte re1[4];
441       Byte tr_len[3];
442       Byte ctrl;
443 
444       Byte re2[6];
445       Byte wd_len[2];
446 
447       struct
448 	{
449 	  Byte wid;                      /* Window ID */
450 	  Byte autobit;                  /* Window creation */
451 
452 	  Byte x_axis_res[2];            /* X resolution */
453 	  Byte y_axis_res[2];            /* X resolution */
454 
455 	  Byte x_axis_ul[2];             /* X upper left */
456 	  Byte y_axis_ul[2];             /* Y upper left */
457 
458 	  Byte wwidth[2];                /* Width */
459 	  Byte wlength[2];               /* Length */
460 
461 	  Byte contrast;                 /* Contrast */
462 	  Byte dummy1;
463 	  Byte intensity;                /* Intensity */
464 
465 	  Byte image_comp;               /* Image composition (0, 2, 5) */
466 	  Byte bpp;                      /* Bits per pixel */
467 
468           Byte tonecurve;                /* Tone curve (0 - 8) */
469 	  Byte ht_pattern;               /* Halftone pattern */
470 	  Byte paddingtype;              /* Padding type */
471 
472           Byte bitordering[2];           /* Bit ordering (0 = left to right) */
473           Byte comprtype;                /* Compression type */
474           Byte comprarg;                 /* Compression argument */
475 
476 	  Byte dummy2[6];
477 	  Byte edge;                     /* Sharpening (0 - 7) */
478 	  Byte dummy3;
479 
480 	  Byte bright_adjust;            /*  */
481 	  Byte contr_adjust;             /*  */
482 
483 	  Byte imagewidthtruncation;     /* */
484 
485 	  Byte dummy4;
486           Byte quality_type;             /* 0 normal, 1 high, 255 low */
487           Byte red_att;
488           Byte green_att;
489           Byte blue_att;
490 
491 	  Byte dummy5[5];
492 	  Byte color_planes;
493 	  Byte orig_type;
494 	  Byte fixturetype;
495 	  Byte exposure[2];
496 	  Byte defocus[2];
497 	  Byte dummy6[4];
498           Byte descreen_factor;
499 
500 	  Byte packing_word_length;
501 	  Byte packing_number_of_pixels;
502 	  Byte packing_color_mode;
503 	  Byte strokenab;
504 	  Byte rotatenab;
505 	  Byte autostrokenab;
506 	  Byte dummy7;
507 	}
508       wd;
509 
510     }
511   cmd;
512 
513   memset (&cmd, 0, sizeof (cmd));
514 
515   cmd.cmd = 0x24; /* SET WINDOW PARAMETERS */
516 
517   switch (s->hw->type)
518     {
519     case AGFAGRAY64:
520     case AGFALINEART:
521     case AGFAGRAY256:
522       set_size (cmd.tr_len, 3, 36 + 8);
523       set_size (cmd.wd_len, 2, 36);
524       break;
525 
526     case AGFACOLOR:
527       set_size (cmd.tr_len, 3, 65 + 8);
528       set_size (cmd.wd_len, 2, 65);
529       break;
530     }
531 
532   /* Resolution.  Original comment in German: Aufloesung */
533   set_size (cmd.wd.x_axis_res, 2, s->val[OPT_RESOLUTION].w);
534   set_size (cmd.wd.y_axis_res, 2, s->val[OPT_RESOLUTION].w);
535 
536   /* Scan window position/size.  Original comment in German:
537      Fensterposition / Groesse */
538   set_size (cmd.wd.x_axis_ul, 2,
539 	    SANE_UNFIX (s->val[OPT_TL_X].w) * pixels_per_mm + 0.5);
540   set_size (cmd.wd.y_axis_ul, 2,
541 	    SANE_UNFIX (s->val[OPT_TL_Y].w) * pixels_per_mm + 0.5);
542 
543   width = (SANE_UNFIX (s->val[OPT_BR_X].w - s->val[OPT_TL_X].w) * pixels_per_mm) + 0.5;
544 
545   if (s->bpp == 1 && width % 8)
546     width += 8 - width % 8;
547 
548   set_size (cmd.wd.wwidth, 2, width);
549   set_size (cmd.wd.wlength, 2, SANE_UNFIX (s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w)
550 	    * pixels_per_mm + 0.5);
551 
552   cmd.wd.bpp = s->bpp;
553 
554   if (s->mode == COLOR18BIT ||
555       s->mode == COLOR24BIT)
556     {
557       cmd.wd.paddingtype = 3;
558       cmd.wd.ht_pattern = 3;
559 
560       cmd.wd.red_att = s->r_att;
561       cmd.wd.blue_att = s->g_att;
562       cmd.wd.green_att = s->b_att;
563       cmd.wd.color_planes = 0x0e;
564 
565       set_size (cmd.wd.exposure, 2, s->exposure);
566 
567       cmd.wd.packing_word_length = 1;
568       cmd.wd.packing_number_of_pixels = 1;
569       cmd.wd.packing_color_mode = 2;
570 
571       if (s->bpp == 6)
572 	cmd.wd.edge = s->edge;
573 
574       DBG (3,
575 	   "Setting parameters: imc %d, bpp %d, res %d, exp %d, attenuation [%d, %d, %d], edge %d\n",
576 	   s->image_composition, s->bpp, s->val[OPT_RESOLUTION].w,
577 	   s->exposure, cmd.wd.red_att, cmd.wd.blue_att, cmd.wd.green_att, s->edge);
578     }
579   else
580     {
581       if (s->bpp == 1)
582 	cmd.wd.ht_pattern = s->halftone;
583       else
584 	cmd.wd.ht_pattern = 3;
585 
586       cmd.wd.intensity = brightness;
587       cmd.wd.contrast = contrast;
588 
589       cmd.wd.contr_adjust = contr_adjust;
590       cmd.wd.bright_adjust = bright_adjust;
591 
592       cmd.wd.tonecurve = s->tonecurve;
593       cmd.wd.paddingtype = 3;
594       cmd.wd.edge = s->edge;
595 
596       if (s->lin_log)
597 	cmd.wd.dummy3 = 0x02;
598 
599       DBG (3,
600 	   "Setting parameters: imc %d, bpp %d, res %d, bri %d, con %d, bad %d, cad %d, ht %d, edge %d\n",
601 	   s->image_composition, s->bpp, s->val[OPT_RESOLUTION].w,
602 	   brightness, contrast, bright_adjust, contr_adjust, s->halftone, s->edge);
603     }
604 
605   cmd.wd.image_comp = s->image_composition;
606   cmd.wd.quality_type = s->quality;
607   cmd.wd.orig_type = s->original;
608 
609   return sanei_scsi_cmd (s->fd, &cmd, sizeof (cmd), 0, 0);
610 }
611 
612 /* Tell scanner to scan more data. */
613 
614 static SANE_Status
request_more_data(AgfaFocus_Scanner * s)615 request_more_data (AgfaFocus_Scanner * s)
616 {
617   SANE_Status status;
618   int lines_available;
619   int bytes_per_line;
620 
621   status = start_scan (s->fd, SANE_TRUE);
622   if (status != SANE_STATUS_GOOD)
623     return status;
624 
625   if (!s->hw->disconnect)
626     wait_ready (s->fd);
627 
628   status = get_read_sizes (s->fd, &lines_available, &bytes_per_line, 0);
629 
630   if (!lines_available)
631     return SANE_STATUS_INVAL;
632 
633   s->lines_available = lines_available;
634 
635   return SANE_STATUS_GOOD;
636 }
637 
638 static SANE_Status
upload_dither_matrix(AgfaFocus_Scanner * s,int rows,int cols,int * dither_matrix)639 upload_dither_matrix (AgfaFocus_Scanner * s, int rows, int cols, int *dither_matrix)
640 {
641   struct {
642     Byte cmd;
643     Byte lun;
644     Byte data_type;
645     Byte re1[3];
646     Byte tr_len[3];
647     Byte ctrl;
648 
649     struct {
650       Byte nrrows[2];
651       Byte nrcols[2];
652 
653       struct {
654 	Byte data[2];
655       } element[256];
656     } wd;
657   } cmd;
658 
659   SANE_Status status;
660   int i;
661 
662   memset (&cmd, 0, sizeof (cmd));
663 
664   cmd.cmd = 0x2a;       /* WRITE */
665   cmd.data_type = 0x81; /* upload dither matrix */
666 
667   set_size (cmd.tr_len, 3, 4 + (2 * rows * cols));
668   set_size (cmd.wd.nrrows, 2, rows);
669   set_size (cmd.wd.nrcols, 2, cols);
670 
671   for (i = 0; i < cols * rows; ++i)
672     set_size (cmd.wd.element[i].data, 2, dither_matrix[i]);
673 
674   status = sanei_scsi_cmd (s->fd, &cmd, sizeof (cmd), 0, 0);
675 
676   if (status != SANE_STATUS_GOOD)
677     /* Command failed */
678     return SANE_STATUS_IO_ERROR;
679 
680   DBG (1, "upload_dither_matrix(): uploaded dither matrix: %d, %d\n", rows, cols);
681 
682   return SANE_STATUS_GOOD;
683 }
684 
685 #if 0
686 static SANE_Status
687 upload_tonecurve (AgfaFocus_Scanner * s, int color_type, int input, int output, int dither_matrix[256])
688 {
689   struct {
690    Byte cmd;
691    Byte lun;
692    Byte re1[4];
693    Byte tr_len[3];
694    Byte ctrl;
695 
696    Byte re2[6];
697    Byte wd_len[2];
698 
699     struct {
700       Byte color_type[2];
701       Byte nrinput[2];
702       Byte nroutput[2];
703 
704       struct {
705 	Byte data[2];
706       } outputval[256];
707     } wd;
708   } cmd;
709 
710   SANE_Status status;
711   int i, j;
712 
713   memset (&cmd, 0, sizeof (cmd));
714 
715   cmd.cmd = 0x80;
716 
717   set_size (cmd.tr_len, 3, sizeof (cmd.wd));
718   set_size (cmd.wd.nrrows, 2, rows);
719   set_size (cmd.wd.nrrows, 2, cols);
720 
721   for (i = 0; i < cols; ++i)
722     for (j = 0; j < rows; ++j)
723       set_size (cmd.wd.element[j + i * rows].data, 2, dither_matrix[j + i * rows]);
724 
725   status = sanei_scsi_cmd (s->fd, &cmd, sizeof (cmd), 0, 0);
726 
727   if (status != SANE_STATUS_GOOD)
728   /*    * Command failed * */
729     return SANE_STATUS_IO_ERROR;
730 
731   DBG (1, "upload_dither_matrix(): uploaded dither matrix\n");
732 
733   return SANE_STATUS_GOOD;
734 }
735 #endif
736 
737 /* May only be called when there is at least one row of data to
738    be read.
739 
740    Original comment in German: Darf nur aufgerufen werden, wenn
741    wirklich noch Zeilen zu scannen/lesen sind !  */
742 static SANE_Status
read_data(AgfaFocus_Scanner * s,SANE_Byte * buf,int lines,int bpl)743 read_data (AgfaFocus_Scanner * s, SANE_Byte *buf, int lines, int bpl)
744 {
745   struct {
746    Byte cmd;
747    Byte lun;
748    Byte re1[4];
749    Byte tr_len[3];
750    Byte ctrl;
751   } cmd;
752 
753   SANE_Status status;
754   size_t size;
755   unsigned int i;
756 
757   memset (&cmd, 0, sizeof (cmd));
758 
759   cmd.cmd = 0x28; /* READ */
760 
761   set_size (cmd.tr_len, 3, lines);
762   size = lines * bpl;
763 
764   status = sanei_scsi_cmd (s->fd, &cmd, sizeof (cmd), buf, &size);
765 
766   if (status != SANE_STATUS_GOOD)
767     {
768       DBG (1, "sanei_scsi_cmd() = %d\n", status);
769       return SANE_STATUS_IO_ERROR;
770     }
771 
772   if (size != ((unsigned int) lines * bpl))
773     {
774       DBG (1, "sanei_scsi_cmd(): got %lu bytes, expected %d\n",
775 	   (u_long) size, lines * bpl);
776       return SANE_STATUS_INVAL;
777     }
778 
779   DBG (1, "Got %lu bytes\n", (u_long) size);
780 
781   /* Reverse: */
782   if (s->bpp != 1)
783     {
784       if (s->bpp != 6)
785 	for (i = 0; i < size; i++)
786 	  buf[i] = 255 - buf[i];
787       else
788 	for (i = 0; i < size; i++)
789 	  buf[i] = 255 - ((buf[i] * 256.0f) / 64.0f);
790     }
791 
792   s->lines_available -= lines;
793 
794   return SANE_STATUS_GOOD;
795 }
796 
797 
798 static SANE_Status
attach(const char * devname,AgfaFocus_Device ** devp)799 attach (const char *devname, AgfaFocus_Device ** devp)
800 {
801 #define ATTACH_SCSI_INQ_LEN 55
802   const Byte scsi_inquiry[] =
803   {
804     0x12, 0x00, 0x00, 0x00, ATTACH_SCSI_INQ_LEN, 0x00
805   };
806   Byte result[ATTACH_SCSI_INQ_LEN];
807 
808   int fd;
809   AgfaFocus_Device *dev;
810   SANE_Status status;
811   size_t size;
812   int i;
813 
814   for (dev = agfafocus_devices; dev; dev = dev->next)
815     if (strcmp (dev->sane.name, devname) == 0)
816       {
817 	if (devp)
818 	  *devp = dev;
819 	return SANE_STATUS_GOOD;
820       }
821 
822   DBG (3, "attach: opening %s\n", devname);
823   status = sanei_scsi_open (devname, &fd, sense_handler, 0);
824   if (status != SANE_STATUS_GOOD)
825     {
826       DBG (1, "attach: open failed (%s)\n", sane_strstatus (status));
827       return SANE_STATUS_INVAL;
828     }
829 
830   DBG (4, "attach: sending INQUIRY\n");
831   size = sizeof (result);
832   status = sanei_scsi_cmd (fd, scsi_inquiry, sizeof (scsi_inquiry),
833 			   result, &size);
834   if (status != SANE_STATUS_GOOD || size != ATTACH_SCSI_INQ_LEN)
835     {
836       DBG (1, "attach: inquiry failed (%s)\n", sane_strstatus (status));
837       sanei_scsi_close (fd);
838       return status;
839     }
840 
841   status = test_ready (fd);
842   sanei_scsi_close (fd);
843   if (status != SANE_STATUS_GOOD)
844     return status;
845 
846   /* The structure send by the scanner after inquiry is not SCSI-2
847      compatible.  The standard manufacturer/model fields are no ASCII
848      strings, but ?  At offset 36 my SIEMENS scanner identifies as an
849      AGFA one ?!   */
850 
851   if (result[0] != 6 || strncmp ((char *)result + 36, "AGFA0", 5))
852     {
853       DBG (1, "attach: device doesn't look like a Siemens 9036 scanner\n");
854       return SANE_STATUS_INVAL;
855     }
856 
857   DBG (4, "Inquiry data:\n");
858   DBG (4, "-----------\n");
859   for (i = 5; i < 55; i += 10)
860     DBG (4, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
861       result[i], result[i + 1], result[i + 2], result[i + 3], result[i + 4],
862 	 result[i + 5], result[i + 6], result[i + 7], result[i + 8],
863 	 result[i + 9]);
864 
865   dev = malloc (sizeof (*dev));
866 
867   if (!dev)
868     return SANE_STATUS_NO_MEM;
869 
870   memset (dev, 0, sizeof (*dev));
871 
872   dev->sane.name = strdup (devname);
873   if (!strncmp ((char *)result + 36, "AGFA01", 6)) {
874     dev->sane.vendor = "AGFA";
875     dev->sane.model = "Focus GS Scanner (6 bit)";
876     dev->upload_user_defines = SANE_TRUE;
877     dev->type = AGFAGRAY64;
878   } else if (!strncmp ((char *)result + 36, "AGFA02", 6)) {
879     dev->sane.vendor = "AGFA";
880     dev->sane.model = "Focus Lineart Scanner";
881     dev->upload_user_defines = SANE_FALSE;
882     dev->type = AGFALINEART;
883   } else if (!strncmp ((char *)result + 36, "AGFA03", 6)) {
884     dev->sane.vendor = "AGFA";
885     dev->sane.model = "Focus II";
886     dev->upload_user_defines = SANE_TRUE;
887     dev->type = AGFAGRAY256;
888   } else if (!strncmp ((char *)result + 36, "AGFA04", 6)) {
889     dev->sane.vendor = "AGFA";
890     dev->sane.model = "Focus Color";
891     dev->upload_user_defines = SANE_TRUE;
892     dev->type = AGFACOLOR;
893   } else {
894     free (dev);
895     DBG (1, "attach: device looks like an AGFA scanner, but wasn't recognised\n");
896     return SANE_STATUS_INVAL;
897   }
898   dev->sane.type = "flatbed scanner";
899 
900   dev->transparent = result[45] & 0x80 ? SANE_TRUE : SANE_FALSE;
901   dev->analoglog =   result[46] & 0x80 ? SANE_TRUE : SANE_FALSE;
902   dev->tos5 =        result[46] & 0x05 ? SANE_TRUE : SANE_FALSE;
903   dev->quality =     result[47] & 0x40 ? SANE_TRUE : SANE_FALSE;
904   dev->disconnect =  result[47] & 0x80 ? SANE_TRUE : SANE_FALSE;
905 
906   DBG (4, "\n");
907   DBG (4, "scan modes:\n");
908   DBG (4, "-----------\n");
909   DBG (4, "three pass color mode: %s\n", dev->type >= AGFACOLOR ? "yes" : "no");
910   DBG (4, "8 bit gray mode: %s\n", dev->type >= AGFAGRAY64 ? "yes" : "no");
911   DBG (4, "uploadable matrices: %s\n", dev->upload_user_defines ? "yes" : "no");
912   DBG (4, "transparency: %s\n", dev->transparent ? "yes" : "no");
913   DBG (4, "disconnect: %s\n", dev->disconnect ? "yes" : "no");
914   DBG (4, "quality calibration: %s\n", dev->quality ? "yes" : "no");
915 
916   dev->handle = 0;
917 
918   DBG (3, "attach: found AgfaFocus scanner model\n");
919 
920   ++num_devices;
921   dev->next = agfafocus_devices;
922   agfafocus_devices = dev;
923 
924   if (devp)
925     *devp = dev;
926 
927   return SANE_STATUS_GOOD;
928 }
929 
930 static SANE_Status
do_eof(AgfaFocus_Scanner * s)931 do_eof (AgfaFocus_Scanner *s)
932 {
933   if (s->pipe >= 0)
934     {
935       close (s->pipe);
936       s->pipe = -1;
937     }
938   return SANE_STATUS_EOF;
939 }
940 
941 
942 static SANE_Status
do_cancel(AgfaFocus_Scanner * s)943 do_cancel (AgfaFocus_Scanner * s)
944 {
945   s->scanning = SANE_FALSE;
946   s->pass = 0;
947 
948   do_eof (s);
949 
950   if (sanei_thread_is_valid (s->reader_pid))
951     {
952       int exit_status;
953 
954       /* ensure child knows it's time to stop: */
955       sanei_thread_kill (s->reader_pid);
956       sanei_thread_waitpid (s->reader_pid, &exit_status);
957       sanei_thread_invalidate(s->reader_pid);
958     }
959 
960   if (s->fd >= 0)
961     {
962       stop_scan (s->fd);
963       release_unit (s->fd);
964       sanei_scsi_close (s->fd);
965       s->fd = -1;
966     }
967 
968   return SANE_STATUS_CANCELLED;
969 }
970 
971 
972 static SANE_Status
init_options(AgfaFocus_Scanner * s)973 init_options (AgfaFocus_Scanner * s)
974 {
975   int i;
976 
977   /* Hardware Limitations: must be static ! */
978   static const SANE_Int dpi_list[] =
979   {8, 100, 200, 300, 400, 500, 600, 700, 800};
980 
981   static const SANE_Range percentage_range =
982   {
983     SANE_FIX(-100),	/* minimum */
984     SANE_FIX(100),	/* maximum */
985     SANE_FIX(1)         /* quantization */
986   };
987 
988   static const SANE_Range sharpen_range =
989   {0, 7, 1};
990   static const SANE_Range exposure_range =
991   {0, 100, 0};
992   static const SANE_Range attenuation_range =
993   {
994     SANE_FIX(0),	/* minimum */
995     SANE_FIX(100),	/* maximum */
996     SANE_FIX(1)	        /* quantization */
997   };
998 
999 
1000   static const SANE_Range x_range =
1001   {0, SANE_FIX (8.27 * MM_PER_INCH), 0};
1002   static const SANE_Range y_range =
1003   {0, SANE_FIX (12.72 * MM_PER_INCH), 0};
1004 
1005   /* ------ */
1006 
1007   memset (s->opt, 0, sizeof (s->opt));
1008   memset (s->val, 0, sizeof (s->val));
1009 
1010   for (i = 0; i < NUM_OPTIONS; ++i)
1011     {
1012       s->opt[i].size = sizeof (SANE_Word);
1013       s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1014     }
1015 
1016   s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
1017   s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
1018   s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
1019   s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
1020   s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
1021 
1022   /* "Mode" group: */
1023 
1024   s->opt[OPT_MODE_GROUP].title = "Scan Mode";
1025   s->opt[OPT_MODE_GROUP].desc = "";
1026   s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
1027   s->opt[OPT_MODE_GROUP].cap = 0;
1028   s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1029 
1030   /* scan mode */
1031   s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
1032   s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
1033   s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
1034   s->opt[OPT_MODE].type = SANE_TYPE_STRING;
1035 
1036   switch (s->hw->type)
1037     {
1038     case AGFACOLOR:
1039       s->opt[OPT_MODE].size = max_string_size (focuscolor_mode_list);
1040       s->opt[OPT_MODE].constraint.string_list = focuscolor_mode_list;
1041       s->val[OPT_MODE].s = strdup (focuscolor_mode_list[0]);
1042       break;
1043     case AGFAGRAY256:
1044       s->opt[OPT_MODE].size = max_string_size (focusii_mode_list);
1045       s->opt[OPT_MODE].constraint.string_list = focusii_mode_list;
1046       s->val[OPT_MODE].s = strdup (focusii_mode_list[0]);
1047       break;
1048     default:
1049       s->opt[OPT_MODE].size = max_string_size (focus_mode_list);
1050       s->opt[OPT_MODE].constraint.string_list = focus_mode_list;
1051       s->val[OPT_MODE].s = strdup (focus_mode_list[0]);
1052       break;
1053     }
1054 
1055   s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1056 
1057   /* resolution */
1058   s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
1059   s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
1060   s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
1061   s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
1062   s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
1063   s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1064   s->opt[OPT_RESOLUTION].constraint.word_list = dpi_list;
1065   s->val[OPT_RESOLUTION].w = 100;
1066 
1067   s->opt[OPT_SOURCE].name  = SANE_NAME_SCAN_SOURCE;
1068   s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
1069   s->opt[OPT_SOURCE].desc  = SANE_DESC_SCAN_SOURCE;
1070   s->opt[OPT_SOURCE].type  = SANE_TYPE_STRING;
1071   s->opt[OPT_SOURCE].unit  = SANE_UNIT_NONE;
1072   if (!s->hw->transparent)
1073     s->opt[OPT_SOURCE].cap |= SANE_CAP_INACTIVE;
1074   else
1075     s->opt[OPT_SOURCE].cap &= ~SANE_CAP_INACTIVE;
1076   s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1077   s->opt[OPT_SOURCE].constraint.string_list = source_list;
1078   s->opt[OPT_SOURCE].size  = max_string_size (source_list);
1079   s->val[OPT_SOURCE].s     = strdup (source_list[0]);
1080 
1081   /* "Geometry" group: */
1082   s->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
1083   s->opt[OPT_GEOMETRY_GROUP].desc = "";
1084   s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
1085   s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
1086   s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1087 
1088   /* top-left x */
1089   s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
1090   s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
1091   s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
1092   s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
1093   s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
1094   s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1095   s->opt[OPT_TL_X].constraint.range = &x_range;
1096   s->val[OPT_TL_X].w = 0;
1097 
1098   /* top-left y */
1099   s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1100   s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1101   s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1102   s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
1103   s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
1104   s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1105   s->opt[OPT_TL_Y].constraint.range = &y_range;
1106   s->val[OPT_TL_Y].w = 0;
1107 
1108   /* bottom-right x */
1109   s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
1110   s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
1111   s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
1112   s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
1113   s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
1114   s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
1115   s->opt[OPT_BR_X].constraint.range = &x_range;
1116   s->val[OPT_BR_X].w = x_range.max;
1117 
1118   /* bottom-right y */
1119   s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
1120   s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
1121   s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
1122   s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
1123   s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
1124   s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1125   s->opt[OPT_BR_Y].constraint.range = &y_range;
1126   s->val[OPT_BR_Y].w = y_range.max;
1127 
1128   /* "Enhancement" group: */
1129   s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
1130   s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
1131   s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
1132   s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
1133   s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1134 
1135   /* exposure */
1136   s->opt[OPT_EXPOSURE].name  = "exposure";
1137   s->opt[OPT_EXPOSURE].title = "Exposure";
1138   s->opt[OPT_EXPOSURE].desc  = "Analog exposure control.";
1139   s->opt[OPT_EXPOSURE].type  = SANE_TYPE_INT;
1140   s->opt[OPT_EXPOSURE].cap |= SANE_CAP_INACTIVE;
1141   s->opt[OPT_EXPOSURE].unit  = SANE_UNIT_PERCENT;
1142   s->opt[OPT_EXPOSURE].constraint_type = SANE_CONSTRAINT_RANGE;
1143   s->opt[OPT_EXPOSURE].constraint.range = &exposure_range;
1144   s->val[OPT_EXPOSURE].w     = 23;
1145 
1146   /* brightness automatic correct */
1147   s->opt[OPT_AUTO_BRIGHTNESS].name = "adjust-bright";
1148   s->opt[OPT_AUTO_BRIGHTNESS].title = "Automatic brightness correction";
1149   s->opt[OPT_AUTO_BRIGHTNESS].desc = "Turns on automatic brightness correction of "
1150     "the acquired image. This makes the scanner do a two pass scan to analyse the "
1151     "brightness of the image before it's scanned.";
1152   s->opt[OPT_AUTO_BRIGHTNESS].type = SANE_TYPE_BOOL;
1153   s->val[OPT_AUTO_BRIGHTNESS].b = SANE_FALSE;
1154 
1155   /* contrast automatic correct */
1156   s->opt[OPT_AUTO_CONTRAST].name = "adjust-contr";
1157   s->opt[OPT_AUTO_CONTRAST].title = "Automatic contrast correction";
1158   s->opt[OPT_AUTO_CONTRAST].desc = "Turns on automatic contrast correction of "
1159     "the acquired image. This makes the scanner do a two pass scan to analyse "
1160     "the contrast of the image to be scanned.";
1161   s->opt[OPT_AUTO_CONTRAST].type = SANE_TYPE_BOOL;
1162   s->val[OPT_AUTO_CONTRAST].b = SANE_FALSE;
1163 
1164   /* brightness */
1165   s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
1166   s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
1167   s->opt[OPT_BRIGHTNESS].desc = "Controls the brightness of the acquired image. "
1168     "When automatic brightness is enabled, this can be used to adjust the selected brightness.";
1169   s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_FIXED;
1170   s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_PERCENT;
1171   s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
1172   s->opt[OPT_BRIGHTNESS].constraint.range = &percentage_range;
1173   s->val[OPT_BRIGHTNESS].w = 0;
1174 
1175   /* contrast */
1176   s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
1177   s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
1178   s->opt[OPT_CONTRAST].desc = "Controls the contrast of the acquired image. "
1179     "When automatic contrast is enabled, this can be used to adjust the selected contrast.";
1180   s->opt[OPT_CONTRAST].type = SANE_TYPE_FIXED;
1181   s->opt[OPT_CONTRAST].unit = SANE_UNIT_PERCENT;
1182   s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
1183   s->opt[OPT_CONTRAST].constraint.range = &percentage_range;
1184   s->val[OPT_CONTRAST].w = 0;
1185 
1186   /* halftone patterns */
1187   s->opt[OPT_HALFTONE_PATTERN].name = SANE_NAME_HALFTONE_PATTERN;
1188   s->opt[OPT_HALFTONE_PATTERN].title = SANE_TITLE_HALFTONE_PATTERN;
1189   s->opt[OPT_HALFTONE_PATTERN].desc = SANE_DESC_HALFTONE_PATTERN;
1190   s->opt[OPT_HALFTONE_PATTERN].type = SANE_TYPE_STRING;
1191   s->opt[OPT_HALFTONE_PATTERN].size = 32;
1192   s->opt[OPT_HALFTONE_PATTERN].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1193   if (s->hw->upload_user_defines)
1194     {
1195       s->opt[OPT_HALFTONE_PATTERN].constraint.string_list = halftone_upload_list;
1196       s->val[OPT_HALFTONE_PATTERN].s = strdup (halftone_upload_list[0]);
1197     }
1198   else
1199     {
1200       s->opt[OPT_HALFTONE_PATTERN].constraint.string_list = halftone_list;
1201       s->val[OPT_HALFTONE_PATTERN].s = strdup (halftone_list[0]);
1202     }
1203 
1204   /* red-attenuation */
1205   s->opt[OPT_ATTENUATION_RED].name  = "red-attenuation";
1206   s->opt[OPT_ATTENUATION_RED].title = "Red attenuation";
1207   s->opt[OPT_ATTENUATION_RED].desc  = "Controls the red attenuation of the acquired image. "
1208     "Higher values mean less impact on scanned image.";
1209   s->opt[OPT_ATTENUATION_RED].type = SANE_TYPE_FIXED;
1210   s->opt[OPT_ATTENUATION_RED].cap |= SANE_CAP_INACTIVE;
1211   s->opt[OPT_ATTENUATION_RED].unit = SANE_UNIT_PERCENT;
1212   s->opt[OPT_ATTENUATION_RED].constraint_type = SANE_CONSTRAINT_RANGE;
1213   s->opt[OPT_ATTENUATION_RED].constraint.range = &attenuation_range;
1214   s->val[OPT_ATTENUATION_RED].w = SANE_FIX (50.0);
1215 
1216   /* green-attenuation */
1217   s->opt[OPT_ATTENUATION_GREEN].name  = "green-attenuation";
1218   s->opt[OPT_ATTENUATION_GREEN].title = "Green attenuation";
1219   s->opt[OPT_ATTENUATION_GREEN].desc  = "Controls the green attenuation of the acquired image. "
1220     "Higher values mean less impact on scanned image.";
1221   s->opt[OPT_ATTENUATION_GREEN].type = SANE_TYPE_FIXED;
1222   s->opt[OPT_ATTENUATION_GREEN].cap |= SANE_CAP_INACTIVE;
1223   s->opt[OPT_ATTENUATION_GREEN].unit = SANE_UNIT_PERCENT;
1224   s->opt[OPT_ATTENUATION_GREEN].constraint_type = SANE_CONSTRAINT_RANGE;
1225   s->opt[OPT_ATTENUATION_GREEN].constraint.range = &attenuation_range;
1226   s->val[OPT_ATTENUATION_GREEN].w = SANE_FIX (50.0);
1227 
1228   /* blue-attenuation */
1229   s->opt[OPT_ATTENUATION_BLUE].name  = "blue-attenuation";
1230   s->opt[OPT_ATTENUATION_BLUE].title = "Blue attenuation";
1231   s->opt[OPT_ATTENUATION_BLUE].desc  = "Controls the blue attenuation of the acquired image. "
1232     "Higher values mean less impact on scanned image.";
1233   s->opt[OPT_ATTENUATION_BLUE].type = SANE_TYPE_FIXED;
1234   s->opt[OPT_ATTENUATION_BLUE].cap |= SANE_CAP_INACTIVE;
1235   s->opt[OPT_ATTENUATION_BLUE].unit = SANE_UNIT_PERCENT;
1236   s->opt[OPT_ATTENUATION_BLUE].constraint_type = SANE_CONSTRAINT_RANGE;
1237   s->opt[OPT_ATTENUATION_BLUE].constraint.range = &attenuation_range;
1238   s->val[OPT_ATTENUATION_BLUE].w = SANE_FIX (50.0);
1239 
1240   /* quality-calibration */
1241   s->opt[OPT_QUALITY].name  = SANE_NAME_QUALITY_CAL;
1242   s->opt[OPT_QUALITY].title = SANE_TITLE_QUALITY_CAL;
1243   s->opt[OPT_QUALITY].desc  = "Controls the calibration that will be done in the "
1244         "scanner.  Less calibration result in faster scanner times.";
1245   s->opt[OPT_QUALITY].type = SANE_TYPE_STRING;
1246   s->opt[OPT_QUALITY].size = 32;
1247   if (!s->hw->quality)
1248     s->opt[OPT_QUALITY].cap |= SANE_CAP_INACTIVE;
1249   else
1250     s->opt[OPT_QUALITY].cap &= ~SANE_CAP_INACTIVE;
1251   s->opt[OPT_QUALITY].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1252   s->opt[OPT_QUALITY].constraint.string_list = quality_list;
1253   s->val[OPT_QUALITY].s = strdup (quality_list[1]);
1254 
1255   /* sharpening */
1256   s->opt[OPT_SHARPEN].name = "sharpen";
1257   s->opt[OPT_SHARPEN].title = "Sharpening";
1258   s->opt[OPT_SHARPEN].desc = "Controls the sharpening that will be "
1259     "done by the video processor in the scanner.";
1260   s->opt[OPT_SHARPEN].type = SANE_TYPE_INT;
1261   s->opt[OPT_SHARPEN].unit = SANE_UNIT_NONE;
1262   s->opt[OPT_SHARPEN].constraint_type = SANE_CONSTRAINT_RANGE;
1263   s->opt[OPT_SHARPEN].constraint.range = &sharpen_range;
1264   s->val[OPT_SHARPEN].w = 1;
1265 
1266   return SANE_STATUS_GOOD;
1267 }
1268 
1269 static SANE_Status
attach_one(const char * dev)1270 attach_one (const char *dev)
1271 {
1272   attach (dev, 0);
1273   return SANE_STATUS_GOOD;
1274 }
1275 
1276 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback authorize)1277 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
1278 {
1279   char dev_name[PATH_MAX];
1280   size_t len;
1281   FILE *fp;
1282 
1283   (void) authorize;			/* silence gcc */
1284 
1285   DBG_INIT ();
1286 
1287   sanei_thread_init ();
1288 
1289   if (version_code)
1290     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
1291 
1292   fp = sanei_config_open ("agfafocus.conf");
1293   if (!fp)
1294     {
1295       /* default to /dev/scanner instead of insisting on config file */
1296       attach ("/dev/scanner", 0);
1297       return SANE_STATUS_GOOD;
1298     }
1299 
1300   while (sanei_config_read (dev_name, sizeof (dev_name), fp))
1301     {
1302       if (dev_name[0] == '#')	/* ignore line comments */
1303 	continue;
1304       len = strlen (dev_name);
1305 
1306       if (!len)
1307 	continue;		/* ignore empty lines */
1308 
1309       sanei_config_attach_matching_devices (dev_name, attach_one);
1310     }
1311   fclose (fp);
1312   return SANE_STATUS_GOOD;
1313 }
1314 
1315 void
sane_exit(void)1316 sane_exit (void)
1317 {
1318   AgfaFocus_Device *dev, *next;
1319 
1320   for (dev = agfafocus_devices; dev; dev = next)
1321     {
1322       next = dev->next;
1323       if (dev->handle)
1324 	sane_close (dev->handle);
1325       free (dev);
1326     }
1327 
1328   if (devlist)
1329     free (devlist);
1330 }
1331 
1332 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)1333 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
1334 {
1335   AgfaFocus_Device *dev;
1336   int i;
1337 
1338   (void) local_only;			/* silence gcc */
1339 
1340   if (devlist)
1341     free (devlist);
1342 
1343   devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
1344   if (!devlist)
1345     return SANE_STATUS_NO_MEM;
1346 
1347   for (dev = agfafocus_devices, i = 0; i < num_devices; dev = dev->next)
1348     devlist[i++] = &dev->sane;
1349   devlist[i++] = 0;
1350 
1351   *device_list = devlist;
1352   return SANE_STATUS_GOOD;
1353 }
1354 
1355 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)1356 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
1357 {
1358   AgfaFocus_Device *dev;
1359   SANE_Status status;
1360   AgfaFocus_Scanner *s;
1361 
1362   if (devicename[0])
1363     {
1364       status = attach (devicename, &dev);
1365       if (status != SANE_STATUS_GOOD)
1366 	return status;
1367     }
1368   else
1369     {
1370       /* empty devicname -> use first device */
1371       dev = agfafocus_devices;
1372     }
1373 
1374   if (!dev)
1375     return SANE_STATUS_INVAL;
1376 
1377   if (dev->handle)
1378     return SANE_STATUS_DEVICE_BUSY;
1379 
1380   s = malloc (sizeof (*s));
1381   if (!s)
1382     return SANE_STATUS_NO_MEM;
1383 
1384   memset (s, 0, sizeof (*s));
1385   s->scanning = SANE_FALSE;
1386 
1387   s->fd = -1;
1388   s->hw = dev;
1389   s->hw->handle = s;
1390 
1391   init_options (s);
1392 
1393   *handle = s;
1394   return SANE_STATUS_GOOD;
1395 }
1396 
1397 void
sane_close(SANE_Handle handle)1398 sane_close (SANE_Handle handle)
1399 {
1400   AgfaFocus_Scanner *s = handle;
1401 
1402   if (s->scanning)
1403     do_cancel (handle);
1404 
1405   s->hw->handle = 0;
1406 
1407   free (handle);
1408 }
1409 
1410 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)1411 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
1412 {
1413   AgfaFocus_Scanner *s = handle;
1414 
1415   if ((unsigned) option >= NUM_OPTIONS)
1416     return 0;
1417   return s->opt + option;
1418 }
1419 
1420 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)1421 sane_control_option (SANE_Handle handle, SANE_Int option,
1422 		     SANE_Action action, void *val, SANE_Int * info)
1423 {
1424   AgfaFocus_Scanner *s = handle;
1425   SANE_Status status;
1426 
1427   if (info)
1428     *info = 0;
1429 
1430   if (s->scanning)
1431     return SANE_STATUS_DEVICE_BUSY;
1432 
1433   if (option >= NUM_OPTIONS || !SANE_OPTION_IS_ACTIVE (s->opt[option].cap))
1434     return SANE_STATUS_UNSUPPORTED;
1435 
1436   if (action == SANE_ACTION_GET_VALUE)
1437     {
1438       switch (option)
1439 	{
1440 	case OPT_RESOLUTION:
1441 	case OPT_TL_X:
1442 	case OPT_TL_Y:
1443 	case OPT_BR_X:
1444 	case OPT_BR_Y:
1445 	case OPT_NUM_OPTS:
1446 	case OPT_BRIGHTNESS:
1447 	case OPT_CONTRAST:
1448 	case OPT_SHARPEN:
1449 	case OPT_EXPOSURE:
1450 	case OPT_ATTENUATION_RED:
1451 	case OPT_ATTENUATION_GREEN:
1452 	case OPT_ATTENUATION_BLUE:
1453 	  *(SANE_Word *) val = s->val[option].w;
1454 	  break;
1455 	case OPT_AUTO_BRIGHTNESS:
1456 	case OPT_AUTO_CONTRAST:
1457 	  *(SANE_Bool *) val = s->val[option].b;
1458 	  break;
1459         case OPT_MODE:
1460 	case OPT_HALFTONE_PATTERN:
1461 	case OPT_QUALITY:
1462 	case OPT_SOURCE:
1463           strcpy (val, s->val[option].s);
1464           return (SANE_STATUS_GOOD);
1465 	default:
1466 	  return SANE_STATUS_UNSUPPORTED;
1467 	}
1468 
1469     }
1470   else if (action == SANE_ACTION_SET_VALUE)
1471     {
1472       if (!SANE_OPTION_IS_SETTABLE (s->opt[option].cap))
1473 	return SANE_STATUS_UNSUPPORTED;
1474 
1475       status = sanei_constrain_value (s->opt + option, val, info);
1476       if (status != SANE_STATUS_GOOD)
1477 	return status;
1478 
1479       switch (option)
1480 	{
1481 	case OPT_RESOLUTION:
1482 	case OPT_TL_X:
1483 	case OPT_TL_Y:
1484 	case OPT_BR_X:
1485 	case OPT_BR_Y:
1486 	  if (info)
1487 	    *info |= SANE_INFO_RELOAD_PARAMS;
1488           // fall through
1489 	case OPT_SHARPEN:
1490 	case OPT_EXPOSURE:
1491 	case OPT_ATTENUATION_RED:
1492 	case OPT_ATTENUATION_GREEN:
1493 	case OPT_ATTENUATION_BLUE:
1494 	case OPT_BRIGHTNESS:
1495 	case OPT_CONTRAST:
1496 	  s->val[option].w = *(SANE_Word *) val;
1497 	  break;
1498 	case OPT_AUTO_BRIGHTNESS:
1499 	case OPT_AUTO_CONTRAST:
1500 	  s->val[option].b = *(SANE_Bool *) val;
1501 	  break;
1502         case OPT_MODE:
1503 	  if (strcmp (s->val[option].s, (SANE_String) val))
1504 	    {
1505 	      if (info)
1506 		*info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1507 
1508 	      if (s->val[option].s)
1509 		free (s->val[option].s);
1510 
1511 	      s->val[option].s = strdup (val);
1512 
1513 	      if (strcmp (s->val[option].s, "Gray (6 bit)") == 0)
1514 		s->mode = GRAY6BIT;
1515 	      else if (strcmp (s->val[option].s, "Gray (8 bit)") == 0)
1516 		s->mode = GRAY8BIT;
1517 	      else if (strcmp (s->val[option].s, "Color (18 bit)") == 0)
1518 		s->mode = COLOR18BIT;
1519 	      else if (strcmp (s->val[option].s, "Color (24 bit)") == 0)
1520 		s->mode = COLOR24BIT;
1521 	      else
1522 		s->mode = LINEART;
1523 
1524 	      switch (s->mode)
1525 		{
1526 		case LINEART:
1527 		  s->opt[OPT_HALFTONE_PATTERN].cap &= ~SANE_CAP_INACTIVE;
1528 		  s->opt[OPT_SHARPEN].cap &= ~SANE_CAP_INACTIVE;
1529 		  s->opt[OPT_EXPOSURE].cap |= SANE_CAP_INACTIVE;
1530 		  s->opt[OPT_ATTENUATION_RED].cap |= SANE_CAP_INACTIVE;
1531 		  s->opt[OPT_ATTENUATION_GREEN].cap |= SANE_CAP_INACTIVE;
1532 		  s->opt[OPT_ATTENUATION_BLUE].cap |= SANE_CAP_INACTIVE;
1533 		  s->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
1534 		  s->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
1535 		  s->opt[OPT_AUTO_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
1536 		  s->opt[OPT_AUTO_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
1537 		  break;
1538 
1539 		case GRAY6BIT:
1540 		  s->opt[OPT_SHARPEN].cap &= ~SANE_CAP_INACTIVE;
1541 		  s->opt[OPT_EXPOSURE].cap |= SANE_CAP_INACTIVE;
1542 		  s->opt[OPT_ATTENUATION_RED].cap |= SANE_CAP_INACTIVE;
1543 		  s->opt[OPT_ATTENUATION_GREEN].cap |= SANE_CAP_INACTIVE;
1544 		  s->opt[OPT_ATTENUATION_BLUE].cap |= SANE_CAP_INACTIVE;
1545 		  s->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
1546 		  s->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
1547 		  s->opt[OPT_AUTO_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
1548 		  s->opt[OPT_AUTO_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
1549 		  s->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
1550 		  break;
1551 
1552 		case GRAY8BIT:
1553 		  s->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
1554 		  s->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
1555 		  s->opt[OPT_AUTO_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
1556 		  s->opt[OPT_AUTO_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
1557 		  s->opt[OPT_EXPOSURE].cap |= SANE_CAP_INACTIVE;
1558 		  s->opt[OPT_ATTENUATION_RED].cap |= SANE_CAP_INACTIVE;
1559 		  s->opt[OPT_ATTENUATION_GREEN].cap |= SANE_CAP_INACTIVE;
1560 		  s->opt[OPT_ATTENUATION_BLUE].cap |= SANE_CAP_INACTIVE;
1561 		  s->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
1562 		  s->opt[OPT_SHARPEN].cap |= SANE_CAP_INACTIVE;
1563 		  break;
1564 
1565 		case COLOR18BIT:
1566 		  s->opt[OPT_EXPOSURE].cap &= ~SANE_CAP_INACTIVE;
1567 		  s->opt[OPT_ATTENUATION_RED].cap &= ~SANE_CAP_INACTIVE;
1568 		  s->opt[OPT_ATTENUATION_GREEN].cap &= ~SANE_CAP_INACTIVE;
1569 		  s->opt[OPT_ATTENUATION_BLUE].cap &= ~SANE_CAP_INACTIVE;
1570 		  s->opt[OPT_BRIGHTNESS].cap |=  SANE_CAP_INACTIVE;
1571 		  s->opt[OPT_CONTRAST].cap |=  SANE_CAP_INACTIVE;
1572 		  s->opt[OPT_AUTO_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
1573 		  s->opt[OPT_AUTO_CONTRAST].cap |= SANE_CAP_INACTIVE;
1574 		  s->opt[OPT_SHARPEN].cap &= ~SANE_CAP_INACTIVE;
1575 		  s->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
1576 		  break;
1577 
1578 		case COLOR24BIT:
1579 		  s->opt[OPT_EXPOSURE].cap &= ~SANE_CAP_INACTIVE;
1580 		  s->opt[OPT_ATTENUATION_RED].cap &= ~SANE_CAP_INACTIVE;
1581 		  s->opt[OPT_ATTENUATION_GREEN].cap &= ~SANE_CAP_INACTIVE;
1582 		  s->opt[OPT_ATTENUATION_BLUE].cap &= ~SANE_CAP_INACTIVE;
1583 		  s->opt[OPT_BRIGHTNESS].cap |=  SANE_CAP_INACTIVE;
1584 		  s->opt[OPT_CONTRAST].cap |=  SANE_CAP_INACTIVE;
1585 		  s->opt[OPT_AUTO_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
1586 		  s->opt[OPT_AUTO_CONTRAST].cap |= SANE_CAP_INACTIVE;
1587 		  s->opt[OPT_SHARPEN].cap |= SANE_CAP_INACTIVE;
1588 		  s->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
1589 		  break;
1590 		}
1591 	    }
1592 	  break;
1593 	case OPT_SOURCE:
1594 	case OPT_QUALITY:
1595 	case OPT_HALFTONE_PATTERN:
1596           if (info && strcmp (s->val[option].s, (SANE_String) val))
1597             *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1598           if (s->val[option].s)
1599             free (s->val[option].s);
1600           s->val[option].s = strdup (val);
1601 	  break;
1602 	default:
1603 	  return SANE_STATUS_UNSUPPORTED;
1604 	}
1605 
1606     }
1607   else
1608     {
1609       return SANE_STATUS_UNSUPPORTED;
1610     }
1611 
1612   return SANE_STATUS_GOOD;
1613 }
1614 
1615 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)1616 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
1617 {
1618   AgfaFocus_Scanner *s = handle;
1619 
1620   if (!s->scanning)
1621     {
1622       double width, height, dpi;
1623       const char *quality;
1624       const char *original;
1625 
1626       memset (&s->params, 0, sizeof (s->params));
1627 
1628       width = SANE_UNFIX (s->val[OPT_BR_X].w - s->val[OPT_TL_X].w);
1629       height = SANE_UNFIX (s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w);
1630       dpi = s->val[OPT_RESOLUTION].w;
1631 
1632       /* make best-effort guess at what parameters will look like once
1633          scanning starts.  */
1634       if (dpi > 0.0 && width > 0.0 && height > 0.0)
1635 	{
1636 	  double dots_per_mm = dpi / MM_PER_INCH;
1637 
1638 	  s->params.pixels_per_line = width * dots_per_mm + 0.5;
1639 	  s->params.lines = height * dots_per_mm + 0.5;
1640 	}
1641 
1642       /* Should we specify calibration quality? */
1643 
1644       if (SANE_OPTION_IS_ACTIVE (s->opt[OPT_QUALITY].cap))
1645         {
1646           DBG(3, " -------------- setting quality\n");
1647           quality = s->val[OPT_QUALITY].s;
1648           if (strcmp (quality, "Low") == 0 )
1649 	    s->quality = 255;
1650           else if (strcmp (quality, "High") == 0)
1651 	    s->quality = 1;
1652           else
1653 	    s->quality = 0;
1654         }
1655       else
1656         s->quality = 0;
1657 
1658       /* Should we select source type? */
1659 
1660       if (SANE_OPTION_IS_ACTIVE (s->opt[OPT_SOURCE].cap))
1661         {
1662           DBG(3, " -------------- setting source\n");
1663           original = s->val[OPT_SOURCE].s;
1664           if (strcmp (original, "Transparency") == 0)
1665 	    s->original = 0;
1666           else
1667 	    s->original = 1;
1668         }
1669       else
1670         s->original = 0;
1671 
1672       s->exposure = ((s->val[OPT_EXPOSURE].w * (255.0f - 80.0f)) / 100.0f) + 80.0f;
1673       s->r_att = (SANE_UNFIX (s->val[OPT_ATTENUATION_RED].w) * 20.0f) / 100.0f;
1674       s->g_att = (SANE_UNFIX (s->val[OPT_ATTENUATION_GREEN].w) * 20.0f) / 100.0f;
1675       s->b_att = (SANE_UNFIX (s->val[OPT_ATTENUATION_BLUE].w) * 20.0f) / 100.0f;
1676       s->tonecurve = 0;
1677 
1678       switch (s->mode)
1679 	{
1680 	case LINEART:
1681 	  {
1682 	    const char *halftone;
1683 
1684 	    s->image_composition = 0;
1685 
1686 	    /* in 1 bpp mode, lines need to be 8 pixel length */
1687 
1688 	    if (s->params.pixels_per_line % 8)
1689 	      s->params.pixels_per_line += 8 - (s->params.pixels_per_line % 8);
1690 
1691 	    s->params.format = SANE_FRAME_GRAY;
1692 	    s->params.bytes_per_line = s->params.pixels_per_line / 8;
1693 	    s->bpp = s->params.depth = 1;
1694 
1695 	    halftone = s->val[OPT_HALFTONE_PATTERN].s;
1696 	    if (strcmp (halftone, "1") == 0 )
1697 	      s->halftone = 1;
1698 	    else if (strcmp (halftone, "Dispersed dot 4x4") == 0)
1699 	      s->halftone = 2;
1700 	    else if (strcmp (halftone, "Round (Clustered dot 4x4)") == 0)
1701 	      s->halftone = 3;
1702 	    else if (strcmp (halftone, "Diamond (Clustered dot 4x4)") == 0)
1703 	      s->halftone = 4;
1704 	    else if (strcmp (halftone, "User defined") == 0)
1705 	      s->halftone = 5;
1706 	    else
1707 	      s->halftone = 0;
1708 
1709 	    s->edge = s->val[OPT_SHARPEN].w;
1710 	  }
1711 	  break;
1712 
1713 	case GRAY6BIT:
1714 	  s->image_composition = 2;
1715 
1716           s->params.format = SANE_FRAME_GRAY;
1717           s->params.bytes_per_line = s->params.pixels_per_line;
1718 	  s->bpp = 6;
1719 	  s->params.depth = 8;
1720 	  s->edge = s->val[OPT_SHARPEN].w;
1721 
1722 	  break;
1723 
1724 	case GRAY8BIT:
1725 	  s->image_composition = 2;
1726 
1727           s->params.format = SANE_FRAME_GRAY;
1728           s->params.bytes_per_line = s->params.pixels_per_line;
1729 	  s->bpp = s->params.depth = 8;
1730 
1731 	  break;
1732 
1733 	case COLOR18BIT:
1734 	  s->image_composition = 5;
1735 
1736           s->params.format = SANE_FRAME_RED;
1737           s->params.bytes_per_line = s->params.pixels_per_line;
1738 	  s->bpp = 6;
1739 	  s->params.depth = 8;
1740 	  s->edge = s->val[OPT_SHARPEN].w;
1741 
1742 	  break;
1743 
1744 	case COLOR24BIT:
1745 	  s->image_composition = 5;
1746 
1747           s->params.format = SANE_FRAME_RED;
1748           s->params.bytes_per_line = s->params.pixels_per_line;
1749           s->bpp = s->params.depth = 8;
1750 
1751 	  break;
1752         }
1753 
1754       s->pass = 0;
1755 
1756       /*s->params.bytes_per_line =
1757 	(s->params.pixels_per_line + (8 - s->params.depth))
1758 	/ (8 / s->params.depth);*/
1759     }
1760   else
1761     if (s->mode == COLOR18BIT ||
1762 	s->mode == COLOR24BIT)
1763       s->params.format = SANE_FRAME_RED + s->pass;
1764 
1765   s->params.last_frame = (s->params.format != SANE_FRAME_RED && s->params.format != SANE_FRAME_GREEN);
1766 
1767   if (params)
1768     *params = s->params;
1769   return SANE_STATUS_GOOD;
1770 }
1771 
1772 /* This function is executed as a child process.  The reason this is
1773    executed as a subprocess is because some (most?) generic SCSI
1774    interfaces block a SCSI request until it has completed.  With a
1775    subprocess, we can let it block waiting for the request to finish
1776    while the main process can go about to do more important things
1777    (such as recognizing when the user presses a cancel button).
1778 
1779 
1780    WARNING: Since this is executed as a subprocess, it's NOT possible
1781    to update any of the variables in the main process (in particular
1782    the scanner state cannot be updated).  */
1783 static int
reader_process(void * scanner)1784 reader_process (void *scanner)
1785 {
1786   AgfaFocus_Scanner *s = (AgfaFocus_Scanner *) scanner;
1787   int fd = s->reader_pipe;
1788 
1789   SANE_Status status;
1790   SANE_Byte *data;
1791   int lines_read = 0;
1792   int lines_per_buffer;
1793   int bytes_per_line = 0, total_lines = 0;
1794   int i;
1795   sigset_t sigterm_set;
1796   sigset_t ignore_set;
1797   struct SIGACTION act;
1798 
1799   if (sanei_thread_is_forked()) close (s->pipe);
1800 
1801   sigfillset (&ignore_set);
1802   sigdelset (&ignore_set, SIGTERM);
1803 #if defined (__APPLE__) && defined (__MACH__)
1804   sigdelset (&ignore_set, SIGUSR2);
1805 #endif
1806   sigprocmask (SIG_SETMASK, &ignore_set, 0);
1807 
1808   memset (&act, 0, sizeof (act));
1809   sigaction (SIGTERM, &act, 0);
1810 
1811   sigemptyset (&sigterm_set);
1812   sigaddset (&sigterm_set, SIGTERM);
1813 
1814   if (!s->hw->disconnect)
1815     wait_ready (s->fd);
1816 
1817   status = get_read_sizes (s->fd, &s->lines_available, &bytes_per_line, &total_lines);
1818   if (status != SANE_STATUS_GOOD)
1819     {
1820       DBG (1, "open: get_read_sizes() failed: %s\n",
1821 	   sane_strstatus (status));
1822       do_cancel (s);
1823       close (fd);
1824       return 1;
1825     }
1826 
1827   if (!s->lines_available || !bytes_per_line || !total_lines || bytes_per_line < s->params.bytes_per_line)
1828     {
1829       DBG (1, "open: invalid sizes: %d, %d, %d\n",
1830 	   s->lines_available, bytes_per_line, total_lines);
1831       do_cancel (s);
1832       close (fd);
1833       return 1;
1834     }
1835 
1836   lines_per_buffer = sanei_scsi_max_request_size / bytes_per_line;
1837   if (!lines_per_buffer)
1838     {
1839       close (fd);
1840       return 2;			/* resolution is too high */
1841     }
1842 
1843   data = malloc (lines_per_buffer * bytes_per_line);
1844   if (!data)
1845     {
1846       DBG (1, "open  malloc(%lu) failed.\n", (u_long) lines_per_buffer * bytes_per_line);
1847       do_cancel (s);
1848       close (fd);
1849       return 1;
1850     }
1851 
1852   while (lines_read < s->params.lines)
1853     {
1854       int lines = lines_per_buffer;
1855 
1856       if (s->lines_available == 0)
1857 	{
1858 	  /* No lines in scanner?  Scan some more */
1859 	  status = request_more_data (s);
1860 
1861 	  if (status != SANE_STATUS_GOOD)
1862 	    {
1863 	      close (fd);
1864 	      return 1;
1865 	    }
1866 	}
1867 
1868       /* We only request as many lines as there are already scanned */
1869       if (lines > s->lines_available)
1870 	lines = s->lines_available;
1871 
1872       DBG (1, "Requesting %d lines, in scanner: %d, total: %d\n", lines,
1873 	   s->lines_available, s->params.lines);
1874 
1875       status = read_data (s, data, lines, bytes_per_line);
1876 
1877       if (status != SANE_STATUS_GOOD)
1878 	{
1879 	  DBG (1, "sane_read: read_data() failed (%s)\n",
1880 	       sane_strstatus (status));
1881 	  do_cancel (s);
1882 	  close (fd);
1883 	  return 1;
1884 	}
1885 
1886       /* Sometimes the scanner will return more bytes per line than
1887          requested, so we copy only what we wanted. */
1888 
1889       for (i = 0; i < lines; i++)
1890 	if (write (fd, data + i * bytes_per_line, s->params.bytes_per_line) != s->params.bytes_per_line)
1891 	  {
1892 	    do_cancel (s);
1893 	    close (fd);
1894 	    return 1;
1895 	  }
1896 
1897       lines_read += lines;
1898     }
1899 
1900   close (fd);
1901   return 0;
1902 }
1903 
1904 SANE_Status
sane_start(SANE_Handle handle)1905 sane_start (SANE_Handle handle)
1906 {
1907   AgfaFocus_Scanner *s = handle;
1908   SANE_Status status;
1909   int fds[2];
1910 
1911   /* First make sure we have a current parameter set.  Some of the
1912      parameters will be overwritten below, but that's OK.  */
1913 
1914   status = sane_get_parameters (s, 0);
1915   if (status != SANE_STATUS_GOOD)
1916     return status;
1917 
1918   /* don't initialise scanner if we're doing a three-pass scan */
1919 
1920   if (s->pass == 0)
1921     {
1922       if (s->fd < 0)
1923 	{
1924 	  status = sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, 0);
1925 	  if (status != SANE_STATUS_GOOD)
1926 	    {
1927 	      DBG (1, "open: open of %s failed: %s\n",
1928 		   s->hw->sane.name, sane_strstatus (status));
1929 	      s->fd = -1;
1930 	      return status;
1931 	    }
1932 	}
1933 
1934       status = test_ready (s->fd);
1935       if (status != SANE_STATUS_GOOD)
1936 	{
1937 	  DBG (1, "open: test_ready() failed: %s\n", sane_strstatus (status));
1938 	  sanei_scsi_close (s->fd);
1939 	  s->fd = -1;
1940 	  return status;
1941 	}
1942 
1943       status = reserve_unit (s->fd);
1944       if (status != SANE_STATUS_GOOD)
1945 	{
1946 	  DBG (1, "open: reserve_unit() failed: %s\n", sane_strstatus (status));
1947 	  sanei_scsi_close (s->fd);
1948 	  s->fd = -1;
1949 	  return status;
1950 	}
1951 
1952       status = set_window (s);
1953       if (status != SANE_STATUS_GOOD)
1954 	{
1955 	  DBG (1, "open: set_window() failed: %s\n", sane_strstatus (status));
1956 	  release_unit (s->fd);
1957 	  sanei_scsi_close (s->fd);
1958 	  s->fd = -1;
1959 	  return status;
1960 	}
1961 
1962       {
1963 	int matrix[256] = {
1964 	   2, 60, 16, 56,  3, 57, 13, 53,
1965 	  34, 18, 48, 32, 35, 19, 45, 29,
1966 	  10, 50,  6, 63, 11, 51,  7, 61,
1967 	  42, 26, 38, 22, 43, 27, 39, 23,
1968 	   4, 58, 14, 54,  1, 59, 15, 55,
1969 	  36, 20, 46, 30, 33, 17, 47, 31,
1970 	  12, 52,  8, 62,  9, 49,  5, 63,
1971 	  44, 28, 40, 24, 41, 25, 37, 21
1972 	};
1973 
1974 	status = upload_dither_matrix (s, 8, 8, matrix);
1975 	if (status != SANE_STATUS_GOOD)
1976 	  {
1977 	    DBG (1, "open: upload_dither_matrix() failed: %s\n", sane_strstatus (status));
1978 	    release_unit (s->fd);
1979 	    sanei_scsi_close (s->fd);
1980 	    s->fd = -1;
1981 	    return status;
1982 	  }
1983       }
1984 
1985       s->scanning = SANE_TRUE;
1986 
1987       status = start_scan (s->fd, SANE_FALSE);
1988       if (status != SANE_STATUS_GOOD)
1989 	{
1990 	  DBG (1, "open: start_scan() failed: %s\n", sane_strstatus (status));
1991 	  do_cancel (s);
1992 	  return status;
1993 	}
1994     }
1995   else
1996     {
1997       /* continue three-pass scan */
1998 
1999       status = start_scan (s->fd, SANE_TRUE);
2000       if (status != SANE_STATUS_GOOD)
2001 	{
2002 	  DBG (1, "open: start_scan() failed: %s\n", sane_strstatus (status));
2003 	  do_cancel (s);
2004 	  return status;
2005 	}
2006     }
2007 
2008   if (pipe (fds) < 0)
2009     return SANE_STATUS_IO_ERROR;
2010 
2011   s->pipe = fds[0];
2012   s->reader_pipe = fds[1];
2013   s->reader_pid = sanei_thread_begin (reader_process, (void *) s);
2014 
2015   if (sanei_thread_is_forked()) close (s->reader_pipe);
2016 
2017   return SANE_STATUS_GOOD;
2018 }
2019 
2020 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)2021 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
2022 	   SANE_Int * len)
2023 {
2024   AgfaFocus_Scanner *s = handle;
2025   ssize_t nread;
2026 
2027   *len = 0;
2028 
2029   nread = read (s->pipe, buf, max_len);
2030   DBG (3, "read %ld bytes\n", (long) nread);
2031 
2032   if (!s->scanning)
2033     return do_cancel (s);
2034 
2035   if (nread < 0) {
2036     if (errno == EAGAIN) {
2037       return SANE_STATUS_GOOD;
2038     } else {
2039       do_cancel (s);
2040       return SANE_STATUS_IO_ERROR;
2041     }
2042   }
2043 
2044   *len = nread;
2045 
2046   if (nread == 0) {
2047     s->pass++;
2048     return do_eof (s);
2049   }
2050   return SANE_STATUS_GOOD;
2051 }
2052 
2053 void
sane_cancel(SANE_Handle handle)2054 sane_cancel (SANE_Handle handle)
2055 {
2056   AgfaFocus_Scanner *s = handle;
2057 
2058   if (sanei_thread_is_valid (s->reader_pid))
2059     sanei_thread_kill (s->reader_pid);
2060   s->scanning = SANE_FALSE;
2061 }
2062 
2063 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)2064 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
2065 {
2066   AgfaFocus_Scanner *s = handle;
2067 
2068   if (!s->scanning)
2069     return SANE_STATUS_INVAL;
2070 
2071   if (fcntl (s->pipe, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0)
2072     return SANE_STATUS_IO_ERROR;
2073 
2074   return SANE_STATUS_GOOD;
2075 }
2076 
2077 SANE_Status
sane_get_select_fd(SANE_Handle handle,SANE_Int * fd)2078 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
2079 {
2080   AgfaFocus_Scanner *s = handle;
2081 
2082   if (!s->scanning)
2083     return SANE_STATUS_INVAL;
2084 
2085   *fd = s->pipe;
2086   return SANE_STATUS_GOOD;
2087 }
2088