1 /* --------------------------------------------------------------------------------------------------------- */
2 
3 /* sane - Scanner Access Now Easy.
4 
5    umax.c
6 
7    (C) 1997-2007 Oliver Rauch
8 
9    This file is part of the SANE package.
10 
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2 of the
14    License, or (at your option) any later version.
15 
16    This program is distributed in the hope that it will be useful, but
17    WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    General Public License for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <https://www.gnu.org/licenses/>.
23 
24    As a special exception, the authors of SANE give permission for
25    additional uses of the libraries contained in this release of SANE.
26 
27    The exception is that, if you link a SANE library with other files
28    to produce an executable, this does not by itself cause the
29    resulting executable to be covered by the GNU General Public
30    License.  Your use of that executable is in no way restricted on
31    account of linking the SANE library code into it.
32 
33    This exception does not, however, invalidate any other reasons why
34    the executable file might be covered by the GNU General Public
35    License.
36 
37    If you submit changes to SANE to the maintainers to be included in
38    a subsequent release, you agree by submitting the changes that
39    those changes may be distributed with this exception intact.
40 
41    If you write modifications of your own for SANE, it is your choice
42    whether to permit this exception to apply to your modifications.
43    If you do not wish that, delete this exception notice.
44 
45    This file implements a SANE backend for UMAX flatbed scanners.  */
46 
47 
48 /* --------------------------------------------------------------------------------------------------------- */
49 
50 #define BUILD 45
51 
52 /* --------------------------------------------------------------------------------------------------------- */
53 
54 
55 /* SANE-FLOW-DIAGRAMM
56 
57 	- sane_init() : initialize backend, attach scanners(devicename,0)
58 	. - sane_get_devices() : query list of scanner-devices
59 	. - sane_open() : open a particular scanner-device and attach_scanner(devicename,&dev)
60 	. . - sane_set_io_mode : set blocking-mode
61 	. . - sane_get_select_fd : get scanner-fd
62 	. . - sane_get_option_descriptor() : get option information
63 	. . - sane_control_option() : change option values
64 	. .
65 	. . - sane_start() : start image acquisition
66 	. .   - sane_get_parameters() : returns actual scan-parameters
67 	. .   - sane_read() : read image-data (from pipe)
68 in ADF mode this is done often:
69 	. . - sane_start() : start image acquisition
70 	. .   - sane_get_parameters() : returns actual scan-parameters
71 	. .   - sane_read() : read image-data (from pipe)
72 
73 	. . - sane_cancel() : cancel operation, kill reader_process
74 
75 	. - sane_close() : close opened scanner-device, do_cancel, free buffer and handle
76 	- sane_exit() : terminate use of backend, free devicename and device-struture
77 */
78 
79 
80 /* ------------------------------------------------------------ DBG OUTPUT LEVELS -------------------------- */
81 
82 
83 #define DBG_error0  0
84 #define DBG_error   1
85 #define DBG_sense   2
86 #define DBG_warning 3
87 #define DBG_inquiry 4
88 #define DBG_info    5
89 #define DBG_info2   6
90 #define DBG_proc    7
91 #define DBG_read    8
92 #define DBG_sane_init   10
93 #define DBG_sane_proc   11
94 #define DBG_sane_info   12
95 #define DBG_sane_option 13
96 
97 
98 /* ------------------------------------------------------------ SANE DEFINES ------------------------------- */
99 
100 #define BACKEND_NAME     umax
101 #define UMAX_CONFIG_FILE "umax.conf"
102 
103 /* ------------------------------------------------------------ SANE INTERNATIONALISATION ------------------ */
104 
105 #ifndef SANE_I18N
106 #define SANE_I18N(text) text
107 #endif
108 
109 /* ------------------------------------------------------------ INCLUDES ----------------------------------- */
110 
111 #include "../include/sane/config.h"
112 
113 #include <errno.h>
114 #include <fcntl.h>
115 #include <limits.h>
116 #include <signal.h>
117 #include <stdio.h>
118 #include <stdlib.h>
119 #include <string.h>
120 #include <sys/types.h>
121 #include <sys/wait.h>
122 #include <unistd.h>
123 
124 #include "../include/sane/sane.h"
125 #include "../include/sane/sanei.h"
126 #include "../include/sane/saneopts.h"
127 #include "../include/sane/sanei_scsi.h"
128 #include "../include/sane/sanei_debug.h"
129 #include "../include/sane/sanei_backend.h"
130 #include "../include/sane/sanei_config.h"
131 #include "../include/sane/sanei_thread.h"
132 
133 #ifdef UMAX_ENABLE_USB
134 # include "sane/sanei_usb.h"
135 #endif
136 
137 #include <math.h>
138 #include <string.h>
139 
140 #include "umax-scsidef.h"
141 #include "umax-scanner.c"
142 
143 #ifdef UMAX_ENABLE_USB
144 # include "umax-usb.c"
145 #endif
146 
147 #include "umax.h"
148 
149 /* ------------------------------------------------------------ SANE DEFINES ------------------------------- */
150 
151 #ifndef PATH_MAX
152 #define PATH_MAX         1024
153 #endif
154 
155 /* ------------------------------------------------------------ OPTION DEFINITIONS ------------------------- */
156 
157 #define SANE_NAME_BATCH_SCAN_START	"batch-scan-start"
158 #define SANE_TITLE_BATCH_SCAN_START	"Batch scan start"
159 #define SANE_DESC_BATCH_SCAN_START	"set for first scan of batch"
160 
161 #define SANE_NAME_BATCH_SCAN_LOOP	"batch-scan-loop"
162 #define SANE_TITLE_BATCH_SCAN_LOOP	"Batch scan loop"
163 #define SANE_DESC_BATCH_SCAN_LOOP	"set for middle scans of batch"
164 
165 #define SANE_NAME_BATCH_SCAN_END	"batch-scan-end"
166 #define SANE_TITLE_BATCH_SCAN_END	"Batch scan end"
167 #define SANE_DESC_BATCH_SCAN_END	"set for last scan of batch"
168 
169 #define SANE_NAME_BATCH_NEXT_TL_Y	"batch-scan-next-tl-y"
170 #define SANE_TITLE_BATCH_NEXT_TL_Y	"Batch scan next top left Y"
171 #define SANE_DESC_BATCH_NEXT_TL_Y	"Set top left Y position for next scan"
172 
173 #define SANE_UMAX_NAME_SELECT_CALIBRATON_EXPOSURE_TIME		"select-calibration-exposure-time"
174 #define SANE_UMAX_TITLE_SELECT_CALIBRATION_EXPOSURE_TIME	"Set calibration exposure time"
175 #define SANE_UMAX_DESC_SELECT_CALIBRATION_EXPOSURE_TIME		"Allow different settings for calibration and scan exposure times"
176 
177 /* ------------------------------------------------------------ STRING DEFINITIONS ------------------------- */
178 
179 #define FLB_STR			SANE_I18N("Flatbed")
180 #define UTA_STR			SANE_I18N("Transparency Adapter")
181 #define ADF_STR 		SANE_I18N("Automatic Document Feeder")
182 
183 #define LINEART_STR		SANE_VALUE_SCAN_MODE_LINEART
184 #define HALFTONE_STR		SANE_VALUE_SCAN_MODE_HALFTONE
185 #define GRAY_STR		SANE_VALUE_SCAN_MODE_GRAY
186 #define COLOR_LINEART_STR	SANE_VALUE_SCAN_MODE_COLOR_LINEART
187 #define COLOR_HALFTONE_STR	SANE_VALUE_SCAN_MODE_COLOR_HALFTONE
188 #define COLOR_STR		SANE_VALUE_SCAN_MODE_COLOR
189 
190 /* ------------------------------------------------------------ DEFINITIONS -------------------------------- */
191 
192 #define P_200_TO_255(per) ( (SANE_UNFIX(per) + 100) * 255/200 )
193 #define P_100_TO_255(per) SANE_UNFIX(per * 255/100 )
194 #define P_100_TO_254(per) 1+SANE_UNFIX(per * 254/100 )
195 
196 /* ------------------------------------------------------------ GLOBAL VARIABLES --------------------------- */
197 
198 
199 static SANE_String scan_mode_list[7];
200 static SANE_String_Const source_list[4];
201 static SANE_Int bit_depth_list[9];
202 static SANE_Auth_Callback frontend_authorize_callback;
203 
204 static int umax_scsi_buffer_size_min = 32768;  /* default: minimum scsi buffer size: 32 KB */
205 static int umax_scsi_buffer_size_max = 131072; /* default: maximum scsi buffer size: 128 KB */
206 
207 /* number of lines that shall be scanned in one buffer for preview if possible */
208 /* this value should not be too large because it defines the step size in which */
209 /* the scanned parts are displayed while preview scan is in progress */
210 static int umax_preview_lines                  = 10; /* default: 10 preview lines */
211 /* number of lines that shall be scanned in one buffer for scan if possible */
212 static int umax_scan_lines                     = 40; /* default: 40 scan lines */
213 static int umax_scsi_maxqueue                  = 2; /* use command queueing depth 2 as default */
214 static int umax_handle_bad_sense_error         = 0; /* default: handle bad sense error code as device busy */
215 static int umax_execute_request_sense          = 0; /* default: do not use request sense in do_calibration */
216 static int umax_force_preview_bit_rgb          = 0; /* default: do not force preview bit in real color scan */
217 static int umax_slow                           = -1; /* don`t use slow scanning speed */
218 static int umax_smear                          = -1; /* don`t care about image smearing problem */
219 static int umax_calibration_area               = -1;   /* -1=auto, 0=calibration on image, 1=calibration for full ccd */
220 static int umax_calibration_width_offset       = -99999; /* -99999=auto */
221 static int umax_calibration_width_offset_batch = -99999; /* -99999=auto */
222 static int umax_calibration_bytespp            = -1;   /* -1=auto */
223 static int umax_exposure_time_rgb_bind         = -1;   /* -1=auto */
224 static int umax_invert_shading_data            = -1;   /* -1=auto */
225 static int umax_lamp_control_available         = 0;    /* 0=disabled */
226 static int umax_gamma_lsb_padded               = -1;   /* -1=auto */
227 static int umax_connection_type                = 1;    /* 1=scsi, 2=usb */
228 
229 /* ------------------------------------------------------------ CALIBRATION MODE --------------------------- */
230 
231 #ifdef UMAX_CALIBRATION_MODE_SELECTABLE
232 
233 #define CALIB_MODE_0000		SANE_I18N("Use Image Composition")
234 #define CALIB_MODE_1111		SANE_I18N("Bi-level black and white (lineart mode)")
235 #define CALIB_MODE_1110		SANE_I18N("Dithered/halftone black & white (halftone mode)")
236 #define CALIB_MODE_1101		SANE_I18N("Multi-level black & white (grayscale mode)")
237 #define CALIB_MODE_1010		SANE_I18N("Multi-level RGB color (one pass color)")
238 #define CALIB_MODE_1001		SANE_I18N("Ignore calibration")
239 
240 static SANE_String_Const calibration_list[] =
241 {
242     CALIB_MODE_0000,
243     CALIB_MODE_1111,
244     CALIB_MODE_1110,
245     CALIB_MODE_1101,
246     CALIB_MODE_1010,
247     CALIB_MODE_1001,
248     0
249 };
250 
251 #endif
252 
253 /* --------------------------------------------------------------------------------------------------------- */
254 
255 enum
256 {
257     UMAX_CALIBRATION_AREA_IMAGE = 0,
258     UMAX_CALIBRATION_AREA_CCD
259 };
260 
261 static const SANE_Int pattern_dim_list[] =
262 {
263   5, /* # of elements */
264   2, 4, 6, 8, 12
265 };
266 
267 static const SANE_Range u8_range =
268 {
269     0, /* minimum */
270   255, /* maximum */
271     0  /* quantization */
272 };
273 
274 static const SANE_Range percentage_range =
275 {
276   SANE_FIX(-100), /* minimum */
277   SANE_FIX( 100), /* maximum */
278   SANE_FIX(   1)  /* quantization */
279 };
280 
281 static const SANE_Range percentage_range_100 =
282 {
283   SANE_FIX(  0), /* minimum */
284   SANE_FIX(100), /* maximum */
285   SANE_FIX(  0)  /* quantization */
286 };
287 
288 static int num_devices = 0;
289 static const SANE_Device **devlist = NULL;
290 static Umax_Device *first_dev      = NULL;
291 static Umax_Scanner *first_handle  = NULL;
292 
293 
294 /* ------------------------------------------------------------ MATH-HELPERS ------------------------------- */
295 
296 
297 #define min(a, b) (((a)<(b))?(a):(b))
298 #define max(a, b) (((a)>(b))?(a):(b))
299 #define inrange(minimum, val, maximum) (min(maximum, max(val, minimum)))
300 
301 
302 /* ------------------------------------------------------------ umax_test_little_endian -------------------- */
303 
umax_test_little_endian(void)304 static SANE_Bool umax_test_little_endian(void)
305 {
306   SANE_Int testvalue = 255;
307   unsigned char *firstbyte = (unsigned char *) &testvalue;
308 
309   if (*firstbyte == 255)
310   {
311     return SANE_TRUE;
312   }
313 
314   return SANE_FALSE;
315 }
316 
317 /* ------------------------------------------------------------ DBG_inq_nz --------------------------------- */
318 
319 
DBG_inq_nz(char *text, int flag)320 static void DBG_inq_nz(char *text, int flag)
321 {
322   if (flag != 0) { DBG(DBG_inquiry,"%s", text); }
323 }
324 
325 
326 /*------------------------------------------------------------- DBG_sense_nz ------------------------------- */
327 
328 
DBG_sense_nz(char *text, int flag)329 static void DBG_sense_nz(char *text, int flag)
330 {
331   if (flag != 0) { DBG(DBG_sense,"%s", text); }
332 }
333 
334 
335 /* ------------------------------------------------------------ UMAX PRINT INQUIRY ------------------------- */
336 
337 
umax_print_inquiry(Umax_Device *dev)338 static void umax_print_inquiry(Umax_Device *dev)
339 {
340  unsigned char *inquiry_block;
341  int i;
342 
343   inquiry_block=dev->buffer[0];
344 
345   DBG(DBG_inquiry,"INQUIRY:\n");
346   DBG(DBG_inquiry,"========\n");
347   DBG(DBG_inquiry,"\n");
348   DBG(DBG_inquiry,"vendor........................: '%s'\n", dev->vendor);
349   DBG(DBG_inquiry,"product.......................: '%s'\n", dev->product);
350   DBG(DBG_inquiry,"version.......................: '%s'\n", dev->version);
351 
352   DBG(DBG_inquiry,"peripheral qualifier..........: %d\n", get_inquiry_periph_qual(inquiry_block));
353   DBG(DBG_inquiry,"peripheral device type........: %d\n", get_inquiry_periph_devtype(inquiry_block));
354 
355   DBG_inq_nz("RMB bit set (reserved)\n", get_inquiry_rmb(inquiry_block));
356   DBG_inq_nz("0x01 bit 6\n", get_inquiry_0x01_bit6(inquiry_block));
357   DBG_inq_nz("0x01 bit 5\n", get_inquiry_0x01_bit5(inquiry_block));
358 
359   DBG(DBG_inquiry,"\n");
360   DBG(DBG_inquiry,"CBHS value range..............: %s\n", cbhs_str[dev->inquiry_cbhs]);
361   DBG(DBG_inquiry,"scanmode......................: %s\n", scanmode_str[get_inquiry_scanmode(inquiry_block)]);
362   if (dev->inquiry_transavail)
363   {
364     DBG(DBG_inquiry,"UTA (transparency)............: available\n");
365 
366     if (get_inquiry_translamp(inquiry_block) == 0)
367     { DBG(DBG_inquiry,"UTA lamp status ..............: off\n"); }
368     else
369     { DBG(DBG_inquiry,"UTA lamp status ..............: on\n"); }
370 
371     DBG(DBG_inquiry,"\n");
372   }
373 
374   DBG(DBG_inquiry,"inquiry block length..........: %d bytes\n", dev->inquiry_len);
375   if (dev->inquiry_len<=0x8e)
376   {
377     DBG(DBG_inquiry, "Inquiry block is unexpected short, should be at least 147 bytes\n");
378   }
379 
380   DBG(DBG_inquiry,"\n");
381   DBG(DBG_inquiry,"ISO  Version (reserved).......: %d\n", get_inquiry_iso_version(inquiry_block));
382   DBG(DBG_inquiry,"ECMA Version (reserved).......: %d\n", get_inquiry_ecma_version(inquiry_block));
383   DBG(DBG_inquiry,"ANSI Version .................: %d\n", get_inquiry_ansi_version(inquiry_block));
384   DBG(DBG_inquiry,"\n");
385 
386   DBG_inq_nz("AENC bit set (reserved)\n",  get_inquiry_aenc(inquiry_block));
387   DBG_inq_nz("TmIOP bit set (reserved)\n", get_inquiry_tmiop(inquiry_block));
388   DBG_inq_nz("0x03 bit 5\n",               get_inquiry_0x03_bit5(inquiry_block));
389   DBG_inq_nz("0x03 bit 4\n",               get_inquiry_0x03_bit4(inquiry_block));
390 
391   DBG(DBG_inquiry,"reserved byte 0x05 = %d\n", get_inquiry_0x05(inquiry_block));
392   DBG(DBG_inquiry,"reserved byte 0x06 = %d\n", get_inquiry_0x06(inquiry_block));
393 
394   DBG(DBG_inquiry,"\n");
395   DBG(DBG_inquiry,"scsi features (%02x):\n", get_inquiry_scsi_byte(inquiry_block));
396   DBG(DBG_inquiry,"-------------------\n");
397   DBG_inq_nz(" - relative address\n", get_inquiry_scsi_reladr(inquiry_block));
398   DBG_inq_nz(" - wide bus 32 bit\n",  get_inquiry_scsi_wbus32(inquiry_block));
399   DBG_inq_nz(" - wide bus 16 bit\n",  get_inquiry_scsi_wbus16(inquiry_block));
400   DBG_inq_nz(" - synchronous neg.\n", get_inquiry_scsi_sync(inquiry_block));
401   DBG_inq_nz(" - linked commands\n",  get_inquiry_scsi_linked(inquiry_block));
402   DBG_inq_nz(" - (reserved)\n",       get_inquiry_scsi_R(inquiry_block));
403   DBG_inq_nz(" - command queueing\n", get_inquiry_scsi_cmdqueue(inquiry_block));
404   DBG_inq_nz(" - sftre\n",            get_inquiry_scsi_sftre(inquiry_block));
405 
406   /* 0x24 */
407   if (dev->inquiry_len<=0x24)
408   {
409     return;
410   }
411 
412   DBG(DBG_inquiry,"\n");
413   DBG(DBG_inquiry,"f/w support function:\n");
414   DBG(DBG_inquiry,"---------------------\n");
415   DBG_inq_nz(" - quality calibration\n", dev->inquiry_quality_ctrl);
416   DBG_inq_nz(" - fast preview function\n", dev->inquiry_preview);
417   DBG_inq_nz(" - shadow compensation by f/w\n", get_inquiry_fw_shadow_comp(inquiry_block));
418   DBG_inq_nz(" - reselection phase\n", get_inquiry_fw_reselection(inquiry_block));
419   DBG_inq_nz(" - lamp intensity control\n", dev->inquiry_lamp_ctrl);
420   DBG_inq_nz(" - batch scan function\n", get_inquiry_fw_batch_scan(inquiry_block));
421   DBG_inq_nz(" - calibration mode control by driver\n", get_inquiry_fw_calibration(inquiry_block));
422 
423   /* 0x36, 0x37 */
424   DBG(DBG_inquiry,"\n");
425   DBG(DBG_inquiry,"reserved byte 0x36 = %d\n", get_inquiry_0x36(inquiry_block));
426   DBG(DBG_inquiry,"reserved byte 0x37 = %d\n", get_inquiry_0x37(inquiry_block));
427 
428   if (get_inquiry_fw_adjust_exposure_tf(inquiry_block))
429   {
430     int unit;
431 
432     DBG(DBG_inquiry,"\n");
433     DBG(DBG_inquiry,"adjust exposure time function\n");
434     unit=get_inquiry_exposure_time_step_unit(inquiry_block);
435     DBG(DBG_inquiry,"exposure time step units......: %d micro-sec\n", unit);
436     DBG(DBG_inquiry,"exposure time maximum.........: %d micro-sec\n",
437             unit*get_inquiry_exposure_time_max(inquiry_block));
438     DBG(DBG_inquiry,"exposure time minimum (LHG)...: %d micro-sec\n",
439             unit*get_inquiry_exposure_time_lhg_min(inquiry_block));
440     DBG(DBG_inquiry,"exposure time minimum color...: %d micro-sec\n",
441             unit*get_inquiry_exposure_time_color_min(inquiry_block));
442     DBG(DBG_inquiry,"exposure time default FB (LH).: %d micro-sec\n",
443             unit*get_inquiry_exposure_time_lh_def_fb(inquiry_block));
444     DBG(DBG_inquiry,"exposure time default UTA (LH): %d micro-sec\n",
445             unit*get_inquiry_exposure_time_lh_def_uta(inquiry_block));
446     DBG(DBG_inquiry,"exposure time default FB gray.: %d micro-sec\n",
447             unit*get_inquiry_exposure_time_gray_def_fb(inquiry_block));
448     DBG(DBG_inquiry,"exposure time default UTA gray: %d micro-sec\n",
449             unit*get_inquiry_exposure_time_gray_def_uta(inquiry_block));
450     DBG(DBG_inquiry,"exposure time default FB red..: %d micro-sec\n",
451             unit*get_inquiry_exposure_time_def_r_fb(inquiry_block));
452     DBG(DBG_inquiry,"exposure time default FB grn..: %d micro-sec\n",
453             unit*get_inquiry_exposure_time_def_g_fb(inquiry_block));
454     DBG(DBG_inquiry,"exposure time default FB blue.: %d micro-sec\n",
455             unit*get_inquiry_exposure_time_def_b_fb(inquiry_block));
456     DBG(DBG_inquiry,"exposure time default UTA red.: %d micro-sec\n",
457             unit*get_inquiry_exposure_time_def_r_uta(inquiry_block));
458     DBG(DBG_inquiry,"exposure time default UTA grn.: %d micro-sec\n",
459             unit*get_inquiry_exposure_time_def_g_uta(inquiry_block));
460     DBG(DBG_inquiry,"exposure time default UTA blue: %d micro-sec\n",
461             unit*get_inquiry_exposure_time_def_b_uta(inquiry_block));
462   }
463 
464 
465   /* 0x60 */
466   if (dev->inquiry_len<=0x60)
467   {
468     return;
469   }
470 
471   DBG(DBG_inquiry,"\n");
472   DBG(DBG_inquiry,"scan modes (%02x):\n", get_inquiry_sc_feature_byte0(inquiry_block));
473   DBG(DBG_inquiry,"----------------\n");
474   DBG_inq_nz(" - three passes color mode\n",		get_inquiry_sc_three_pass_color(inquiry_block));
475   DBG_inq_nz(" - single pass color mode\n",		get_inquiry_sc_one_pass_color(inquiry_block));
476   DBG_inq_nz(" - lineart mode\n",			dev->inquiry_lineart);
477   DBG_inq_nz(" - halftone mode\n",			dev->inquiry_halftone);
478   DBG_inq_nz(" - gray mode\n",				dev->inquiry_gray);
479   DBG_inq_nz(" - color mode\n",				dev->inquiry_color);
480   DBG_inq_nz(" - transparency (UTA)\n",			dev->inquiry_uta);
481   DBG_inq_nz(" - automatic document feeder (ADF)\n",	dev->inquiry_adf);
482 
483   /* 0x61 */
484   if (dev->inquiry_len<=0x61)
485   {
486     return;
487   }
488 
489   DBG(DBG_inquiry,"\n");
490   DBG(DBG_inquiry,"scanner capability (%02x, %02x, %02x):\n",
491       get_inquiry_sc_feature_byte1(inquiry_block),
492       get_inquiry_sc_feature_byte2(inquiry_block),
493       get_inquiry_sc_feature_byte3(inquiry_block));
494   DBG(DBG_inquiry,"--------------------------------\n");
495   DBG_inq_nz(" - double resolution\n",			dev->inquiry_dor);
496   DBG_inq_nz(" - send high byte first\n",		get_inquiry_sc_high_byte_first(inquiry_block));
497   DBG_inq_nz(" - bi-level image reverse\n",		dev->inquiry_reverse);
498   DBG_inq_nz(" - multi-level image reverse\n",		dev->inquiry_reverse_multi);
499   DBG_inq_nz(" - support shadow function\n",		dev->inquiry_shadow);
500   DBG_inq_nz(" - support highlight function\n",		dev->inquiry_highlight);
501   DBG_inq_nz(" - f/w downloadable\n",			get_inquiry_sc_downloadable_fw(inquiry_block));
502   DBG_inq_nz(" - paper length can reach to 14 inch\n",	get_inquiry_sc_paper_length_14(inquiry_block));
503 
504   /* 0x62 */
505   if (dev->inquiry_len<=0x62)
506   {
507     return;
508   }
509 
510   DBG_inq_nz(" - shading data/gain uploadable\n",	get_inquiry_sc_uploadable_shade(inquiry_block));
511   DBG_inq_nz(" - analog gamma correction\n",		dev->inquiry_analog_gamma);
512   DBG_inq_nz(" - x, y coordinate base\n",		get_inquiry_xy_coordinate_base(inquiry_block));
513   DBG_inq_nz(" - lineart starts with LSB\n",		get_inquiry_lineart_order(inquiry_block));
514   DBG_inq_nz(" - start density \n",			get_inquiry_start_density(inquiry_block));
515   DBG_inq_nz(" - hardware x scaling\n",			get_inquiry_hw_x_scaling(inquiry_block));
516   DBG_inq_nz(" - hardware y scaling\n",			get_inquiry_hw_y_scaling(inquiry_block));
517 
518   /* 0x63 */
519   if (dev->inquiry_len<=0x63)
520   {
521     return;
522   }
523 
524   DBG_inq_nz(" + ADF: no paper\n",			get_inquiry_ADF_no_paper(inquiry_block));
525   DBG_inq_nz(" + ADF: cover open\n",			get_inquiry_ADF_cover_open(inquiry_block));
526   DBG_inq_nz(" + ADF: paper jam\n",			get_inquiry_ADF_paper_jam(inquiry_block));
527   DBG_inq_nz(" - unknown flag; 0x63 bit 3\n",		get_inquiry_0x63_bit3(inquiry_block));
528   DBG_inq_nz(" - unknown lfag: 0x63 bit 4\n",		get_inquiry_0x63_bit4(inquiry_block));
529   DBG_inq_nz(" - lens calib in doc pos\n",		get_inquiry_lens_cal_in_doc_pos(inquiry_block));
530   DBG_inq_nz(" - manual focus\n",			get_inquiry_manual_focus(inquiry_block));
531   DBG_inq_nz(" - UTA lens calib pos selectable\n",	get_inquiry_sel_uta_lens_cal_pos(inquiry_block));
532 
533   /* 0x64 - 0x68*/
534   if (dev->inquiry_len<=0x68)
535   {
536     return;
537   }
538 
539   if (dev->inquiry_gamma_dwload)
540   {
541     DBG(DBG_inquiry,"\n");
542     DBG(DBG_inquiry,"gamma download available\n");
543     DBG_inq_nz("gamma download type 2\n", get_inquiry_gamma_type_2(inquiry_block));
544     DBG(DBG_inquiry,"lines of gamma curve: %s\n", gamma_lines_str[get_inquiry_gamma_lines(inquiry_block)]);
545 
546     /* 0x66 */
547     DBG_inq_nz("gamma input   8 bits/pixel support\n", get_inquiry_gib_8bpp(inquiry_block));
548     DBG_inq_nz("gamma input   9 bits/pixel support\n", get_inquiry_gib_9bpp(inquiry_block));
549     DBG_inq_nz("gamma input  10 bits/pixel support\n", get_inquiry_gib_10bpp(inquiry_block));
550     DBG_inq_nz("gamma input  12 bits/pixel support\n", get_inquiry_gib_12bpp(inquiry_block));
551     DBG_inq_nz("gamma input  14 bits/pixel support\n", get_inquiry_gib_14bpp(inquiry_block));
552     DBG_inq_nz("gamma input  16 bits/pixel support\n", get_inquiry_gib_16bpp(inquiry_block));
553     DBG_inq_nz("0x66 bit 6\n", get_inquiry_0x66_bit6(inquiry_block));
554     DBG_inq_nz("0x66 bit 7\n", get_inquiry_0x66_bit7(inquiry_block));
555 
556     /* 0x68 */
557     DBG_inq_nz("gamma output  8 bits/pixel support\n", get_inquiry_gob_8bpp(inquiry_block));
558     DBG_inq_nz("gamma output  9 bits/pixel support\n", get_inquiry_gob_9bpp(inquiry_block));
559     DBG_inq_nz("gamma output 10 bits/pixel support\n", get_inquiry_gob_10bpp(inquiry_block));
560     DBG_inq_nz("gamma output 12 bits/pixel support\n", get_inquiry_gob_12bpp(inquiry_block));
561     DBG_inq_nz("gamma output 14 bits/pixel support\n", get_inquiry_gob_14bpp(inquiry_block));
562     DBG_inq_nz("gamma output 16 bits/pixel support\n", get_inquiry_gob_16bpp(inquiry_block));
563     DBG_inq_nz("0x68 bit 6\n", get_inquiry_0x68_bit6(inquiry_block));
564     DBG_inq_nz("0x68 bit 7\n", get_inquiry_0x68_bit7(inquiry_block));
565   }
566 
567   /* 0x64 - 0x68 reserved bits */
568   DBG_inq_nz("0x64 bit 2\n", get_inquiry_0x64_bit2(inquiry_block));
569   DBG_inq_nz("0x64 bit 3\n", get_inquiry_0x64_bit3(inquiry_block));
570   DBG_inq_nz("0x64 bit 4\n", get_inquiry_0x64_bit4(inquiry_block));
571   DBG_inq_nz("0x64 bit 6\n", get_inquiry_0x64_bit6(inquiry_block));
572 
573   DBG(DBG_inquiry,"\n");
574   DBG(DBG_inquiry,"reserved byte 0x65 = %d\n", get_inquiry_0x65(inquiry_block));
575   DBG(DBG_inquiry,"reserved byte 0x67 = %d\n", get_inquiry_0x67(inquiry_block));
576 
577 
578   /* 0x69 */
579   if (dev->inquiry_len<=0x69)
580   {
581     return;
582   }
583 
584   DBG(DBG_inquiry,"\n");
585   if (get_inquiry_hda(inquiry_block))
586   {
587     DBG(DBG_inquiry,"halftone download available\n");
588     DBG(DBG_inquiry,"halftone pattern download max matrix %dx%d\n",
589                     get_inquiry_max_halftone_matrix(inquiry_block),
590                     get_inquiry_max_halftone_matrix(inquiry_block));
591   }
592 
593   /* 0x6a */
594   if (dev->inquiry_len<=0x6a)
595   {
596     return;
597   }
598 
599   DBG_inq_nz("built-in halftone patterns:\n", get_inquiry_halftones_supported(inquiry_block));
600   DBG_inq_nz("built-in halftone pattern size ............: 2x2\n", get_inquiry_halftones_2x2(inquiry_block));
601   DBG_inq_nz("built-in halftone pattern size ............: 4x4\n", get_inquiry_halftones_4x4(inquiry_block));
602   DBG_inq_nz("built-in halftone pattern size ............: 6x6\n", get_inquiry_halftones_6x6(inquiry_block));
603   DBG_inq_nz("built-in halftone pattern size ............: 8x8\n", get_inquiry_halftones_8x8(inquiry_block));
604   DBG_inq_nz("built-in halftone pattern size ............: 12x12\n", get_inquiry_halftones_12x12(inquiry_block));
605 
606   /* 0x6b, 0x6c */
607   DBG(DBG_inquiry,"reserved byte 0x6b = %d\n", get_inquiry_0x6b(inquiry_block));
608   DBG(DBG_inquiry,"reserved byte 0x6c = %d\n", get_inquiry_0x6c(inquiry_block));
609 
610 
611   /* 0x6d */
612   if (dev->inquiry_len<=0x6d)
613   {
614     return;
615   }
616 
617   DBG(DBG_inquiry,"\n");
618   DBG(DBG_inquiry,"color sequence............................: %s\n",
619       color_sequence_str[get_inquiry_colorseq(inquiry_block)]);
620   DBG_inq_nz("color ordering support....................: pixel\n",
621              get_inquiry_color_order_pixel(inquiry_block));
622   DBG_inq_nz("color ordering support....................: line without CCD distance\n",
623              get_inquiry_color_order_line_no_ccd(inquiry_block));
624   DBG_inq_nz("color ordering support....................: plane\n",
625              get_inquiry_color_order_plane(inquiry_block));
626   DBG_inq_nz("color ordering support....................: line with CCD distance\n",
627              get_inquiry_color_order_line_w_ccd(inquiry_block));
628   DBG_inq_nz("color ordering support....................: (reserved)\n",
629              get_inquiry_color_order_reserved(inquiry_block));
630 
631   /* 0x6e */
632   if (dev->inquiry_len<=0x71)
633   {
634     return;
635   }
636 
637   DBG(DBG_inquiry,"\n");
638   DBG(DBG_inquiry,"maximum video memory......................: %d KB\n", dev->inquiry_vidmem/1024);
639 
640   /* 0x72 */
641   DBG(DBG_inquiry,"\n");
642   DBG(DBG_inquiry,"reserved byte 0x72 = %d\n", get_inquiry_0x72(inquiry_block));
643   DBG(DBG_inquiry,"\n");
644 
645   /* 0x73/0x94 - 0x75/0x96 */
646   if (dev->inquiry_len<=0x75)
647   {
648     return;
649   }
650 
651   DBG(DBG_inquiry,"optical resolution........................: %d dpi\n", dev->inquiry_optical_res);
652   DBG(DBG_inquiry,"maximum x-resolution......................: %d dpi\n", dev->inquiry_x_res);
653   DBG(DBG_inquiry,"maximum y-resolution......................: %d dpi\n", dev->inquiry_y_res);
654 
655   /* ---------- */
656 
657   /* 0x76 0x77 */
658   if (dev->inquiry_len<=0x77)
659   {
660     return;
661   }
662 
663   DBG(DBG_inquiry,"\n");
664   DBG(DBG_inquiry,"FB (flatbed-mode):\n");
665   DBG(DBG_inquiry,"FB maximum scan width.....................: %2.2f inch\n", dev->inquiry_fb_width);
666   DBG(DBG_inquiry,"FB maximum scan length....................: %2.2f inch\n", dev->inquiry_fb_length);
667 
668   /* ---------- */
669 
670   /* 0x7a - 0x81 */
671   if (dev->inquiry_len<=0x81)
672   {
673     return;
674   }
675 
676   DBG(DBG_inquiry,"\n");
677   DBG(DBG_inquiry,"UTA (transparency-mode):\n");
678   DBG(DBG_inquiry,"UTA x-original point......................: %2.2f inch\n", dev->inquiry_uta_x_off);
679   DBG(DBG_inquiry,"UTA y-original point......................: %2.2f inch\n", dev->inquiry_uta_y_off);
680   DBG(DBG_inquiry,"UTA maximum scan width....................: %2.2f inch\n", dev->inquiry_uta_width);
681   DBG(DBG_inquiry,"UTA maximum scan length...................: %2.2f inch\n", dev->inquiry_uta_length);
682 
683   /* ---------- */
684 
685   /* 0x82-0x85 */
686   DBG(DBG_inquiry,"\n");
687   DBG(DBG_inquiry,"reserved byte 0x82 = %d\n", get_inquiry_0x82(inquiry_block));
688 
689   /* ---------- */
690 
691   /* 0x83/0xa0 - 0x85/0xa2 */
692   if (dev->inquiry_len<=0x85)
693   {
694     return;
695   }
696 
697   DBG(DBG_inquiry,"\n");
698   DBG(DBG_inquiry,"DOR (double optical resolution-mode):\n");
699   DBG(DBG_inquiry,"DOR optical resolution....................: %d dpi\n", dev->inquiry_dor_optical_res);
700   DBG(DBG_inquiry,"DOR maximum x-resolution..................: %d dpi\n", dev->inquiry_dor_x_res);
701   DBG(DBG_inquiry,"DOR maximum y-resolution..................: %d dpi\n", dev->inquiry_dor_y_res);
702 
703   /* 0x86 - 0x8d */
704   if (dev->inquiry_len<=0x8d)
705   {
706     return;
707   }
708 
709   DBG(DBG_inquiry,"DOR x-original point......................: %2.2f inch\n", dev->inquiry_dor_x_off);
710   DBG(DBG_inquiry,"DOR y-original point......................: %2.2f inch\n", dev->inquiry_dor_y_off);
711   DBG(DBG_inquiry,"DOR maximum scan width....................: %2.2f inch\n", dev->inquiry_dor_width);
712   DBG(DBG_inquiry,"DOR maximum scan length...................: %2.2f inch\n", dev->inquiry_dor_length);
713   DBG(DBG_inquiry,"\n");
714 
715   /* ---------- */
716 
717   /* 0x8e */
718   DBG(DBG_inquiry,"reserved byte 0x8e = %d\n", get_inquiry_0x8e(inquiry_block));
719   DBG(DBG_inquiry,"\n");
720 
721   /* ---------- */
722 
723   /* 0x8f */
724   if (dev->inquiry_len<=0x8f)
725   {
726     return;
727   }
728 
729   DBG(DBG_inquiry,"last calibration lamp density.............: %d\n",
730       get_inquiry_last_calibration_lamp_density(inquiry_block));
731 
732   /* 0x90 */
733   DBG(DBG_inquiry,"\n");
734   DBG(DBG_inquiry,"reserved byte 0x90 = %d\n", get_inquiry_0x90(inquiry_block));
735   DBG(DBG_inquiry,"\n");
736 
737   /* 0x91 */
738   if (dev->inquiry_len<=0x91)
739   {
740     return;
741   }
742 
743   DBG(DBG_inquiry,"lamp warmup maximum time..................: %d sec\n", dev->inquiry_max_warmup_time);
744 
745   /* 0x92 0x93 */
746   if (dev->inquiry_len<=0x93)
747   {
748     return;
749   }
750 
751   DBG(DBG_inquiry,"window descriptor block length............: %d bytes\n", get_inquiry_wdb_length(inquiry_block));
752 
753   /* ----------------- */
754 
755   /* 0x97 */
756   if (dev->inquiry_len<=0x97)
757   {
758     return;
759   }
760 
761   if (get_inquiry_analog_gamma_table(inquiry_block) == 0)
762   {
763     DBG(DBG_inquiry,"no analog gamma function\n");
764   }
765   else
766   {
767     DBG(DBG_inquiry,"mp 8832 analog gamma table\n");
768   }
769 
770   /* 0x98, 0x99 */
771   DBG(DBG_inquiry,"\n");
772   DBG(DBG_inquiry,"reserved byte 0x98 = %d\n", get_inquiry_0x98(inquiry_block));
773   DBG(DBG_inquiry,"reserved byte 0x99 = %d\n", get_inquiry_0x99(inquiry_block));
774   DBG(DBG_inquiry,"\n");
775 
776   /* 0x9a */
777   if (dev->inquiry_len<=0x9a)
778   {
779     return;
780   }
781 
782   DBG(DBG_inquiry,"maximum calibration data lines for shading: %d\n",
783       get_inquiry_max_calibration_data_lines(inquiry_block));
784 
785   /* 0x9b */
786   if (dev->inquiry_len<=0x9b)
787   {
788     return;
789   }
790 
791   DBG(DBG_inquiry,"fb/uta: color line arrangement mode.......: %d\n",
792       get_inquiry_fb_uta_line_arrangement_mode(inquiry_block));
793 
794   /* 0x9c */
795   if (dev->inquiry_len<=0x9c)
796   {
797     return;
798   }
799 
800   DBG(DBG_inquiry,"adf:    color line arrangement mode.......: %d\n",
801       get_inquiry_adf_line_arrangement_mode(inquiry_block));
802 
803   /* 0x9d */
804   if (dev->inquiry_len<=0x9d)
805   {
806     return;
807   }
808 
809   DBG(DBG_inquiry,"CCD line distance.........................: %d\n",
810       get_inquiry_CCD_line_distance(inquiry_block));
811 
812   DBG(DBG_inquiry,"\n");
813   DBG(DBG_inquiry,"reserved byte 0x9e = %d\n", get_inquiry_0x9e(inquiry_block));
814 
815   /* 0xa2 following */
816   if (dev->inquiry_len<=0xa2)
817   {
818     return;
819   }
820 
821   DBG(DBG_inquiry,"\n");
822   for(i=0xa3; i<dev->inquiry_len; i++)
823   {
824     DBG(DBG_inquiry,"unknown reserved byte 0x%x = %d\n", i, inquiry_block[i]);
825   }
826 }
827 
828 
829 /* ------------------------------------------------------------ CBHS_CORRECT ------------------------------- */
830 
831 
umax_cbhs_correct(int minimum, int cbhs, int maximum)832 static int umax_cbhs_correct(int minimum, int cbhs, int maximum)
833 {
834  int range = maximum - minimum + 1;
835 
836   if (range == 256)
837   {
838     return cbhs;
839   }
840 
841  return (int)( (cbhs/256.0)*range + minimum );
842 }
843 
844 
845 /* ------------------------------------------------------------ SENSE_HANDLER ------------------------------ */
846 
847 
sense_handler(int scsi_fd, unsigned char *result, void *arg)848 static SANE_Status sense_handler(int scsi_fd, unsigned char *result, void *arg)	  /* is called by sanei_scsi */
849 {
850  unsigned char asc, ascq, sensekey;
851  int           asc_ascq, len;
852  Umax_Device   *dev = arg;
853 
854   DBG(DBG_proc, "check condition sense handler (scsi_fd = %d)\n", scsi_fd);
855 
856   sensekey = get_RS_sense_key(result);
857   asc      = get_RS_ASC(result);
858   ascq     = get_RS_ASCQ(result);
859   asc_ascq = (int)(256 * asc + ascq);
860   len      = 7 + get_RS_additional_length(result);
861 
862   if ( get_RS_error_code(result) != 0x70 )
863   {
864     DBG(DBG_error, "invalid sense key error code (%d)\n", get_RS_error_code(result));
865 
866     switch (dev->handle_bad_sense_error)
867     {
868       default:
869       case 0:
870         DBG(DBG_error, "=> handled as DEVICE BUSY!\n");
871        return SANE_STATUS_DEVICE_BUSY;
872 
873       case 1:
874         DBG(DBG_error, "=> handled as ok!\n");
875        return SANE_STATUS_GOOD;
876 
877       case 2:
878         DBG(DBG_error, "=> handled as i/o error!\n");
879        return SANE_STATUS_IO_ERROR;
880 
881       case 3:
882         DBG(DBG_error, "=> ignored, sense handler does continue\n");
883     }
884   }
885 
886   DBG(DBG_sense, "check condition sense: %s\n", sense_str[sensekey]);
887 
888   /* when we reach here then we have no valid data in buffer[0] */
889   /* but it may be helpful to have the result data in buffer[0] */
890   memset(dev->buffer[0], 0, rs_return_block_size);  /* clear sense data buffer */
891   memcpy(dev->buffer[0], result, len+1); /* copy sense data to buffer */
892 
893   if (len > 0x15)
894   {
895    int scanner_error = get_RS_scanner_error_code(result);
896 
897     if (scanner_error < 100)
898     {
899       DBG(DBG_sense, "-> %s (#%d)\n", scanner_error_str[scanner_error], scanner_error);
900     }
901     else
902     {
903       DBG(DBG_sense, "-> error %d\n", scanner_error);
904     }
905   }
906 
907   if (get_RS_ILI(result) != 0)
908   {
909     DBG(DBG_sense, "-> ILI-ERROR: requested data length is larger than actual length\n");
910   }
911 
912   switch(sensekey)
913   {
914     case 0x00:											 /* no sense */
915       return SANE_STATUS_GOOD;
916      break;
917 
918 
919     case 0x03:										     /* medium error */
920       if (asc_ascq == 0x1400)
921       {
922         DBG(DBG_sense, "-> misfeed, paper jam\n");
923         return SANE_STATUS_JAMMED;
924       }
925       else if (asc_ascq == 0x1401)
926       {
927         DBG(DBG_sense, "-> adf not ready\n");
928         return SANE_STATUS_NO_DOCS;
929       }
930       else
931       {
932         DBG(DBG_sense, "-> unknown medium error: asc=%d, ascq=%d\n", asc, ascq);
933       }
934      break;
935 
936 
937     case 0x04:										   /* hardware error */
938       if (asc_ascq == 0x4000)
939       {
940         DBG(DBG_sense, "-> diagnostic error:\n");
941         if (len >= 0x13)
942 	{
943 	  DBG_sense_nz("   dim light\n",			get_RS_asb_dim_light(result));
944 	  DBG_sense_nz("   no light\n",				get_RS_asb_no_light(result));
945 	  DBG_sense_nz("   sensor or motor error\n",		get_RS_asb_sensor_motor(result));
946 	  DBG_sense_nz("   too light\n",			get_RS_asb_too_light(result));
947 	  DBG_sense_nz("   calibration error\n",		get_RS_asb_calibration(result));
948 	  DBG_sense_nz("   rom error\n",			get_RS_asb_rom(result));
949 	  DBG_sense_nz("   ram error\n",			get_RS_asb_ram(result));
950 	  DBG_sense_nz("   cpu error\n",			get_RS_asb_cpu(result));
951 	  DBG_sense_nz("   scsi error\n",			get_RS_asb_scsi(result));
952 	  DBG_sense_nz("   timer error\n",			get_RS_asb_timer(result));
953 	  DBG_sense_nz("   filter motor error\n",		get_RS_asb_filter_motor(result));
954 	  DBG_sense_nz("   dc adjust error\n",			get_RS_asb_dc_adjust(result));
955 	  DBG_sense_nz("   uta home sensor or motor error\n",	get_RS_asb_uta_sensor(result));
956 	}
957       }
958       else
959       {
960         DBG(DBG_sense, "-> unknown hardware error: asc=%d, ascq=%d\n", asc, ascq);
961       }
962       return SANE_STATUS_IO_ERROR;
963      break;
964 
965 
966     case 0x05:										  /* illegal request */
967       if (asc_ascq == 0x2000)
968       {
969         DBG(DBG_sense, "-> invalid command operation code\n");
970       }
971       else if (asc_ascq == 0x2400)
972       {
973         DBG(DBG_sense, "-> illegal field in CDB\n");
974        }
975       else if (asc_ascq == 0x2500)
976       {
977         DBG(DBG_sense, "-> logical unit not supported\n");
978       }
979       else if (asc_ascq == 0x2600)
980       {
981         DBG(DBG_sense, "-> invalid field in parameter list\n");
982       }
983       else if (asc_ascq == 0x2c01)
984       {
985         DBG(DBG_sense, "-> too many windows specified\n");
986       }
987       else if (asc_ascq == 0x2c02)
988       {
989         DBG(DBG_sense, "-> invalid combination of windows specified\n");
990       }
991       else
992       {
993         DBG(DBG_sense, "-> illegal request: asc=%d, ascq=%d\n", asc, ascq);
994       }
995 
996       if (len >= 0x11)
997       {
998         if (get_RS_SKSV(result) != 0)
999         {
1000           if (get_RS_CD(result) == 0)
1001           {
1002             DBG(DBG_sense, "-> illegal parameter in CDB\n");
1003           }
1004           else
1005           {
1006             DBG(DBG_sense, "-> illegal parameter is in the data parameters sent during data out phase\n");
1007           }
1008 
1009           DBG(DBG_sense, "-> error detected in byte %d\n", get_RS_field_pointer(result));
1010          }
1011       }
1012       return SANE_STATUS_IO_ERROR;
1013      break;
1014 
1015 
1016     case 0x06:										   /* unit attention */
1017       if (asc_ascq == 0x2900)
1018       {
1019         DBG(DBG_sense, "-> power on, reset or bus device reset\n");
1020       }
1021       else if (asc_ascq == 0x3f01)
1022       {
1023         DBG(DBG_sense, "-> microcode has been changed\n");
1024        }
1025       else
1026       {
1027         DBG(DBG_sense, "-> unit attention: asc=%d, ascq=%d\n", asc, ascq);
1028       }
1029      break;
1030 
1031 
1032     case 0x09:										  /* vendor specific */
1033 
1034       if (asc == 0x00)
1035       {
1036         DBG(DBG_sense, "-> button protocol\n");
1037         if (ascq & 1)
1038         {
1039           dev->button0_pressed = 1;
1040           DBG(DBG_sense, "-> button 0 pressed\n");
1041         }
1042 
1043         if (ascq & 2)
1044         {
1045           dev->button1_pressed = 1;
1046           DBG(DBG_sense, "-> button 1 pressed\n");
1047         }
1048 
1049         if (ascq & 4)
1050         {
1051           dev->button2_pressed = 1;
1052           DBG(DBG_sense, "-> button 2 pressed\n");
1053         }
1054         return SANE_STATUS_GOOD;
1055       }
1056       else if (asc_ascq == 0x8001)
1057       {
1058         DBG(DBG_sense, "-> lamp warmup\n");
1059         return SANE_STATUS_DEVICE_BUSY;
1060       }
1061       else if (asc_ascq == 0x8002)
1062       {
1063         DBG(DBG_sense, "-> calibration by driver\n");
1064         if (dev)
1065 	{
1066           dev->do_calibration = 1;				       /* set flag for calibration by driver */
1067         }
1068         return SANE_STATUS_GOOD;
1069       }
1070       else
1071       {
1072         DBG(DBG_sense, "-> vendor specific sense-code: asc=%d, ascq=%d\n", asc, ascq);
1073       }
1074      break;
1075 
1076   }
1077  return SANE_STATUS_GOOD;
1078 }
1079 
1080 /* ------------------------------------------------------------ UMAX SET RGB BIND -------------------------- */
1081 
umax_set_rgb_bind(Umax_Scanner *scanner)1082 static void umax_set_rgb_bind(Umax_Scanner *scanner)
1083 {
1084   if ( (scanner->val[OPT_RGB_BIND].w == SANE_FALSE) &&
1085        (strcmp(scanner->val[OPT_MODE].s, COLOR_STR) == 0) ) /* enable rgb options */
1086   {
1087     if (scanner->device->inquiry_analog_gamma)
1088     {
1089       scanner->opt[OPT_ANALOG_GAMMA].cap   |= SANE_CAP_INACTIVE;
1090       scanner->opt[OPT_ANALOG_GAMMA_R].cap &= ~SANE_CAP_INACTIVE;
1091       scanner->opt[OPT_ANALOG_GAMMA_G].cap &= ~SANE_CAP_INACTIVE;
1092       scanner->opt[OPT_ANALOG_GAMMA_B].cap &= ~SANE_CAP_INACTIVE;
1093     }
1094     if (scanner->device->inquiry_highlight)
1095     {
1096       scanner->opt[OPT_HIGHLIGHT].cap   |= SANE_CAP_INACTIVE;
1097       scanner->opt[OPT_HIGHLIGHT_R].cap &= ~SANE_CAP_INACTIVE;
1098       scanner->opt[OPT_HIGHLIGHT_G].cap &= ~SANE_CAP_INACTIVE;
1099       scanner->opt[OPT_HIGHLIGHT_B].cap &= ~SANE_CAP_INACTIVE;
1100     }
1101     if (scanner->device->inquiry_shadow)
1102     {
1103       scanner->opt[OPT_SHADOW].cap   |= SANE_CAP_INACTIVE;
1104       scanner->opt[OPT_SHADOW_R].cap &= ~SANE_CAP_INACTIVE;
1105       scanner->opt[OPT_SHADOW_G].cap &= ~SANE_CAP_INACTIVE;
1106       scanner->opt[OPT_SHADOW_B].cap &= ~SANE_CAP_INACTIVE;
1107     }
1108   }
1109   else /* only show gray options */
1110   {
1111     if (scanner->device->inquiry_analog_gamma)
1112     {
1113       scanner->opt[OPT_ANALOG_GAMMA].cap   &= ~SANE_CAP_INACTIVE;
1114       scanner->opt[OPT_ANALOG_GAMMA_R].cap |= SANE_CAP_INACTIVE;
1115       scanner->opt[OPT_ANALOG_GAMMA_G].cap |= SANE_CAP_INACTIVE;
1116       scanner->opt[OPT_ANALOG_GAMMA_B].cap |= SANE_CAP_INACTIVE;
1117     }
1118     if (scanner->device->inquiry_highlight)
1119     {
1120       scanner->opt[OPT_HIGHLIGHT].cap   &= ~SANE_CAP_INACTIVE;
1121       scanner->opt[OPT_HIGHLIGHT_R].cap |= SANE_CAP_INACTIVE;
1122       scanner->opt[OPT_HIGHLIGHT_G].cap |= SANE_CAP_INACTIVE;
1123       scanner->opt[OPT_HIGHLIGHT_B].cap |= SANE_CAP_INACTIVE;
1124     }
1125     if (scanner->device->inquiry_shadow)
1126     {
1127       scanner->opt[OPT_SHADOW].cap   &= ~SANE_CAP_INACTIVE;
1128       scanner->opt[OPT_SHADOW_R].cap |= SANE_CAP_INACTIVE;
1129       scanner->opt[OPT_SHADOW_G].cap |= SANE_CAP_INACTIVE;
1130       scanner->opt[OPT_SHADOW_B].cap |= SANE_CAP_INACTIVE;
1131     }
1132   }
1133 
1134   if ( (scanner->device->inquiry_exposure_adj) && (scanner->val[OPT_SELECT_EXPOSURE_TIME].w) )
1135   {
1136     if ( (scanner->val[OPT_RGB_BIND].w == SANE_FALSE) &&
1137          (!scanner->device->exposure_time_rgb_bind) &&
1138          (strcmp(scanner->val[OPT_MODE].s, COLOR_STR) == 0) ) /* enable rgb exposure time options */
1139     {
1140       if (scanner->val[OPT_SELECT_CAL_EXPOSURE_TIME].w) /* exposure time setting for calibration enabled */
1141       {
1142         scanner->opt[OPT_CAL_EXPOS_TIME].cap    |= SANE_CAP_INACTIVE;
1143         scanner->opt[OPT_CAL_EXPOS_TIME_R].cap  &= ~SANE_CAP_INACTIVE;
1144         scanner->opt[OPT_CAL_EXPOS_TIME_G].cap  &= ~SANE_CAP_INACTIVE;
1145         scanner->opt[OPT_CAL_EXPOS_TIME_B].cap  &= ~SANE_CAP_INACTIVE;
1146       }
1147       else /* no separate settings for calibration exposure times */
1148       {
1149         scanner->opt[OPT_CAL_EXPOS_TIME].cap    |= SANE_CAP_INACTIVE;
1150         scanner->opt[OPT_CAL_EXPOS_TIME_R].cap  |= SANE_CAP_INACTIVE;
1151         scanner->opt[OPT_CAL_EXPOS_TIME_G].cap  |= SANE_CAP_INACTIVE;
1152         scanner->opt[OPT_CAL_EXPOS_TIME_B].cap  |= SANE_CAP_INACTIVE;
1153       }
1154 
1155       scanner->opt[OPT_SCAN_EXPOS_TIME].cap   |= SANE_CAP_INACTIVE;
1156       scanner->opt[OPT_SCAN_EXPOS_TIME_R].cap &= ~SANE_CAP_INACTIVE;
1157       scanner->opt[OPT_SCAN_EXPOS_TIME_G].cap &= ~SANE_CAP_INACTIVE;
1158       scanner->opt[OPT_SCAN_EXPOS_TIME_B].cap &= ~SANE_CAP_INACTIVE;
1159     }
1160     else /* enable gray exposure time options */
1161     {
1162       if (scanner->val[OPT_SELECT_CAL_EXPOSURE_TIME].w) /* exposure time setting for calibration enabled */
1163       {
1164         scanner->opt[OPT_CAL_EXPOS_TIME].cap  &= ~SANE_CAP_INACTIVE;
1165       }
1166       else /* no separate settings for calibration exposure times */
1167       {
1168         scanner->opt[OPT_CAL_EXPOS_TIME].cap  |= SANE_CAP_INACTIVE;
1169       }
1170       scanner->opt[OPT_CAL_EXPOS_TIME_R].cap  |= SANE_CAP_INACTIVE;
1171       scanner->opt[OPT_CAL_EXPOS_TIME_G].cap  |= SANE_CAP_INACTIVE;
1172       scanner->opt[OPT_CAL_EXPOS_TIME_B].cap  |= SANE_CAP_INACTIVE;
1173 
1174       scanner->opt[OPT_SCAN_EXPOS_TIME].cap   &= ~SANE_CAP_INACTIVE;
1175       scanner->opt[OPT_SCAN_EXPOS_TIME_R].cap |= SANE_CAP_INACTIVE;
1176       scanner->opt[OPT_SCAN_EXPOS_TIME_G].cap |= SANE_CAP_INACTIVE;
1177       scanner->opt[OPT_SCAN_EXPOS_TIME_B].cap |= SANE_CAP_INACTIVE;
1178     }
1179   }
1180 }
1181 
1182 /* ------------------------------------------------------------ UMAX CALCULATE PIXELS ---------------------- */
1183 
umax_calculate_pixels(int scansize_pixel, int resolution, int resolution_base, int coordinate_base)1184 static int umax_calculate_pixels(int scansize_pixel, int resolution, int resolution_base, int coordinate_base)
1185 /* scansize_pixel	= size in pixels at 1200 dpi */
1186 /* resolution		= scan resolution */
1187 /* resolution_base	= this is the optical resolution * 1 or * 2 */
1188 /* coordinate_base	= this is 1200 dpi */
1189 {
1190  unsigned int intsize_inch, intsize_pixel, diffsize_pixel, missing_pixels, del_pixel_1, pix;
1191  int toomuch;
1192 
1193   intsize_inch   = scansize_pixel / coordinate_base;	/* full inches */
1194   intsize_pixel  = intsize_inch * resolution;		/* pixels in full inches */
1195 
1196   diffsize_pixel  = scansize_pixel % coordinate_base;	/* missing pixels in last inch at 1200 dpi */
1197   missing_pixels  = diffsize_pixel * resolution_base / coordinate_base; /* missing pixels at resolution_base dpi */
1198   del_pixel_1     = resolution_base - resolution;	/* pixels to erase in one inch */
1199   toomuch         = 0;					/* number of pixels that must be deleted in last inch  */
1200 
1201   if (del_pixel_1 != 0)					/* search the number of pixels that must deleted */
1202   {
1203     pix = 0;
1204     while (pix <= missing_pixels)
1205     {
1206       toomuch++;
1207       pix = toomuch * resolution_base/del_pixel_1;
1208     }
1209 
1210     if (pix > missing_pixels)
1211     {
1212       toomuch--;
1213     }
1214   }
1215 
1216   return (intsize_pixel + missing_pixels - toomuch);
1217 }
1218 
1219 /* ------------------------------------------------------------ UMAX FORGET LINE --------------------------- */
1220 
1221 
umax_forget_line(Umax_Device *dev, int color)1222 static int umax_forget_line(Umax_Device *dev, int color)
1223 /* tests if line related to optical resolution has to be skipped for selected resolution */
1224 /* returns 0 if line is ok, -1 if line has to be skipped */
1225 {
1226  unsigned int opt_res = dev->relevant_optical_res * dev->scale_y;
1227  unsigned int forget;
1228 
1229   dev->pixelline_opt_res++;					 /* increment number of lines in optical res */
1230 
1231   if (opt_res != dev->y_resolution)					    /* are there any lines to skip ? */
1232   {
1233 
1234     forget = (dev->pixelline_del[color] * opt_res)/(opt_res - dev->y_resolution);
1235 
1236     if (dev->pixelline_optic[color]++ == forget)
1237     {
1238       dev->pixelline_del[color]++;					 /* inc pointer to next line to skip */
1239       return(-1);										/* skip line */
1240     }
1241   }
1242 
1243  return(0);									      /* ok, order this line */
1244 }
1245 
1246 
1247 /* ------------------------------------------------------------ UMAX ORDER LINE TO PIXEL ------------------- */
1248 
1249 
umax_order_line_to_pixel(Umax_Device *dev, unsigned char *source, int color)1250 static void umax_order_line_to_pixel(Umax_Device *dev, unsigned char *source, int color)
1251 /* reads a one-color line and writes it into a pixel-ordered-buffer if line */
1252 /* is not skipped */
1253 /* color = 0:red, 1:green, 2:blue */
1254 {
1255  unsigned int i;
1256  unsigned int line = dev->pixelline_next[color];					 /* bufferlinenumber */
1257  unsigned char *dest = dev->pixelbuffer;
1258 
1259   if (dest != NULL)
1260   {
1261     if (dev->bits_per_pixel_code == 1)								   /* 24 bpp */
1262     {
1263       dest += line * dev->width_in_pixels * 3 + color;
1264 
1265       for (i=0; i<dev->width_in_pixels; i++)				   /* cp each pixel into pixelbuffer */
1266       {
1267         *dest++ = *source++;
1268 	dest++;
1269 	dest++;
1270       }
1271     }
1272     else											 /* > 24 bpp */
1273     {
1274       dest += line * dev->width_in_pixels * 6 + color * 2;
1275 
1276       for(i=0; i<dev->width_in_pixels; i++)				   /* cp each pixel into pixelbuffer */
1277       {
1278         *dest++ = *source++;					      /* byte order correct ? , don't know ! */
1279         *dest++ = *source++;
1280 
1281         dest++; dest++;
1282         dest++; dest++;
1283       }
1284     }
1285 
1286     line++;
1287     if (line >= dev->pixelline_max)
1288     {
1289       line = 0;
1290     }
1291 
1292     dev->pixelline_next[color] = line;						  /* next line of this color */
1293     dev->pixelline_ready[color]++;					  /* number of ready lines for color */
1294 
1295     DBG(DBG_read, "merged line as color %d to line %d\n", color, dev->pixelline_ready[color]);
1296   }
1297 }
1298 
1299 
1300 /* ------------------------------------------------------------ UMAX ORDER LINE ---------------------------- */
1301 
1302 
umax_order_line(Umax_Device *dev, unsigned char *source)1303 static void umax_order_line(Umax_Device *dev, unsigned char *source)
1304 {
1305  unsigned int CCD_distance = dev->CCD_distance * dev->scale_y;
1306  unsigned int length = (dev->scanlength * dev->scale_y * dev->relevant_optical_res) / dev->y_coordinate_base;
1307  unsigned int color;
1308 
1309   do										   /* search next valid line */
1310   {
1311     if (dev->pixelline_opt_res < CCD_distance)
1312     {
1313       color = dev->CCD_color[0];								  /* color 0 */
1314     }
1315     else if (dev->pixelline_opt_res < CCD_distance * 3)
1316     {
1317       color = dev->CCD_color[1 + ((dev->pixelline_opt_res - CCD_distance) % 2)];	 	/* color 1,2 */
1318     }
1319     else if (dev->pixelline_opt_res < length * 3 - CCD_distance * 3)
1320     {
1321       color = dev->CCD_color[3 + (dev->pixelline_opt_res % 3)];				      /* color 3,4,5 */
1322     }
1323     else if (dev->pixelline_opt_res < length * 3 - CCD_distance)
1324     {
1325       color = dev->CCD_color[6 + ((dev->pixelline_opt_res - length*3 + CCD_distance*3) % 2)];	/* color 6,7 */
1326     }
1327     else
1328     {
1329       color = dev->CCD_color[8];								  /* color 8 */
1330     }
1331   } while(umax_forget_line(dev, color) != 0);					 /* until found correct line */
1332 
1333   umax_order_line_to_pixel(dev, source, color);
1334 }
1335 
1336 
1337 /* ------------------------------------------------------------ UMAX GET PIXEL LINE ------------------------ */
1338 
1339 
umax_get_pixel_line(Umax_Device *dev)1340 static unsigned char * umax_get_pixel_line(Umax_Device *dev)
1341 {
1342  unsigned char *source = NULL;
1343 
1344   if (dev->pixelbuffer != NULL)
1345   {
1346     if ( (dev->pixelline_ready[0] > dev->pixelline_written) &&
1347          (dev->pixelline_ready[1] > dev->pixelline_written) &&
1348          (dev->pixelline_ready[2] > dev->pixelline_written) )
1349     {
1350       source = dev->pixelbuffer + dev->pixelline_read * dev->width_in_pixels * 3;
1351 
1352       dev->pixelline_written++;
1353       dev->pixelline_read++;
1354 
1355       if (dev->pixelline_read >= dev->pixelline_max)
1356       {
1357         dev->pixelline_read = 0;
1358       }
1359     }
1360   }
1361 
1362   return source;
1363 }
1364 
1365 
1366 /* ============================================================ Switches between the SCSI and USB commands = */
1367 
1368 /* ------------------------------------------------------------ UMAX SCSI CMD ------------------------------ */
1369 
umax_scsi_cmd(Umax_Device *dev, const void *src, size_t src_size, void *dst, size_t * dst_size)1370 static SANE_Status umax_scsi_cmd(Umax_Device *dev, const void *src, size_t src_size, void *dst, size_t * dst_size)
1371 {
1372   switch (dev->connection_type)
1373   {
1374     case SANE_UMAX_SCSI:
1375       return sanei_scsi_cmd(dev->sfd, src, src_size, dst, dst_size);
1376      break;
1377 
1378 #ifdef UMAX_ENABLE_USB
1379     case SANE_UMAX_USB:
1380       return sanei_umaxusb_cmd(dev->sfd, src, src_size, dst, dst_size);
1381      break;
1382 #endif
1383 
1384     default:
1385       return(SANE_STATUS_INVAL);
1386   }
1387 }
1388 
1389 /* ------------------------------------------------------------ UMAX SCSI OPEN EXTENDED -------------------- */
1390 
umax_scsi_open_extended(const char *devicename, Umax_Device *dev, SANEI_SCSI_Sense_Handler handler, void *handler_arg, int *buffersize)1391 static SANE_Status umax_scsi_open_extended(const char *devicename, Umax_Device *dev,
1392                                            SANEI_SCSI_Sense_Handler handler, void *handler_arg, int *buffersize)
1393 {
1394   switch (dev->connection_type)
1395   {
1396     case SANE_UMAX_SCSI:
1397       return sanei_scsi_open_extended(devicename, &dev->sfd, handler, handler_arg, buffersize);
1398      break;
1399 
1400 #ifdef UMAX_ENABLE_USB
1401     case SANE_UMAX_USB:
1402       return sanei_umaxusb_open_extended(devicename, &dev->sfd, handler, handler_arg, buffersize);
1403      break;
1404 #endif
1405 
1406     default:
1407       return(SANE_STATUS_INVAL);
1408   }
1409 }
1410 
1411 /* ------------------------------------------------------------ UMAX SCSI OPEN ----------------------------- */
1412 
umax_scsi_open(const char *devicename, Umax_Device *dev, SANEI_SCSI_Sense_Handler handler, void *handler_arg)1413 static SANE_Status umax_scsi_open(const char *devicename, Umax_Device *dev,
1414                                   SANEI_SCSI_Sense_Handler handler, void *handler_arg)
1415 {
1416   switch (dev->connection_type)
1417   {
1418     case SANE_UMAX_SCSI:
1419       return sanei_scsi_open(devicename, &dev->sfd, handler, handler_arg);
1420      break;
1421 
1422 #ifdef UMAX_ENABLE_USB
1423     case SANE_UMAX_USB:
1424       return sanei_umaxusb_open(devicename, &dev->sfd, handler, handler_arg);
1425      break;
1426 #endif
1427 
1428     default:
1429       return(SANE_STATUS_INVAL);
1430   }
1431 }
1432 
1433 /* ------------------------------------------------------------ UMAX SCSI CLOSE ---------------------------- */
1434 
umax_scsi_close(Umax_Device *dev)1435 static void umax_scsi_close(Umax_Device *dev)
1436 {
1437   switch (dev->connection_type)
1438   {
1439     case SANE_UMAX_SCSI:
1440       sanei_scsi_close(dev->sfd);
1441       dev->sfd=-1;
1442      break;
1443 
1444 #ifdef UMAX_ENABLE_USB
1445     case SANE_UMAX_USB:
1446       sanei_umaxusb_close(dev->sfd);
1447       dev->sfd=-1;
1448      break;
1449 #endif
1450   }
1451 }
1452 
1453 /* ------------------------------------------------------------ UMAX SCSI REQ ENTER ------------------------ */
1454 
umax_scsi_req_enter(Umax_Device *dev, const void *src, size_t src_size, void *dst, size_t * dst_size, void **idp)1455 static SANE_Status umax_scsi_req_enter(Umax_Device *dev, const void *src, size_t src_size,
1456                                        void *dst, size_t * dst_size, void **idp)
1457 {
1458   switch (dev->connection_type)
1459   {
1460     case SANE_UMAX_SCSI:
1461       return sanei_scsi_req_enter (dev->sfd, src, src_size, dst, dst_size, idp);
1462      break;
1463 
1464 #ifdef UMAX_ENABLE_USB
1465     case SANE_UMAX_USB:
1466       return sanei_umaxusb_req_enter (dev->sfd, src, src_size, dst, dst_size, idp);
1467      break;
1468 #endif
1469 
1470     default:
1471       return(SANE_STATUS_INVAL);
1472   }
1473 }
1474 
1475 /* ------------------------------------------------------------ UMAX SCSI REQ WAIT ------------------------- */
1476 
umax_scsi_req_wait(Umax_Device *dev, void *id)1477 static SANE_Status umax_scsi_req_wait(Umax_Device *dev, void *id)
1478 {
1479   switch (dev->connection_type)
1480   {
1481     case SANE_UMAX_SCSI:
1482       return sanei_scsi_req_wait(id);
1483      break;
1484 
1485 #ifdef UMAX_ENABLE_USB
1486     case SANE_UMAX_USB:
1487       return sanei_umaxusb_req_wait(id);
1488      break;
1489 #endif
1490 
1491     default:
1492       return(SANE_STATUS_INVAL);
1493   }
1494 }
1495 
1496 /* ------------------------------------------------------------ UMAX SCSI GET LAMP STATUS ------------------ */
1497 
1498 
umax_scsi_get_lamp_status(Umax_Device *dev, int *lamp_on)1499 static SANE_Status umax_scsi_get_lamp_status(Umax_Device *dev, int *lamp_on)
1500 {
1501  SANE_Status status;
1502  size_t size = 1;
1503 
1504   DBG(DBG_proc, "umax_scsi_get_lamp_status\n");
1505 
1506   status = umax_scsi_cmd(dev, get_lamp_status.cmd, get_lamp_status.size, dev->buffer[0], &size);
1507   if (status)
1508   {
1509     DBG(DBG_error, "umax_scsi_get_lamp_status: command returned status %s\n", sane_strstatus(status));
1510    return status;
1511   }
1512 
1513   *lamp_on = get_lamp_status_lamp_on(dev->buffer[0]);
1514 
1515   DBG(DBG_info, "lamp_status = %d\n", *lamp_on);
1516 
1517  return status;
1518 }
1519 
1520 /* ------------------------------------------------------------ UMAX SCSI SET LAMP STATUS ------------------ */
1521 
1522 
umax_scsi_set_lamp_status(Umax_Device *dev, int lamp_on)1523 static SANE_Status umax_scsi_set_lamp_status(Umax_Device *dev, int lamp_on)
1524 {
1525  SANE_Status status;
1526 
1527   DBG(DBG_proc, "umax_scsi_set_lamp_status\n");
1528   DBG(DBG_info, "lamp_status=%d\n", lamp_on);
1529 
1530   set_lamp_status_lamp_on(set_lamp_status.cmd, lamp_on);
1531   status = umax_scsi_cmd(dev, set_lamp_status.cmd, set_lamp_status.size, NULL, NULL);
1532 
1533   if (status)
1534   {
1535     DBG(DBG_error, "umax_scsi_set_lamp_status: command returned status %s\n", sane_strstatus(status));
1536   }
1537 
1538  return status;
1539 }
1540 
1541 /* ------------------------------------------------------------ UMAX SET LAMP STATUS ----------------------- */
1542 
umax_set_lamp_status(SANE_Handle handle, int lamp_on)1543 static SANE_Status umax_set_lamp_status(SANE_Handle handle, int lamp_on)
1544 {
1545  Umax_Scanner *scanner = handle;
1546  int lamp_status;
1547  SANE_Status status;
1548 
1549   DBG(DBG_proc, "umax_set_lamp_status\n");
1550 
1551   if (umax_scsi_open(scanner->device->sane.name, scanner->device, sense_handler,
1552                      scanner->device) != SANE_STATUS_GOOD )
1553   {
1554      DBG(DBG_error, "ERROR: umax_set_lamp_status: open of %s failed:\n", scanner->device->sane.name);
1555      return SANE_STATUS_INVAL;
1556   }
1557 
1558   status = umax_scsi_get_lamp_status(scanner->device, &lamp_status);
1559 
1560   if (!status)
1561   {
1562     status = umax_scsi_set_lamp_status(scanner->device, lamp_on);
1563   }
1564 
1565   umax_scsi_close(scanner->device);
1566 
1567  return status;
1568 }
1569 
1570 /* ------------------------------------------------------------ UMAX GET DATA BUFFER STATUS ---------------- */
1571 
1572 
1573 #ifndef UMAX_HIDE_UNUSED									 /* NOT USED */
umax_get_data_buffer_status(Umax_Device *dev)1574 static SANE_Status umax_get_data_buffer_status(Umax_Device *dev)
1575 {
1576  SANE_Status status;
1577 
1578   DBG(DBG_proc, "get_data_buffer_status\n");
1579   set_GDBS_wait(get_data_buffer_status.cmd,1);					    /* wait for scanned data */
1580   status = umax_scsi_cmd(dev, get_data_buffer_status.cmd, get_data_buffer_status.size, NULL, NULL);
1581   if (status)
1582   {
1583     DBG(DBG_error, "umax_get_data_buffer_status: command returned status %s\n", sane_strstatus(status));
1584   }
1585 
1586  return status;
1587 }
1588 #endif
1589 
1590 
1591 /* ------------------------------------------------------------ UMAX DO REQUEST SENSE ---------------------- */
1592 
1593 
umax_do_request_sense(Umax_Device *dev)1594 static void umax_do_request_sense(Umax_Device *dev)
1595 {
1596  size_t size = rs_return_block_size;
1597  SANE_Status status;
1598 
1599   DBG(DBG_proc, "do_request_sense\n");
1600   set_RS_allocation_length(request_sense.cmd, rs_return_block_size);
1601   status = umax_scsi_cmd(dev, request_sense.cmd, request_sense.size, dev->buffer[0], &size);
1602   if (status)
1603   {
1604     DBG(DBG_error, "umax_do_request_sense: command returned status %s\n", sane_strstatus(status));
1605   }
1606 }
1607 
1608 
1609 /* ------------------------------------------------------------ UMAX WAIT SCANNER -------------------------- */
1610 
1611 
umax_wait_scanner(Umax_Device *dev)1612 static SANE_Status umax_wait_scanner(Umax_Device *dev)
1613 {
1614  SANE_Status status;
1615  int cnt = 0;
1616 
1617   DBG(DBG_proc, "wait_scanner\n");
1618 
1619   do
1620   {
1621     if (cnt > 100)							   /* maximal 100 * 0.5 sec = 50 sec */
1622     {
1623       DBG(DBG_warning, "scanner does not get ready\n");
1624       return -1;
1625     }
1626 											  /* test unit ready */
1627     status = umax_scsi_cmd(dev, test_unit_ready.cmd, test_unit_ready.size, NULL, NULL);
1628     cnt++;
1629 
1630     if (status)
1631     {
1632       if (cnt == 1)
1633       {
1634         DBG(DBG_info2, "scanner reports %s, waiting ...\n", sane_strstatus(status));
1635       }
1636 
1637       usleep(500000);									 /* wait 0.5 seconds */
1638     }
1639   } while (status != SANE_STATUS_GOOD );
1640 
1641   DBG(DBG_info, "scanner ready\n");
1642 
1643   return status;
1644 }
1645 
1646 #define WAIT_SCANNER { int status = umax_wait_scanner(dev); if (status) return status; }
1647 
1648 
1649 /* ------------------------------------------------------------ UMAX GRAB SCANNER -------------------------- */
1650 
1651 
umax_grab_scanner(Umax_Device *dev)1652 static int umax_grab_scanner(Umax_Device *dev)
1653 {
1654  int status;
1655 
1656   DBG(DBG_proc, "grab_scanner\n");
1657 
1658   WAIT_SCANNER;									   /* wait for scanner ready */
1659   status = umax_scsi_cmd(dev, reserve_unit.cmd, reserve_unit.size, NULL, NULL);
1660 
1661   if (status)
1662   {
1663     DBG(DBG_error, "umax_grab_scanner: command returned status %s\n", sane_strstatus(status));
1664   }
1665   else
1666   {
1667     DBG(DBG_info, "scanner reserved\n");
1668   }
1669 
1670   return status;
1671 }
1672 
1673 
1674 /* ------------------------------------------------------------ UMAX REPOSITION SCANNER -------------------- */
1675 
1676 
umax_reposition_scanner(Umax_Device *dev)1677 static int umax_reposition_scanner(Umax_Device *dev)
1678 {
1679  int status;
1680  int pause;
1681 
1682   pause = dev->pause_after_reposition + dev->pause_for_moving * (dev->upper_left_y + dev->scanlength) /
1683                                         ( (dev->inquiry_fb_length * dev->y_coordinate_base) );
1684 
1685   DBG(DBG_info2, "trying to reposition scanner ...\n");
1686   status = umax_scsi_cmd(dev, object_position.cmd, object_position.size, NULL, NULL);
1687   if (status)
1688   {
1689     DBG(DBG_error, "umax_reposition_scanner: command returned status %s\n", sane_strstatus(status));
1690     return status;
1691   }
1692 
1693   if (pause > 0) /* predefined time to wait (Astra 2400S) */
1694   {
1695     DBG(DBG_info2, "pause for repositioning %d msec ...\n", pause);
1696     usleep(((long) pause) * 1000);
1697     DBG(DBG_info, "repositioning pause done\n");
1698   }
1699   else if (pause == 0) /* use TEST UNIT READY */
1700   {
1701     WAIT_SCANNER;
1702     DBG(DBG_info, "scanner repositioned\n");
1703   }
1704   else /* pause < 0 : return without any pause */
1705   {
1706     DBG(DBG_info, "not waiting for finishing reposition scanner\n");
1707   }
1708 
1709   return SANE_STATUS_GOOD;
1710 }
1711 
1712 
1713 /* ------------------------------------------------------------ UMAX GIVE SCANNER -------------------------- */
1714 
1715 
umax_give_scanner(Umax_Device *dev)1716 static int umax_give_scanner(Umax_Device *dev)
1717 {
1718  int status;
1719 
1720   DBG(DBG_info2, "trying to release scanner ...\n");
1721   status = umax_scsi_cmd(dev, release_unit.cmd, release_unit.size, NULL, NULL);
1722   if (status)
1723   {
1724     DBG(DBG_error, "umax_give_scanner: command returned status %s\n", sane_strstatus(status));
1725   }
1726   else
1727   {
1728     DBG(DBG_info, "scanner released\n");
1729   }
1730 
1731   if (!dev->batch_scan || dev->batch_end)
1732   {
1733     umax_reposition_scanner(dev);
1734   }
1735   else
1736   {
1737     usleep(200000); /* 200 ms pause to make sure program does not exit before scanner is ready */
1738   }
1739 
1740   return status;
1741 }
1742 
1743 
1744 /* ------------------------------------------------------------ UMAX SEND GAMMA DATA ----------------------- */
1745 
1746 
umax_send_gamma_data(Umax_Device *dev, void *gamma_data, int color)1747 static void umax_send_gamma_data(Umax_Device *dev, void *gamma_data, int color)
1748 {
1749  unsigned char *data = gamma_data;
1750  unsigned char *dest;
1751  int length;
1752  SANE_Status status;
1753 
1754   DBG(DBG_proc, "send_gamma_data\n");
1755 
1756   if (dev->inquiry_gamma_dwload == 0)
1757   {
1758     DBG(DBG_error, "ERROR: gamma download not available\n");
1759     return;
1760   }
1761 
1762   memcpy(dev->buffer[0], send.cmd, send.size);							     /* send */
1763   set_S_datatype_code(dev->buffer[0], S_datatype_gamma);					      /* gamma curve */
1764 
1765   dest = dev->buffer[0] + send.size;
1766 
1767   if (dev->inquiry_gamma_DCF == 0)						      /* gamma format type 0 */
1768   {
1769     DBG(DBG_info, "using gamma download curve format type 0\n");
1770 
1771     memcpy(dest, gamma_DCF0.cmd, gamma_DCF0.size);
1772 
1773     if (color == 1)										/* one color */
1774     {
1775       set_DCF0_gamma_lines(dest, DCF0_gamma_one_line);
1776 
1777       set_DCF0_gamma_color(dest, 0, DCF0_gamma_color_gray);				        /* grayscale */
1778       if ( (dev->colormode == RGB) && (dev->three_pass != 0) )				     /* 3 pass color */
1779       {
1780         set_DCF0_gamma_color(dest, 0,  dev->three_pass_color);					/* set color */
1781       }
1782 
1783       dest = dest + 2;
1784       memcpy(dest, data, 1024);								/* copy data */
1785 
1786       set_S_xfer_length(dev->buffer[0], 1026);						       /* set length */
1787       status = umax_scsi_cmd(dev, dev->buffer[0], send.size + 1026, NULL, NULL);
1788       if (status)
1789       {
1790         DBG(DBG_error, "umax_send_gamma_data(DCF=0, one color): command returned status %s\n", sane_strstatus(status));
1791       }
1792     }
1793     else										     /* three colors */
1794     {
1795       set_DCF0_gamma_lines(dest, DCF0_gamma_three_lines);
1796 
1797       set_DCF0_gamma_color(dest, 0, DCF0_gamma_color_red);					      /* red */
1798       set_DCF0_gamma_color(dest, 1, DCF0_gamma_color_green);					    /* green */
1799       set_DCF0_gamma_color(dest, 2, DCF0_gamma_color_blue);					     /* blue */
1800 
1801       dest = dest + 2;
1802       memcpy(dest, data, 1024);								    /* copy red data */
1803 
1804       dest = dest + 1025;
1805       data = data + 1024;
1806       memcpy(dest, data, 1024);								  /* copy green data */
1807 
1808       dest = dest + 1025;
1809       data = data + 1024;
1810       memcpy(dest, data, 1024);								   /* copy blue data */
1811 
1812       set_S_xfer_length(dev->buffer[0], 3076);						       /* set length */
1813       status = umax_scsi_cmd(dev, dev->buffer[0], send.size + 3076, NULL, NULL);
1814       if (status)
1815       {
1816         DBG(DBG_error, "umax_send_gamma_data(DCF=0, RGB): command returned status %s\n", sane_strstatus(status));
1817       }
1818     }
1819   }
1820   else if (dev->inquiry_gamma_DCF == 1)						      /* gamma format type 1 */
1821   {
1822     DBG(DBG_info, "using gamma download curve format type 1\n");
1823 
1824     memcpy(dest, gamma_DCF1.cmd, gamma_DCF1.size);
1825 
1826     set_DCF1_gamma_color(dest, DCF1_gamma_color_gray);					        /* grayscale */
1827     if ( (dev->colormode == RGB) && (dev->three_pass != 0) )				     /* 3 pass color */
1828     {
1829       set_DCF1_gamma_color(dest,  dev->three_pass_color);					/* set color */
1830     }
1831 
1832     dest = dest + 2;
1833     memcpy(dest, data, 256);									/* copy data */
1834 
1835     set_S_xfer_length(dev->buffer[0], 258);						       /* set length */
1836     status = umax_scsi_cmd(dev, dev->buffer[0], send.size + 258, NULL, NULL);
1837     if (status)
1838     {
1839       DBG(DBG_error, "umax_send_gamma_data(DCF=1): command returned status %s\n", sane_strstatus(status));
1840     }
1841   }
1842   else if (dev->inquiry_gamma_DCF == 2)						      /* gamma format type 2 */
1843   {
1844     DBG(DBG_info, "using gamma download curve format type 2\n");
1845 
1846     memcpy(dest, gamma_DCF2.cmd, gamma_DCF2.size);
1847 
1848     set_DCF2_gamma_color(dest, DCF2_gamma_color_gray);					        /* grayscale */
1849     if ( (dev->colormode == RGB) && (dev->three_pass != 0) )				     /* 3 pass color */
1850     { set_DCF2_gamma_color(dest, dev->three_pass_color); }				        /* set color */
1851 
1852     if (color == 1)
1853     {
1854       set_DCF2_gamma_lines(dest, DCF2_gamma_one_line);
1855     }
1856     else
1857     {
1858       set_DCF2_gamma_lines(dest, DCF2_gamma_three_lines);
1859     }
1860 
1861     set_DCF2_gamma_input_bits(dest, dev->gamma_input_bits_code);
1862     set_DCF2_gamma_output_bits(dest, dev->bits_per_pixel_code);
1863 
1864     dest = dev->buffer[0] + send.size + gamma_DCF2.size;					    /* write to dest */
1865 
1866     if (dev->gamma_input_bits_code & 32)
1867     {
1868       length = 65536; /* 16 input bits */
1869     }
1870     else if (dev->gamma_input_bits_code & 16)
1871     {
1872       length = 16384; /* 14 input bits */
1873     }
1874     else if (dev->gamma_input_bits_code & 8)
1875     {
1876       length = 4096; /* 12 input bits */
1877     }
1878     else if (dev->gamma_input_bits_code & 4)
1879     {
1880       length = 1024; /* 10 input bits */
1881     }
1882     else if (dev->gamma_input_bits_code & 2)
1883     {
1884       length = 512; /* 9 input bits */
1885     }
1886     else
1887     {
1888       length = 256; /* 8 input bits */
1889     }
1890 
1891     if (dev->bits_per_pixel_code != 1)					/* more than 8 output bits per pixel */
1892     {
1893       length = length * 2; /* = 2 output bytes */
1894     }
1895 
1896     if (dev->bufsize >= color*length+gamma_DCF2.size)
1897     {
1898       set_S_xfer_length(dev->buffer[0], color*length+gamma_DCF2.size);			       /* set length */
1899       memcpy(dest, data, color*length);								/* copy data */
1900 
1901       status = umax_scsi_cmd(dev, dev->buffer[0], send.size+gamma_DCF2.size + length * color, NULL, NULL);
1902       if (status)
1903       {
1904         DBG(DBG_error, "umax_send_gamma_data(DCF=2): command returned status %s\n", sane_strstatus(status));
1905       }
1906     }
1907     else
1908     {
1909       DBG(DBG_error, "ERROR: too small scsi buffer (%d bytes) to send gamma data\n", dev->bufsize);
1910     }
1911   }
1912   else
1913   {
1914     DBG(DBG_error, "ERROR: unknown gamma download curve type for this scanner\n");
1915   }
1916 }
1917 
1918 
1919 /* ------------------------------------------------------------ UMAX SEND DATA  ---------------------------- */
1920 
1921 
umax_send_data(Umax_Device *dev, void *data, int size, int datatype)1922 static void umax_send_data(Umax_Device *dev, void *data, int size, int datatype)
1923 {
1924  unsigned char *dest;
1925  SANE_Status status;
1926 
1927   memcpy(dev->buffer[0], send.cmd, send.size);							     /* send */
1928   set_S_datatype_code(dev->buffer[0], datatype);						     /* set datatype */
1929   set_S_xfer_length(dev->buffer[0], size);								    /* bytes */
1930 
1931   dest=dev->buffer[0] + send.size;
1932   memcpy(dest, data, size);									/* copy data */
1933 
1934   status = umax_scsi_cmd(dev, dev->buffer[0], send.size + size, NULL, NULL);
1935   if (status)
1936   {
1937     DBG(DBG_error, "umax_send_data: command returned status %s\n", sane_strstatus(status));
1938   }
1939 }
1940 
1941 
1942 /* ------------------------------------------------------------ UMAX SEND HALFTONE PATTERN ----------------- */
1943 
1944 
1945 #ifndef UMAX_HIDE_UNUSED
umax_send_halftone_pattern(Umax_Device *dev, void *data, int size)1946 static void umax_send_halftone_pattern(Umax_Device *dev, void *data, int size)
1947 {
1948   DBG(DBG_proc,"send_halftone_pattern\n");
1949   umax_send_data(dev, data, size*size, S_datatype_halftone);
1950 }
1951 #endif
1952 
1953 
1954 /* ------------------------------------------------------------ UMAX SEND SHADING DATA  -------------------- */
1955 
1956 
umax_send_shading_data(Umax_Device *dev, void *data, int size)1957 static void umax_send_shading_data(Umax_Device *dev, void *data, int size)
1958 {
1959   DBG(DBG_proc,"send_shading_data\n");
1960   umax_send_data(dev, data, size, S_datatype_shading);
1961 }
1962 
1963 
1964 /* ------------------------------------------------------------ UMAX SEND GAIN DATA  ----------------------- */
1965 
1966 #ifndef UMAX_HIDE_UNUSED
umax_send_gain_data(Umax_Device *dev, void *data, int size)1967 static void umax_send_gain_data(Umax_Device *dev, void *data, int size)
1968 {
1969   DBG(DBG_proc,"send_gain_data\n");
1970   umax_send_data(dev, data, size, S_datatype_gain);
1971 }
1972 #endif
1973 
1974 
1975 /* ------------------------------------------------------------ UMAX QUEUE READ IMAGE DATA REQ ------------- */
1976 
umax_queue_read_image_data_req(Umax_Device *dev, unsigned int length, int bufnr)1977 static SANE_Status umax_queue_read_image_data_req(Umax_Device *dev, unsigned int length, int bufnr)
1978 {
1979  SANE_Status status;
1980 
1981   DBG(DBG_proc, "umax_queue_read_image_data_req for buffer[%d], length = %d\n", bufnr, length);
1982 
1983   set_R_xfer_length(sread.cmd, length);							       /* set length */
1984   set_R_datatype_code(sread.cmd, R_datatype_imagedata);					     /* set datatype */
1985 
1986   dev->length_queued[bufnr] = length; /* set length request */
1987   dev->length_read[bufnr]   = length; /* set length request, can be changed asynchronous by umax_scsi_req_enter */
1988 
1989   status = umax_scsi_req_enter(dev, sread.cmd, sread.size, dev->buffer[bufnr], &(dev->length_read[bufnr]), &(dev->queue_id[bufnr]));
1990   if (status)
1991   {
1992     DBG(DBG_error, "umax_queue_read_image_data_req: command returned status %s\n", sane_strstatus(status));
1993     return -1;
1994   }
1995   else
1996   {
1997     DBG(DBG_info2, "umax_queue_read_image_data_req: id for buffer[%d] is %p\n", bufnr, dev->queue_id[bufnr]);
1998   }
1999 
2000   return length;
2001 }
2002 
2003 /* ------------------------------------------------------------ UMAX WAIT QUEUED IMAGE DATA ---------------- */
2004 
2005 
umax_wait_queued_image_data(Umax_Device *dev, int bufnr)2006 static int umax_wait_queued_image_data(Umax_Device *dev, int bufnr)
2007 {
2008  SANE_Status status;
2009 
2010   DBG(DBG_proc, "umax_wait_queued_image_data for buffer[%d] (id=%p)\n", bufnr, dev->queue_id[bufnr]);
2011 
2012   status = umax_scsi_req_wait(dev, dev->queue_id[bufnr]);
2013   if (status)
2014   {
2015     DBG(DBG_error, "umax_wait_queued_image_data: wait returned status %s\n", sane_strstatus(status));
2016     return -1;
2017   }
2018 
2019  return SANE_STATUS_GOOD;
2020 }
2021 
2022 
2023 /* ------------------------------------------------------------ UMAX READ DATA ----------------------------- */
2024 
2025 
umax_read_data(Umax_Device *dev, size_t length, int datatype)2026 static int umax_read_data(Umax_Device *dev, size_t length, int datatype)
2027 {
2028  SANE_Status status;
2029 
2030   set_R_xfer_length(sread.cmd, length);							       /* set length */
2031   set_R_datatype_code(sread.cmd, datatype);						     /* set datatype */
2032 
2033   status = umax_scsi_cmd(dev, sread.cmd, sread.size, dev->buffer[0], &length);
2034   if (status)
2035   {
2036     DBG(DBG_error, "umax_read_data: command returned status %s\n", sane_strstatus(status));
2037     return -1;
2038   }
2039 
2040  return length;
2041 }
2042 
2043 
2044 /* ------------------------------------------------------------ UMAX READ SHADING DATA  -------------------- */
2045 
2046 
umax_read_shading_data(Umax_Device *dev, unsigned int length)2047 static int umax_read_shading_data(Umax_Device *dev, unsigned int length)
2048 {
2049   DBG(DBG_proc,"read_shading_data\n");
2050   return umax_read_data(dev, length, R_datatype_shading);
2051 }
2052 
2053 
2054 /* ------------------------------------------------------------ UMAX READ GAIN DATA  ----------------------- */
2055 
2056 
2057 #ifndef UMAX_HIDE_UNUSED
umax_read_gain_data(Umax_Device *dev, unsigned int length)2058 static int umax_read_gain_data(Umax_Device *dev, unsigned int length)
2059 {
2060   DBG(DBG_proc,"read_gain_data\n");
2061   return umax_read_data(dev, length, R_datatype_gain);
2062 }
2063 #endif
2064 
2065 
2066 /* ------------------------------------------------------------ UMAX READ IMAGE DATA  ---------------------- */
2067 
2068 
2069 #ifndef UMAX_HIDE_UNUSED
umax_read_image_data(Umax_Device *dev, unsigned int length)2070 static int umax_read_image_data(Umax_Device *dev, unsigned int length)
2071 {
2072   DBG(DBG_proc,"read_image_data\n");
2073   WAIT_SCANNER;
2074   return umax_read_data(dev, length, R_datatype_imagedata);
2075 }
2076 #endif
2077 
2078 
2079 /* ------------------------------------------------------------ UMAX CORRECT LIGHT ------------------------- */
2080 
2081 
umax_correct_light(int light, int analog_gamma_byte)2082 static int umax_correct_light(int light, int analog_gamma_byte)  /* correct highlight/shadow if analog gamma is set */
2083 {
2084   double analog_gamma;
2085   analog_gamma=analog_gamma_table[analog_gamma_byte];
2086   return( (int) 255 * pow(  ((double) light)/255.0 , (1.0/analog_gamma) )+.5 );
2087 }
2088 
2089 
2090 /* ------------------------------------------------------------ UMAX SET WINDOW PARAM ---------------------- */
2091 
2092 
2093 /* set_window_param sets all the window parameters. This means building a */
2094 /* fairly complicated SCSI command before sending it...  */
2095 
umax_set_window_param(Umax_Device *dev)2096 static SANE_Status umax_set_window_param(Umax_Device *dev)
2097 {
2098  SANE_Status status;
2099  int num_dblocks = 1;		 		       /* number of window descriptor blocks, usually 1 or 3 */
2100  unsigned char buffer_r[max_WDB_size], buffer_g[max_WDB_size], buffer_b[max_WDB_size];
2101 
2102   DBG(DBG_proc, "set_window_param\n");
2103   memset(buffer_r, '\0', max_WDB_size);							     /* clear buffer */
2104   set_WDB_length(dev->wdb_len);						   /* length of win descriptor block */
2105   memcpy(buffer_r, window_descriptor_block.cmd, window_descriptor_block.size);		 /* copy preset data */
2106 
2107   set_WD_wid(buffer_r, 0);								/* window identifier */
2108   set_WD_auto(buffer_r, dev->set_auto);					    /* 0 or 1: don't know what it is */
2109 
2110 												  /* geometry */
2111   set_WD_Xres(buffer_r, dev->x_resolution);					      /* x resolution in dpi */
2112   set_WD_Yres(buffer_r, dev->y_resolution);					      /* y resolution in dpi */
2113   set_WD_ULX(buffer_r, dev->upper_left_x);						      /* left_edge x */
2114   set_WD_ULY(buffer_r, dev->upper_left_y);						     /* upper_edge y */
2115   set_WD_width(buffer_r, dev->scanwidth);							    /* width */
2116   set_WD_length(buffer_r, dev->scanlength);							   /* length */
2117 
2118 												       /* BTC */
2119   set_WD_brightness(buffer_r, dev->brightness);					/* brightness, only halftone */
2120   set_WD_threshold(buffer_r, dev->threshold);					  /* threshold, only lineart */
2121   set_WD_contrast(buffer_r, dev->contrast);					  /* contrast, only halftone */
2122 
2123 									       /* scanmode, preset to LINEART */
2124   set_WD_composition(buffer_r, WD_comp_lineart);					/* image composition */
2125 											     /* = (scan-mode) */
2126   set_WD_bitsperpixel(buffer_r, WD_bits_1);				   /* bits/pixel (1,8,9,10,12,14,16) */
2127   set_WD_halftone(buffer_r, dev->halftone);					  /* select halftone-pattern */
2128   set_WD_RIF(buffer_r, dev->reverse);					  /* reverse, invert black and white */
2129   set_WD_speed(buffer_r, dev->WD_speed);						        /* set speed */
2130   set_WD_select_color(buffer_r, WD_color_gray);					   /* color for window-block */
2131 
2132 						   /* set highlight and shadow in dependence of analog gamma */
2133   set_WD_highlight(buffer_r, umax_correct_light(dev->highlight_r, dev->analog_gamma_r));
2134   set_WD_shadow(buffer_r, umax_correct_light(dev->shadow_r, dev->analog_gamma_r));
2135 
2136 											      /* scan options */
2137   set_WD_gamma(buffer_r, dev->digital_gamma_r);						/* set digital gamma */
2138   set_WD_module(buffer_r, dev->module);						  /* flatbed or transparency */
2139   set_WD_CBHS(buffer_r, dev->cbhs_range);							/* 50 or 255 */
2140   set_WD_FF(buffer_r, dev->fix_focus_position);					       /* fix focus position */
2141   set_WD_RMIF(buffer_r, dev->reverse_multi);					     /* reverse color-values */
2142   set_WD_FDC(buffer_r, dev->lens_cal_in_doc_pos);		    /* lens calibration in document position */
2143   set_WD_PF(buffer_r, dev->disable_pre_focus);						/* disable pre focus */
2144   set_WD_LCL(buffer_r, dev->holder_focus_pos_0mm);		    /* 0.6mm <-> 0.0mm holder focus position */
2145   set_WD_HBT(buffer_r, dev->low_byte_first);			       /* set byte order for 16 bit scanners */
2146   set_WD_DOR(buffer_r, dev->dor);						   /* double-resolution-mode */
2147   set_WD_scan_exposure_level(buffer_r, dev->exposure_time_scan_r);		       /* scan exposure time */
2148   set_WD_calibration_exposure_level(buffer_r, dev->exposure_time_calibration_r);/* calibration exposure time */
2149 
2150   set_WD_batch(buffer_r, dev->batch_scan);					     /* batch or normal scan */
2151   set_WD_MF(buffer_r, dev->manual_focus);				       /* automatic <-> manual focus */
2152   set_WD_line_arrangement(buffer_r, WD_line_arrengement_by_fw);		      /* line arrangement by scanner */
2153   set_WD_warmup(buffer_r, dev->warmup);								   /* warmup */
2154 
2155   set_WD_calibration(buffer_r, dev->calibration); 				        /* image calibration */
2156 
2157   set_WD_color_sequence(buffer_r, WD_color_sequence_RGB);				     /* sequence RGB */
2158   set_WD_color_ordering(buffer_r, WD_color_ordering_pixel);	      /* set to pixel for pbm, pgm, pnm-file */
2159   set_WD_analog_gamma(buffer_r, dev->analog_gamma_r );					     /* analog gamma */
2160   set_WD_lamp_c_density(buffer_r, dev->c_density);				   /* calibrat. lamp density */
2161   set_WD_lamp_s_density(buffer_r, dev->s_density);					/* scan lamp density */
2162   set_WD_next_upper_left(buffer_r, dev->batch_next_tl_y);	      /* batch scan next top left y position */
2163   set_WD_pixel_count(buffer_r, dev->width_in_pixels);					      /* pixel count */
2164   set_WD_line_count(buffer_r, dev->length_in_pixels);					       /* line count */
2165   set_WD_x_coordinate_base(buffer_r, dev->x_coordinate_base);				       /* dpi (1200) */
2166   set_WD_y_coordinate_base(buffer_r, dev->y_coordinate_base);				       /* dpi (1200) */
2167   set_WD_calibration_data_lines(buffer_r, dev->calib_lines);     /* required lines for calibration by driver */
2168 
2169 
2170   switch(dev->colormode)
2171   {
2172      case LINEART:										   /* LINEART */
2173       set_WD_composition(buffer_r, WD_comp_lineart);
2174       set_WD_bitsperpixel(buffer_r, WD_bits_1);
2175 
2176       set_WD_select_color(buffer_r, WD_color_gray);
2177      break;
2178 
2179      case HALFTONE:										  /* HALFTONE */
2180       set_WD_composition(buffer_r, WD_comp_dithered);
2181       set_WD_bitsperpixel(buffer_r, WD_bits_1);
2182 
2183       set_WD_select_color(buffer_r, WD_color_gray);
2184      break;
2185 
2186      case GRAYSCALE:										 /* GRAYSCALE */
2187       set_WD_composition(buffer_r, WD_comp_gray);
2188       set_WD_bitsperpixel(buffer_r, dev->bits_per_pixel);
2189 
2190       set_WD_select_color(buffer_r, WD_color_gray);
2191      break;
2192 
2193      case RGB_LINEART:								              /* COLOR MODES */
2194      case RGB_HALFTONE:
2195      case RGB:
2196       if (dev->colormode == RGB_LINEART )
2197       {
2198         set_WD_composition(buffer_r, WD_comp_rgb_bilevel);
2199         set_WD_bitsperpixel(buffer_r, WD_bits_1);
2200       }
2201       else if (dev->colormode == RGB_HALFTONE )
2202       {
2203         set_WD_composition(buffer_r, WD_comp_rgb_dithered);
2204         set_WD_bitsperpixel(buffer_r, WD_bits_1);
2205       }
2206       else /* RGB */
2207       {
2208         set_WD_composition(buffer_r, WD_comp_rgb_full);
2209         set_WD_bitsperpixel(buffer_r, dev->bits_per_pixel);
2210       }
2211 
2212       if (dev->three_pass == 0)
2213       {											       /* singlepass */
2214         num_dblocks = 3;
2215 
2216         if (dev->do_color_ordering != 0)
2217 	{
2218           set_WD_line_arrangement(buffer_r, WD_line_arrengement_by_driver);
2219 
2220 	  if (dev->CCD_distance == 0)
2221 	  {
2222             set_WD_color_ordering(buffer_r, WD_color_ordering_line_no_ccd);
2223           }
2224 	  else
2225 	  {
2226             set_WD_color_ordering(buffer_r, WD_color_ordering_line_w_ccd);
2227           }
2228         }
2229 
2230         memcpy(buffer_g, buffer_r, max_WDB_size);				       /* copy WDB for green */
2231         memcpy(buffer_b, buffer_r, max_WDB_size);					/* copy WDB for blue */
2232 
2233         set_WD_wid(buffer_r, WD_wid_red);					    /* window identifier red */
2234         set_WD_wid(buffer_g, WD_wid_green);					  /* window identifier green */
2235         set_WD_wid(buffer_b, WD_wid_blue);					   /* window identifier blue */
2236 
2237         set_WD_select_color(buffer_r, WD_color_red);			       /* select red for this window */
2238         set_WD_select_color(buffer_g, WD_color_green);			     /* select green for this window */
2239         set_WD_select_color(buffer_b, WD_color_blue);			      /* select blue for this window */
2240 
2241         set_WD_gamma(buffer_r, dev->digital_gamma_r);					    /* digital gamma */
2242         set_WD_gamma(buffer_g, dev->digital_gamma_g);
2243         set_WD_gamma(buffer_b, dev->digital_gamma_b);
2244 
2245         set_WD_analog_gamma(buffer_r, dev->analog_gamma_r);				     /* analog gamma */
2246         set_WD_analog_gamma(buffer_g, dev->analog_gamma_g);
2247         set_WD_analog_gamma(buffer_b, dev->analog_gamma_b);
2248 
2249 							      /* set highlight in dependence of analog gamma */
2250         set_WD_highlight(buffer_r, umax_correct_light(dev->highlight_r, dev->analog_gamma_r));
2251         set_WD_highlight(buffer_g, umax_correct_light(dev->highlight_g, dev->analog_gamma_g));
2252         set_WD_highlight(buffer_b, umax_correct_light(dev->highlight_b, dev->analog_gamma_b));
2253 
2254 								 /* set shadow in dependence of analog gamma */
2255         set_WD_shadow(buffer_r, umax_correct_light(dev->shadow_r, dev->analog_gamma_r));
2256         set_WD_shadow(buffer_g, umax_correct_light(dev->shadow_g, dev->analog_gamma_g));
2257         set_WD_shadow(buffer_b, umax_correct_light(dev->shadow_b, dev->analog_gamma_b));
2258 
2259         set_WD_scan_exposure_level(buffer_r, dev->exposure_time_scan_r);	  /* set scan exposure times */
2260         set_WD_scan_exposure_level(buffer_g, dev->exposure_time_scan_g);
2261         set_WD_scan_exposure_level(buffer_b, dev->exposure_time_scan_b);
2262 
2263         set_WD_calibration_exposure_level(buffer_r, dev->exposure_time_calibration_r);/* set calib exp times */
2264         set_WD_calibration_exposure_level(buffer_g, dev->exposure_time_calibration_g);
2265         set_WD_calibration_exposure_level(buffer_b, dev->exposure_time_calibration_b);
2266       }
2267       else
2268       {												/* threepass */
2269         set_WD_wid(buffer_r, 0);							/* window identifier */
2270         set_WD_color_ordering(buffer_r, WD_color_ordering_plane);				     /* ???? */
2271 
2272         if (dev->colormode == RGB_LINEART )
2273         {
2274           set_WD_composition(buffer_r, WD_comp_lineart);			       /* color-lineart-mode */
2275         }
2276         else if (dev->colormode == RGB_HALFTONE )
2277         {
2278           set_WD_composition(buffer_r, WD_comp_dithered);			      /* color-halftone-mode */
2279         }
2280         else /* RGB */
2281         {
2282           set_WD_composition(buffer_r, WD_comp_gray);					       /* color-mode */
2283         }
2284 
2285         switch (dev->three_pass_color)
2286         {
2287         case WD_wid_red:
2288            set_WD_select_color(buffer_r, WD_color_red);					        /* color red */
2289            set_WD_gamma(buffer_r, dev->digital_gamma_r);
2290            set_WD_analog_gamma(buffer_r, dev->analog_gamma_r);
2291            set_WD_highlight(buffer_r, umax_correct_light(dev->highlight_r, dev->analog_gamma_r));
2292            set_WD_shadow(buffer_r, umax_correct_light(dev->shadow_r, dev->analog_gamma_r));
2293            set_WD_scan_exposure_level(buffer_r, dev->exposure_time_scan_r);
2294            set_WD_calibration_exposure_level(buffer_r, dev->exposure_time_calibration_r);
2295            break;
2296 
2297         case WD_wid_green:
2298            set_WD_select_color(buffer_r, WD_color_green);				      /* color green */
2299            set_WD_gamma(buffer_r, dev->digital_gamma_g);
2300            set_WD_analog_gamma(buffer_r, dev->analog_gamma_g);
2301            set_WD_highlight(buffer_r, umax_correct_light(dev->highlight_g, dev->analog_gamma_g));
2302            set_WD_shadow(buffer_r, umax_correct_light(dev->shadow_g, dev->analog_gamma_g));
2303            set_WD_scan_exposure_level(buffer_r, dev->exposure_time_scan_g);
2304            set_WD_calibration_exposure_level(buffer_r, dev->exposure_time_calibration_g);
2305            break;
2306 
2307         case WD_wid_blue:
2308            set_WD_select_color(buffer_r, WD_color_blue);				       /* color blue */
2309            set_WD_gamma(buffer_r, dev->digital_gamma_b);
2310            set_WD_analog_gamma(buffer_r, dev->analog_gamma_b);
2311            set_WD_highlight(buffer_r, umax_correct_light(dev->highlight_b, dev->analog_gamma_b));
2312            set_WD_shadow(buffer_r, umax_correct_light(dev->shadow_b, dev->analog_gamma_b));
2313            set_WD_scan_exposure_level(buffer_r, dev->exposure_time_scan_b);
2314            set_WD_calibration_exposure_level(buffer_r, dev->exposure_time_calibration_b);
2315            break;
2316 
2317         } /* switch dev->three_pass_color */
2318 
2319       } /* if (single_pass) else (three_pass) */
2320      break;
2321   } /* switch dev->colormode, case RGB */
2322 
2323 										       /* prepare SCSI-BUFFER */
2324   memcpy(dev->buffer[0], set_window.cmd, set_window.size);					   /* SET-WINDOW cmd */
2325   memcpy(WPDB_OFF(dev->buffer[0]), window_parameter_data_block.cmd, window_parameter_data_block.size);   /* WPDB */
2326   set_WPDB_wdbnum(WPDB_OFF(dev->buffer[0]), num_dblocks);					       /* set WD_len */
2327   memcpy(WDB_OFF(dev->buffer[0],1), buffer_r, window_descriptor_block.size);		     /* add WD_block */
2328 
2329   if ( num_dblocks == 3)								/* if singelpass RGB */
2330   {
2331      memcpy(WDB_OFF(dev->buffer[0],2), buffer_g, window_descriptor_block.size);			/* add green */
2332      memcpy(WDB_OFF(dev->buffer[0],3), buffer_b, window_descriptor_block.size);			 /* add blue */
2333   }
2334 
2335 
2336   DBG(DBG_info2, "window descriptor block created with %d bytes\n", dev->wdb_len);
2337 
2338   set_SW_xferlen(dev->buffer[0], (window_parameter_data_block.size + (window_descriptor_block.size * num_dblocks)));
2339 
2340   status = umax_scsi_cmd(dev, dev->buffer[0], set_window.size + window_parameter_data_block.size +
2341                                               (window_descriptor_block.size * num_dblocks), NULL, NULL);
2342   if (status)
2343   {
2344     DBG(DBG_error, "umax_set_window_param: command returned status %s\n", sane_strstatus(status));
2345   }
2346   else
2347   {
2348     DBG(DBG_info, "window(s) set\n");
2349   }
2350 
2351  return status;
2352 }
2353 
2354 
2355 /* ------------------------------------------------------------ UMAX DO INQUIRY ---------------------------- */
2356 
2357 
umax_do_inquiry(Umax_Device *dev)2358 static void umax_do_inquiry(Umax_Device *dev)
2359 {
2360  size_t size;
2361  SANE_Status status;
2362 
2363   DBG(DBG_proc,"do_inquiry\n");
2364   memset(dev->buffer[0], '\0', 256);							     /* clear buffer */
2365 
2366   size = 5;
2367 
2368   set_inquiry_return_size(inquiry.cmd, size);  /* first get only 5 bytes to get size of inquiry_return_block */
2369   status = umax_scsi_cmd(dev, inquiry.cmd, inquiry.size, dev->buffer[0], &size);
2370   if (status)
2371   {
2372     DBG(DBG_error, "umax_do_inquiry: command returned status %s\n", sane_strstatus(status));
2373   }
2374 
2375   size = get_inquiry_additional_length(dev->buffer[0]) + 5;
2376 
2377   set_inquiry_return_size(inquiry.cmd, size);			        /* then get inquiry with actual size */
2378   status = umax_scsi_cmd(dev, inquiry.cmd, inquiry.size, dev->buffer[0], &size);
2379   if (status)
2380   {
2381     DBG(DBG_error, "umax_do_inquiry: command returned status %s\n", sane_strstatus(status));
2382   }
2383 }
2384 
2385 
2386 /* ------------------------------------------------------------ UMAX START SCAN ---------------------------- */
2387 
2388 
umax_start_scan(Umax_Device *dev)2389 static SANE_Status umax_start_scan(Umax_Device *dev)
2390 {
2391  int size = 1;
2392  SANE_Status status;
2393 
2394   DBG(DBG_proc,"start_scan\n");
2395 
2396   if (dev->adf) 							/* ADF selected: test for ADF errors */
2397   {
2398     umax_do_inquiry(dev);								      /* get inquiry */
2399 
2400     if (get_inquiry_ADF_paper_jam(dev->buffer[0]))					   /* test for ADF paper jam */
2401     {
2402       DBG(DBG_error,"ERROR: umax_start_scan: ADF paper jam\n");
2403       return SANE_STATUS_JAMMED;
2404     }
2405     else if (get_inquiry_ADF_cover_open(dev->buffer[0]))				  /* test for ADF cover open */
2406     {
2407       DBG(DBG_error,"ERROR: umax_start_scan: ADF cover open\n");
2408       return SANE_STATUS_COVER_OPEN;
2409     }
2410     else if (get_inquiry_ADF_no_paper(dev->buffer[0]))				    /* test for ADF no paper */
2411     {
2412       DBG(DBG_error,"ERROR: umax_start_scan: ADF no paper\n");
2413       return SANE_STATUS_NO_DOCS;
2414     }
2415   }
2416 
2417   set_SC_quality(scan.cmd, dev->quality);						  /*  1=qual, 0=fast */
2418   set_SC_adf(    scan.cmd, dev->adf);							/* ADF, 0=off, 1=use */
2419   set_SC_preview(scan.cmd, dev->preview);							/* 1=preview */
2420 
2421   set_SC_wid(scan.cmd, 1, 0);								/* Window-Identifier */
2422 
2423   set_SC_xfer_length(scan.cmd, size);							  /* following Bytes */
2424 
2425   DBG(DBG_info,"starting scan\n");
2426 
2427   status = umax_scsi_cmd(dev, scan.cmd, scan.size + size, NULL, NULL);
2428   if (status)
2429   {
2430     DBG(DBG_error, "umax_start_scan: command returned status %s\n", sane_strstatus(status));
2431   }
2432 
2433  return status;
2434 }
2435 
2436 
2437 /* ------------------------------------------------------------ UMAX DO CALIBRATION ------------------------ */
2438 
2439 
umax_do_calibration(Umax_Device *dev)2440 static SANE_Status umax_do_calibration(Umax_Device *dev)
2441 {
2442  SANE_Status status;
2443  unsigned int width   = 0;
2444  unsigned int lines   = 0;
2445  unsigned int bytespp = 0;
2446 
2447   DBG(DBG_proc,"do_calibration\n");
2448 
2449   status = umax_wait_scanner(dev);
2450 
2451   if ((status == SANE_STATUS_GOOD) && (dev->do_calibration != 0))			    /* calibration by driver */
2452   {
2453    unsigned char *shading_data = 0;
2454    unsigned int i, j;
2455    long *average;
2456 
2457 
2458     DBG(DBG_info,"driver is doing calibration\n");
2459 
2460 
2461     if (umax_execute_request_sense)
2462     {
2463       DBG(DBG_info,"request sense call is enabled\n");
2464       memset(dev->buffer[0], 0, rs_return_block_size);					  /* clear sense data buffer */
2465       umax_do_request_sense(dev);					   /* new request-sense call to get all data */
2466     }
2467     else
2468     {
2469       DBG(DBG_info,"request sense call is disabled\n");
2470     }
2471 
2472     if (get_RS_SCC_condition_code(dev->buffer[0]) != 1)
2473     {
2474       DBG(DBG_warning,"WARNING: missing information about shading-data\n");
2475       DBG(DBG_warning,"         driver tries to guess missing values!\n");
2476 
2477       if ((dev->calibration_area != UMAX_CALIBRATION_AREA_CCD) && (!dev->batch_scan))
2478       /* calibration is done with image geometry and depth */
2479       {
2480         DBG(DBG_warning,"         Calibration is done with selected image geometry and depth!\n");
2481 
2482         width = dev->scanwidth * dev->relevant_optical_res / dev->x_coordinate_base;
2483 
2484         if (dev->calibration_width_offset > -99999) /* driver or user (umax.conf) define an offset */
2485         {
2486           width = width + dev->calibration_width_offset;
2487           DBG(DBG_warning,"         Using calibration width offset of %d\n", dev->calibration_width_offset);
2488         }
2489 
2490         if (dev->colormode == RGB)
2491         {
2492           width = width * 3;
2493         }
2494 
2495         lines   = dev->calib_lines;
2496 
2497         if (dev->gamma_input_bits_code <= 1)
2498         {
2499           bytespp = 1; /* 8 bit mode */
2500         }
2501         else
2502         {
2503           bytespp = 2; /* 16 bit mode */
2504         }
2505       }
2506       else /*  calibration is done with full scanarea and full depth */
2507       {
2508         DBG(DBG_warning,"         Calibration is done for each CCD pixel with full depth!\n");
2509 
2510         width = (int)(dev->inquiry_fb_width * dev->inquiry_optical_res);
2511 
2512         if (dev->batch_scan)
2513         {
2514           if (dev->calibration_width_offset_batch > -99999) /* driver or user (umax.conf) define an offset for batch scanning */
2515           {
2516             width = width + dev->calibration_width_offset_batch;
2517             DBG(DBG_warning,"         Using calibration width offset for batch scanning of %d\n", dev->calibration_width_offset_batch);
2518           }
2519         }
2520         else /* normal scan */
2521         {
2522           if (dev->calibration_width_offset > -99999) /* driver or user (umax.conf) define an offset */
2523           {
2524             width = width + dev->calibration_width_offset;
2525             DBG(DBG_warning,"         Using calibration width offset of %d\n", dev->calibration_width_offset);
2526           }
2527         }
2528 
2529         if (dev->colormode == RGB)
2530         {
2531           width = width * 3;
2532         }
2533 
2534         lines = dev->calib_lines;
2535 
2536         if (dev->gamma_input_bits_code <= 1)
2537         {
2538           bytespp = 1; /* 8 bit mode */
2539          }
2540         else
2541         {
2542           bytespp = 2; /* 16 bit mode */
2543         }
2544       }
2545     }
2546     else
2547     {
2548       lines   =  get_RS_SCC_calibration_lines(dev->buffer[0]);
2549       bytespp =  get_RS_SCC_calibration_bytespp(dev->buffer[0]);
2550       width   =  get_RS_SCC_calibration_bytesperline(dev->buffer[0]) / bytespp;
2551     }
2552 
2553     if (dev->calibration_bytespp > 0) /* correct bytespp if necessary and driver knows about it or user did select it */
2554     {
2555       bytespp = dev->calibration_bytespp;
2556     }
2557 
2558     DBG(DBG_info,"scanner sends %d lines with %d pixels and %d bytes/pixel\n", lines, width, bytespp);
2559 
2560     if (width * bytespp > dev->bufsize)
2561     {
2562       DBG(DBG_error,"ERROR: scsi buffer is to small for one shading line, calibration aborted\n");
2563       DBG(DBG_error,"=> change umax.conf options scsi-buffer-size-min and scsi-buffer-size-max\n");
2564      return SANE_STATUS_NO_MEM;
2565     }
2566 
2567     /* UMAX S12 sends a kind of uncalibrated image data, bright -> 255, dark -> 0 */
2568     /* (although 0 is not black) my scanner sends values around 220 */
2569     /* for some scanners the data is simply sent back, other scanners want 255-value as awnswer */
2570 
2571     average = calloc(width, sizeof(long));
2572     if (average == 0)
2573     {
2574       DBG(DBG_error,"ERROR: could not allocate memory for averaging shading data: calibration aborted\n");
2575      return SANE_STATUS_NO_MEM;
2576     }
2577 
2578     shading_data = calloc(width, bytespp);
2579     if (shading_data == 0)
2580     {
2581       DBG(DBG_error,"ERROR: could not allocate memory for shading data: calibration aborted\n");
2582      return SANE_STATUS_NO_MEM;
2583     }
2584 
2585     if (bytespp == 1)					 /* 1 byte per pixel */
2586     {
2587       DBG(DBG_info,"calculating average value for 8 bit shading data!\n");
2588 
2589       for (i=0; i<lines; i++)
2590       {
2591         umax_read_shading_data(dev, width * bytespp);
2592 
2593         for (j=0; j<width; j++)
2594         {
2595           average[j] += (long) dev->buffer[0][j];
2596         }
2597 
2598         DBG(DBG_read,"8 bit shading-line %d read\n", i+1);
2599       }
2600 
2601       for (j=0; j<width; j++)
2602       {
2603         shading_data[j] = (unsigned char) (average[j] / lines);
2604       }
2605     }
2606     else if (dev->low_byte_first) /* 2 bytes per pixel with low byte first */
2607     {
2608       DBG(DBG_info,"calculating average value for 16 bit shading data (low byte first)!\n");
2609       for (i=0; i<lines; i++)
2610       {
2611         umax_read_shading_data(dev, width * bytespp);
2612 
2613         for (j=0; j<width; j++)
2614         {
2615           average[j] += (long) 256 * dev->buffer[0][2*j+1] + dev->buffer[0][2*j] ;
2616         }
2617 
2618         DBG(DBG_read,"16 bit shading-line %d read\n", i+1);
2619       }
2620 
2621       for (j=0; j<width; j++)
2622       {
2623         shading_data[2*j+1] = (unsigned char) (average[j] / (256 * lines));
2624         shading_data[2*j]   = (unsigned char) (average[j] / lines);
2625       }
2626     }
2627     else					/* 2 bytes per pixel with highbyte first */
2628     {
2629       DBG(DBG_info,"calculating average value for 16 bit shading data (high byte first)!\n");
2630       for (i=0; i<lines; i++)
2631       {
2632         umax_read_shading_data(dev, width * bytespp);
2633 
2634         for (j=0; j<width; j++)
2635         {
2636           average[j] += (long) 256 * dev->buffer[0][2*j] + dev->buffer[0][2*j + 1] ;
2637         }
2638 
2639         DBG(DBG_read,"16 bit shading-line %d read\n", i+1);
2640       }
2641 
2642       for (j=0; j<width; j++)
2643       {
2644         shading_data[2*j]   = (unsigned char) (average[j] / (256 * lines));
2645         shading_data[2*j+1] = (unsigned char) (average[j] / lines);
2646       }
2647     }
2648 
2649     free(average);
2650 
2651     if ( (dev->invert_shading_data) ) /* invert data */
2652     {
2653       if (bytespp == 1)
2654       {
2655         DBG(DBG_info,"inverting 8 bit shading data\n");
2656 
2657         for (j=0; j<width; j++)
2658         {
2659           shading_data[j] = 255 - shading_data[j];
2660         }
2661       }
2662       else
2663       {
2664        unsigned int value;
2665 
2666         DBG(DBG_info,"inverting 16 bit shading data\n");
2667 
2668         for (j=0; j<width; j++)
2669         {
2670           value = shading_data[2*j] + shading_data[2*j+1] * 256;
2671           value = 65535 - value;
2672           shading_data[2*j]   = (unsigned char) value/256;
2673           shading_data[2*j+1] = (unsigned char) value & 255;
2674         }
2675       }
2676     }
2677 
2678     umax_send_shading_data(dev, shading_data, width * bytespp);
2679     DBG(DBG_info,"shading-data sent\n");
2680     free(shading_data);
2681 
2682     status = umax_start_scan(dev);						      /* now start real scan */
2683 
2684     dev->do_calibration = 0;
2685   }
2686 
2687  return status;
2688 }
2689 
2690 
2691 /* ------------------------------------------------------------ UMAX DO NEW INQUIRY ------------------------ */
2692 
2693 
umax_do_new_inquiry(Umax_Device *dev, size_t size)2694 static void umax_do_new_inquiry(Umax_Device *dev, size_t size)	       /* call inquiry again if wrong length */
2695 {
2696  SANE_Status status;
2697 
2698   DBG(DBG_proc,"do_new_inquiry\n");
2699   memset(dev->buffer[0], '\0', 256);							     /* clear buffer */
2700 
2701   set_inquiry_return_size(inquiry.cmd, size);
2702   status = umax_scsi_cmd(dev, inquiry.cmd, inquiry.size, dev->buffer[0], &size);
2703   if (status)
2704   {
2705     DBG(DBG_error, "umax_do_new_inquiry: command returned status %s\n", sane_strstatus(status));
2706   }
2707 }
2708 
2709 
2710 /* ------------------------------------------------------------ UMAX CORRECT INQUIRY ----------------------- */
2711 
2712 
umax_correct_inquiry(Umax_Device *dev, char *vendor, char *product, char *version)2713 static void umax_correct_inquiry(Umax_Device *dev, char *vendor, char *product, char *version)
2714 {
2715   DBG(DBG_info, "umax_correct_inquiry(\"%s %s %s\")\n", vendor, product, version);
2716 
2717   if (!strncmp(vendor, "UMAX ", 5))
2718   {
2719     if (!strncmp(product, "Astra 600S ", 11))
2720     {
2721      int add_len = get_inquiry_additional_length(dev->buffer[0]);
2722 
2723       DBG(DBG_warning,"setting up special options for %s\n", product);
2724 
2725       if (add_len == 0x8f)
2726       {
2727         DBG(DBG_warning," - correcting wrong inquiry data\n");
2728 	umax_do_new_inquiry(dev, 0x9b);		  /* get inquiry with correct length */
2729         set_inquiry_length(dev->buffer[0], 0x9e); /* correct inquiry len */
2730 					      /* correct color-ordering from pixel to line_with_ccd_distance */
2731         set_inquiry_color_order(dev->buffer[0], IN_color_ordering_line_w_ccd);
2732 	set_inquiry_fb_uta_line_arrangement_mode(dev->buffer[0], 32);
2733 	set_inquiry_CCD_line_distance(dev->buffer[0], 8);
2734         /* we should reset ADF-bit here too */
2735 
2736         if (dev->invert_shading_data == -1) /* nothing defined in umax.conf */
2737         {
2738           DBG(DBG_warning," - activating inversion of shading data\n");
2739           dev->invert_shading_data = 1;
2740         }
2741       }
2742     }
2743     else if (!strncmp(product, "Astra 610S ", 11))
2744     {
2745      int add_len = get_inquiry_additional_length(dev->buffer[0]);
2746 
2747       DBG(DBG_warning,"setting up special options for %s\n", product);
2748 
2749       if (add_len == 0x8f)
2750       {
2751         DBG(DBG_warning," - correcting wrong inquiry data\n");
2752 	umax_do_new_inquiry(dev, 0x9b);		  /* get inquiry with correct length */
2753         set_inquiry_length(dev->buffer[0], 0x9e); /* correct inquiry len */
2754 					      /* correct color-ordering from pixel to line_with_ccd_distance */
2755         set_inquiry_color_order(dev->buffer[0], IN_color_ordering_line_w_ccd);
2756 	set_inquiry_fb_uta_line_arrangement_mode(dev->buffer[0], 33);
2757 	set_inquiry_CCD_line_distance(dev->buffer[0], 8);
2758 
2759         if (dev->invert_shading_data == -1) /* nothing defined in umax.conf */
2760         {
2761           DBG(DBG_warning," - activating inversion of shading data\n");
2762           dev->invert_shading_data = 1;
2763         }
2764       }
2765     }
2766     else if ( (!strncmp(product, "Astra 1200S ", 12)) ||
2767               (!strncmp(product, "Perfection600 ", 14)) )
2768     {
2769       DBG(DBG_warning,"using standard options for %s\n", product);
2770     }
2771     else if (!strncmp(product, "Astra 1220S ", 12))
2772     {
2773       DBG(DBG_warning,"setting up special options for %s\n", product);
2774 
2775       if (dev->gamma_lsb_padded == -1) /* nothing defined in umax.conf and not by backend */
2776       {
2777         DBG(DBG_warning," - 16 bit gamma table is created lsb padded\n");
2778         dev->gamma_lsb_padded = 1;
2779       }
2780 
2781       if (!strncmp(version, "V1.5 ", 4))
2782       {
2783         DBG(DBG_warning," - lamp control enabled for version %s\n", version);
2784         dev->lamp_control_available = 1;
2785       }
2786     }
2787     else if (!strncmp(product, "Astra 2100S ", 12))
2788     {
2789       DBG(DBG_warning,"setting up special options for %s\n", product);
2790       DBG(DBG_warning," - lamp control enabled\n");
2791       dev->lamp_control_available = 1;
2792 
2793       if (dev->calibration_bytespp == -1) /* no calibration-bytespp defined in umax.conf */
2794       {
2795         DBG(DBG_warning," - setting calibration_bytespp = 1\n");
2796         dev->calibration_bytespp = 1; /* scanner says 2 bytespp for calibration but 1 bytepp is correct */
2797       }
2798     }
2799     else if (!strncmp(product, "Astra 2200 ", 11))
2800     {
2801       DBG(DBG_warning,"setting up special options for %s\n", product);
2802       DBG(DBG_warning," - lamp control enabled\n");
2803       dev->lamp_control_available = 1;
2804 
2805       if (dev->calibration_area == -1) /* no calibration area defined in umax.conf */
2806       {
2807         DBG(DBG_warning," - calibration by driver is done for each CCD pixel\n");
2808         dev->calibration_area = UMAX_CALIBRATION_AREA_CCD;
2809       }
2810 
2811       if (dev->calibration_bytespp == -1) /* no calibration-bytespp defined in umax.conf */
2812       {
2813         DBG(DBG_warning," - setting calibration_bytespp = 2\n");
2814         dev->calibration_bytespp = 2;
2815       }
2816 
2817       DBG(DBG_warning," - common x and y resolution\n");
2818       dev->common_xy_resolutions = 1;
2819 
2820       if (dev->connection_type == SANE_UMAX_USB)
2821       {
2822         DBG(DBG_warning," - disabling quality calibration for USB connection\n");
2823 	set_inquiry_fw_quality(dev->buffer[0], 0);
2824       }
2825     }
2826     else if (!strncmp(product, "Astra 2400S ", 12))
2827     {
2828       DBG(DBG_warning,"setting up special options for %s\n", product);
2829       DBG(DBG_warning," - defining pauses\n");
2830       dev->pause_for_color_calibration = 7000;		/* pause between start_scan and do_calibration in ms */
2831       dev->pause_for_gray_calibration = 4000;		/* pause between start_scan and do_calibration in ms */
2832       dev->pause_after_calibration = 0000;		 /* pause between do_calibration and read data in ms */
2833       dev->pause_after_reposition = 3000;			      /* pause after repostion scanner in ms */
2834       dev->pause_for_moving = 3000;			         /* pause for moving scanhead over full area */
2835 
2836       DBG(DBG_warning," - correcting ADF bit in inquiry\n");
2837       set_inquiry_sc_adf(dev->buffer[0], 1);		   /* set second bit that indicates ADF is supported */
2838     }
2839     else if (!strncmp(product, "Vista-T630 ", 11))
2840     {
2841       DBG(DBG_warning,"setting up special options for %s\n", product);
2842 
2843       if (dev->slow == -1) /* option is not predefined in umax.conf */
2844       {
2845         DBG(DBG_warning," - activating slow option\n");
2846         dev->slow = 1;
2847       }
2848     }
2849     else if (!strncmp(product, "UC630 ", 6))
2850     {
2851       DBG(DBG_warning,"setting up special options for %s\n", product);
2852       DBG(DBG_warning," - reposition_scanner waits until move of scan head has finished\n");
2853       dev->pause_after_reposition = 0;	    /* call wait_scanner */
2854     }
2855     else if (!strncmp(product, "UC840 ", 6))
2856     {
2857       DBG(DBG_warning,"setting up special options for %s\n", product);
2858       DBG(DBG_warning," - reposition_scanner waits until move of scan head has finished\n");
2859       dev->pause_after_reposition = 0;	    /* call wait_scanner */
2860     }
2861     else if (!strncmp(product, "UC1260 ", 7))
2862     {
2863       DBG(DBG_warning,"setting up special options for %s\n", product);
2864       DBG(DBG_warning," - setting gamma download curve format to type 1\n");
2865       dev->inquiry_gamma_DCF = 1;				       /* define gamma download curve format */
2866       DBG(DBG_warning," - reposition_scanner waits until move of scan head has finished\n");
2867       dev->pause_after_reposition = 0;     /* call wait_scanner */
2868     }
2869     else if (!strncmp(product, "UC1200S ", 8))
2870     {
2871       DBG(DBG_warning,"setting up special options for %s\n", product);
2872       DBG(DBG_warning," - setting gamma download curve format to type 1\n");
2873       dev->inquiry_gamma_DCF = 1;				       /* define gamma download curve format */
2874     }
2875     else if (!strncmp(product, "UC1200SE ", 9))
2876     {
2877       DBG(DBG_warning,"setting up special options for %s\n", product);
2878       DBG(DBG_warning," - setting gamma download curve format to type 0\n");
2879       dev->inquiry_gamma_DCF = 0;				       /* define gamma download curve format */
2880     }
2881     else if (!strncmp(product, "ARCUS PLUS ", 11))
2882     {
2883       DBG(DBG_warning,"setting up special options for %s\n", product);
2884       DBG(DBG_warning," - setting gamma download curve format to type 0\n");
2885       dev->inquiry_gamma_DCF = 0;				       /* define gamma download curve format */
2886     }
2887     else if ( (!strncmp(product, "UMAX S-12G ", 11)) ||
2888               (!strncmp(product, "UMAX S-12 ", 10)) ||
2889               (!strncmp(product, "SuperVista S-12 ", 16)) )
2890     {
2891       DBG(DBG_warning,"setting up special options for %s\n", product);
2892 
2893       DBG(DBG_warning," - setting maximum calibration data lines to 66\n");
2894       set_inquiry_max_calibration_data_lines(dev->buffer[0], 66);
2895 
2896       if (dev->calibration_width_offset == -99999) /* no calibration-width-offset defined in umax.conf */
2897       {
2898         dev->calibration_width_offset = -1;
2899         DBG(DBG_warning," - adding calibration width offset of %d pixels\n", dev->calibration_width_offset);
2900       }
2901 
2902       if (dev->calibration_area == -1) /* no calibration area defined in umax.conf */
2903       {
2904         DBG(DBG_warning," - calibration by driver is done for each CCD pixel\n");
2905         dev->calibration_area = UMAX_CALIBRATION_AREA_CCD;
2906       }
2907     }
2908     else if (!strncmp(product, "Mirage D-16L ", 13))
2909     {
2910       DBG(DBG_warning,"setting up special options for %s\n", product);
2911       if (dev->calibration_area == -1) /* no calibration area defined in umax.conf */
2912       {
2913         DBG(DBG_warning," - calibration by driver is done for each CCD pixel\n");
2914         dev->calibration_area = UMAX_CALIBRATION_AREA_CCD;
2915       }
2916 
2917       if (dev->calibration_width_offset == -99999) /* no calibration-width-offset defined in umax.conf */
2918       {
2919         dev->calibration_width_offset = 308;
2920         DBG(DBG_warning," - adding calibration width offset of %d pixels\n", dev->calibration_width_offset);
2921       }
2922     }
2923     else if (!strncmp(product, "PowerLook III ", 14))
2924     {
2925       DBG(DBG_warning,"setting up special options for %s\n", product);
2926 
2927       if (dev->calibration_width_offset == -99999) /* no calibration-width-offset defined in umax.conf */
2928       {
2929         dev->calibration_width_offset = 28;
2930         DBG(DBG_warning," - adding calibration width offset of %d pixels\n", dev->calibration_width_offset);
2931       }
2932       /* calibration_area = image */
2933 
2934       if (dev->calibration_width_offset_batch == -99999) /* no calibration-width-offset for batch scanning defined in umax.conf */
2935       {
2936         dev->calibration_width_offset_batch = 828;
2937         DBG(DBG_warning," - adding calibration width offset for batch scanning of %d pixels\n", dev->calibration_width_offset_batch);
2938       }
2939     }
2940     else if (!strncmp(product, "Power Look 2000", 15))
2941     {
2942       DBG(DBG_warning,"setting up special options for %s\n", product);
2943 
2944       if (dev->calibration_width_offset == -99999) /* no calibration-width-offset defined in umax.conf */
2945       {
2946         dev->calibration_width_offset = 22;
2947         DBG(DBG_warning," - adding calibration width offset of %d pixels\n", dev->calibration_width_offset);
2948       }
2949       /* calibration_area = image */
2950 
2951       if (dev->calibration_width_offset_batch == -99999) /* no calibration-width-offset for batch scanning defined in umax.conf */
2952       {
2953         dev->calibration_width_offset_batch = 24;
2954         DBG(DBG_warning," - adding calibration width offset for batch scanning of %d pixels\n", dev->calibration_width_offset_batch);
2955       }
2956     }
2957     else if (!strncmp(product, "PowerLook 2100XL", 16))
2958     {
2959       DBG(DBG_warning,"setting up special options for %s\n", product);
2960 
2961       if (dev->calibration_width_offset == -99999) /* no calibration-width-offset defined in umax.conf */
2962       {
2963         dev->calibration_width_offset = 52;
2964         DBG(DBG_warning," - adding calibration width offset of %d pixels\n", dev->calibration_width_offset);
2965       }
2966       /* calibration_area = image */
2967 
2968       if (dev->calibration_width_offset_batch == -99999) /* no calibration-width-offset for batch scanning defined in umax.conf */
2969       {
2970         dev->calibration_width_offset_batch = 1052;
2971         DBG(DBG_warning," - adding calibration width offset for batch scanning of %d pixels\n", dev->calibration_width_offset_batch);
2972       }
2973 
2974       dev->force_quality_calibration = 1;
2975       DBG(DBG_warning," - always set quality calibration\n");
2976 
2977       /* the scanner uses the same exposure times for red, green and blue exposure_time_rgb_bind = 1 */
2978     }
2979     else if (!strncmp(product, "PowerLook 3000 ", 15))
2980     {
2981       DBG(DBG_warning,"setting up special options for %s\n", product);
2982 
2983       if (dev->calibration_width_offset == -99999) /* no calibration-width-offset defined in umax.conf */
2984       {
2985         dev->calibration_width_offset = 52;
2986         DBG(DBG_warning," - adding calibration width offset of %d pixels\n", dev->calibration_width_offset);
2987       }
2988       /* calibration_area = image */
2989 
2990       if (dev->calibration_width_offset_batch == -99999) /* no calibration-width-offset for batch scanning defined in umax.conf */
2991       {
2992         /* not tested */
2993         dev->calibration_width_offset_batch = 1052;
2994         DBG(DBG_warning," - adding calibration width offset for batch scanning of %d pixels\n", dev->calibration_width_offset_batch);
2995       }
2996     }
2997     else
2998     {
2999       DBG(DBG_warning,"using standard options for %s\n", product);
3000     }
3001   }
3002   else if (!strncmp(vendor, "LinoHell ", 9))
3003   {
3004     if ( (!strncmp(product, "Office ", 7)) || (!strncmp(product, "JADE ", 5)) ) /* is a Supervista S-12 */
3005     {
3006       DBG(DBG_warning,"setting up special options for %s\n", product);
3007 
3008       DBG(DBG_warning," - setting maximum calibration data lines to 66\n");
3009       set_inquiry_max_calibration_data_lines(dev->buffer[0], 66);
3010 
3011       if (dev->calibration_width_offset == -99999) /* no calibration-width-offset defined in umax.conf */
3012       {
3013         dev->calibration_width_offset = -1;
3014         DBG(DBG_warning," - adding calibration width offset of %d pixels\n", dev->calibration_width_offset);
3015       }
3016 
3017       if (dev->calibration_area == -1) /* no calibration area defined in umax.conf */
3018       {
3019         DBG(DBG_warning," - calibration by driver is done for each CCD pixel\n");
3020         dev->calibration_area = UMAX_CALIBRATION_AREA_CCD;
3021       }
3022     }
3023     else if (!strncmp(product, "OPAL2 ", 6)) /* looks like a Mirage II */
3024     {
3025       DBG(DBG_warning,"setting up special options for %s\n", product);
3026 
3027       if (dev->gamma_lsb_padded == -1) /* nothing defined in umax.conf and not by backend */
3028       {
3029         DBG(DBG_warning," - 16 bit gamma table is created lsb padded\n");
3030         dev->gamma_lsb_padded = 1;
3031       }
3032     }
3033   }
3034   else if (!strncmp(vendor, "Linotype ", 9))
3035   {
3036     if (!strncmp(product, "SAPHIR4 ", 8)) /* is a Powerlook III */
3037     {
3038       DBG(DBG_warning,"setting up special options for %s\n", product);
3039 
3040       if (dev->calibration_width_offset == -99999) /* no calibration-width-offset defined in umax.conf */
3041       {
3042         dev->calibration_width_offset = 28;
3043         DBG(DBG_warning," - adding calibration width offset of %d pixels\n", dev->calibration_width_offset);
3044       }
3045       /* calibration_area = image */
3046 
3047       if (dev->calibration_width_offset_batch == -99999) /* no calibration-width-offset for batch scanning defined in umax.conf */
3048       {
3049         dev->calibration_width_offset_batch = 828;
3050         DBG(DBG_warning," - adding calibration width offset for batch scanning of %d pixels\n", dev->calibration_width_offset_batch);
3051       }
3052     }
3053   }
3054   else if (!strncmp(vendor, "HDM ", 4))
3055   {
3056     if (!strncmp(product, "LS4H1S ", 7)) /* is a Powerlook III */
3057     {
3058       DBG(DBG_warning,"setting up special options for %s\n", product);
3059 
3060       if (dev->calibration_width_offset == -99999) /* no calibration-width-offset defined in umax.conf */
3061       {
3062         dev->calibration_width_offset = 28;
3063         DBG(DBG_warning," - adding calibration width offset of %d pixels\n", dev->calibration_width_offset);
3064       }
3065       /* calibration_area = image */
3066 
3067       if (dev->calibration_width_offset_batch == -99999) /* no calibration-width-offset for batch scanning defined in umax.conf */
3068       {
3069         dev->calibration_width_offset_batch = 828;
3070         DBG(DBG_warning," - adding calibration width offset for batch scanning of %d pixels\n", dev->calibration_width_offset_batch);
3071       }
3072     }
3073   }
3074   else if (!strncmp(vendor, "ESCORT ", 7))
3075   {
3076     if (!strncmp(product, "Galleria 600S ", 14)) /* this is an Astra 600S */
3077     {
3078      int add_len = get_inquiry_additional_length(dev->buffer[0]);
3079 
3080       DBG(DBG_warning,"setting up special options for %s\n", product);
3081 
3082       if (add_len == 0x8f)
3083       {
3084         DBG(DBG_warning," - correcting wrong inquiry data\n");
3085 	umax_do_new_inquiry(dev, 0x9b);		  /* get inquiry with correct length */
3086         set_inquiry_length(dev->buffer[0], 0x9e); /* correct inquiry len */
3087 					      /* correct color-ordering from pixel to line_with_ccd_distance */
3088         set_inquiry_color_order(dev->buffer[0], IN_color_ordering_line_w_ccd);
3089 	set_inquiry_fb_uta_line_arrangement_mode(dev->buffer[0], 32);
3090 	set_inquiry_CCD_line_distance(dev->buffer[0], 8);
3091         /* we should reset ADF-bit here too */
3092 
3093         if (dev->invert_shading_data == -1) /* nothing defined in umax.conf */
3094         {
3095           DBG(DBG_warning," - activating inversion of shading data\n");
3096           dev->invert_shading_data = 1;
3097         }
3098       }
3099     }
3100   }
3101   else if (!strncmp(vendor, "TriGem ", 7))
3102   {
3103     if (!strncmp(product, "PowerScanII ", 12)) /* is a Supervista S-12 */
3104     {
3105       DBG(DBG_warning,"setting up special options for %s\n", product);
3106 
3107       DBG(DBG_warning," - setting maximum calibration data lines to 66\n");
3108       set_inquiry_max_calibration_data_lines(dev->buffer[0], 66);
3109 
3110       if (dev->calibration_width_offset == -99999) /* no calibration-width-offset defined in umax.conf */
3111       {
3112         dev->calibration_width_offset = -1;
3113         DBG(DBG_warning," - adding calibration width offset of %d pixels\n", dev->calibration_width_offset);
3114       }
3115 
3116       if (dev->calibration_area == -1) /* no calibration area defined in umax.conf */
3117       {
3118         DBG(DBG_warning," - calibration by driver is done for each CCD pixel\n");
3119         dev->calibration_area = UMAX_CALIBRATION_AREA_CCD;
3120       }
3121     }
3122   }
3123 }
3124 
3125 
3126 /* ------------------------------------------------------------ UMAX IDENTIFY SCANNER ---------------------- */
3127 
3128 
umax_identify_scanner(Umax_Device *dev)3129 static int umax_identify_scanner(Umax_Device *dev)
3130 {
3131  char vendor[10];
3132  char product[0x12];
3133  char version[6];
3134  char *pp;
3135 
3136   DBG(DBG_proc,"identify_scanner\n");
3137   umax_do_inquiry(dev);									      /* get inquiry */
3138   if (get_inquiry_periph_devtype(dev->buffer[0]) != IN_periph_devtype_scanner) { return 1; }      /* no scanner */
3139 
3140   get_inquiry_vendor( (char *)dev->buffer[0], vendor);  vendor[8]   = ' '; vendor[9]   = '\0';
3141   get_inquiry_product((char *)dev->buffer[0], product); product[16] = ' '; product[17] = '\0';
3142   get_inquiry_version((char *)dev->buffer[0], version); version[4]  = ' '; version[5]  = '\0';
3143 
3144   pp = &vendor[8];
3145   while (*(pp-1) == ' ')
3146   {
3147     *pp-- = '\0';
3148   }
3149 
3150   pp = &product[0x10];
3151   while (*(pp-1) == ' ')
3152   {
3153     *pp-- = '\0';
3154   }
3155 
3156   pp = &version[4];
3157   while (*pp == ' ')
3158   {
3159     *pp-- = '\0';
3160   }
3161 
3162   DBG(DBG_info, "Found %s scanner %sversion %s on device %s\n", vendor, product, version, dev->devicename);
3163 
3164 					      /* look for scanners that do not give all inquiry-information */
3165 							   /* and if possible use driver-known inquiry-data  */
3166 
3167   if (get_inquiry_additional_length(dev->buffer[0])>=0x8f)
3168   {
3169     int i = 0;
3170     while (strncmp("END_OF_LIST", scanner_str[2*i], 11) != 0)	     /* Now identify full supported scanners */
3171     {
3172       if (!strncmp(vendor, scanner_str[2*i], strlen(scanner_str[2*i])) )
3173       {
3174         if (!strncmp(product, scanner_str[2*i+1], strlen(scanner_str[2*i+1])) )
3175         {
3176 	  umax_correct_inquiry(dev, vendor, product, version);
3177           return 0;
3178         }
3179       }
3180       i++;
3181     }
3182 
3183     if (strncmp(vendor, "UMAX ", 5)) { return 1; }				      /* not UMAX then abort */
3184 
3185     DBG(DBG_error0, "WARNING: %s scanner %s version %s on device %s\n"
3186      "is currently an unrecognized device for this backend version.\n"
3187      "Please make sure you use the most recent version of the umax backend.\n"
3188      "You can download new umax-backend versions from:\n"
3189      "http://www.rauch-domain.de/sane-umax\n",
3190      vendor, product, version, dev->devicename);
3191 
3192     DBG(DBG_error0,
3193      "Inquiry seems to be ok.\n"
3194      "******************************************************************\n"
3195      "***             !!!! CONTINUE AT YOUR OWN RISK !!!!            ***\n"
3196      "******************************************************************\n"
3197      "If you already use the most recent umax-backend version\n"
3198      "then please contact me: Oliver.Rauch@rauch-domain.de\n");
3199 
3200     return 0;
3201   }
3202   else									        /* inquiry-data not complete */
3203   if (!strncmp(vendor, "UMAX ", 5)) /* test UMAX-scanners with short inquiry */
3204   {
3205    inquiry_blk inq_data;
3206    int  i;
3207 
3208     for(i=0; i < known_inquiry; i++)
3209     {
3210       inq_data = *inquiry_table[i];
3211       if (!strncmp(product, inq_data.scanner, strlen(inq_data.scanner)))
3212       {
3213 	DBG(DBG_warning, "inquiry-block-length: %d\n", get_inquiry_additional_length(dev->buffer[0])+5);
3214 	DBG(DBG_warning, "using driver-internal inquiry-data for this scanner!\n");
3215 
3216 						      /* copy driver-defined inquiry-data into inquiry-block */
3217         memcpy(dev->buffer[0]+0x24, inq_data.inquiry, inq_data.inquiry_len-0x24);
3218 
3219         /* correct variables */
3220         set_inquiry_sc_uta(dev->buffer[0], get_inquiry_transavail(dev->buffer[0]));	/* transparency available ? */
3221         set_inquiry_sc_adf(dev->buffer[0], get_inquiry_scanmode(dev->buffer[0]));	/* automatic document feeder available ? */
3222 
3223         set_inquiry_length(dev->buffer[0], inq_data.inquiry_len);
3224         umax_correct_inquiry(dev, vendor, product, version);
3225 
3226         return 0;										       /* ok */
3227       }
3228     }
3229     DBG(DBG_error0, "ERROR: %s scanner %s version %s on device %s\n"
3230          "is currently an unrecognized device, and inquiry is too short,\n"
3231          "so we are not able to continue!\n"
3232          "Please make sure you use the most recent version of the umax backend.\n"
3233          "You can download new umax-backend versions from:\n"
3234          "http://www.rauch-domain.de/sane-umax\n"
3235          "You already use the most recent umax-backend version:\n"
3236          "Please contact me: Oliver.Rauch@rauch-domain.de\n",
3237          vendor, product, version, dev->devicename);
3238   }
3239 
3240  return 1;				    /* NO SUPPORTED SCANNER: short inquiry-block and unknown scanner */
3241 }
3242 
3243 
3244 /* ------------------------------------------------------------ UMAX TRIM BUFSIZE -------------------------- */
3245 
3246 
umax_trim_rowbufsize(Umax_Device *dev)3247 static void umax_trim_rowbufsize(Umax_Device *dev)
3248 {
3249  unsigned int lines=0;
3250 
3251   if (dev->row_bufsize > dev->row_len)
3252   {
3253     lines = dev->row_bufsize / dev->row_len;
3254 
3255     if (lines > dev->lines_max) /* reduce number of lines to scan if set up in config file */
3256     {
3257       lines = dev->lines_max;
3258     }
3259 
3260     dev->row_bufsize = lines * dev->row_len;
3261   }
3262 
3263   DBG(DBG_proc,"trim_rowbufsize: row_bufsize = %d bytes = %d lines\n", dev->row_bufsize, lines);
3264 }
3265 
3266 
3267 /* ------------------------------------------------------------ UMAX CALCULATE EXPOSURE TIME --------------- */
3268 
3269 
umax_calculate_exposure_time(Umax_Device *dev, int def, int *value)3270 static void umax_calculate_exposure_time(Umax_Device *dev, int def, int *value)
3271 {
3272  int level;
3273 
3274   DBG(DBG_proc,"calculate_exposure_time\n");
3275   if ( (*value))
3276   {
3277     if ( (*value) == -1 ) { (*value) = def; }
3278     else
3279     {
3280       level = (*value) / dev->inquiry_exposure_time_step_unit;
3281       (*value) = inrange(dev->use_exposure_time_min, level, dev->inquiry_exposure_time_max);
3282     }
3283   }
3284 }
3285 
3286 
3287 /* ------------------------------------------------------------ UMAX CHECK VALUES -------------------------- */
3288 
3289 
umax_check_values(Umax_Device *dev)3290 static int umax_check_values(Umax_Device *dev)
3291 {
3292  double inquiry_x_orig;
3293  double inquiry_y_orig;
3294  double inquiry_width;
3295  double inquiry_length;
3296  unsigned int maxwidth;
3297  unsigned int maxlength;
3298 
3299   DBG(DBG_proc,"check_values\n");
3300 
3301   /* ------------------------------- flatbed ------------------------------- */
3302 
3303   dev->module = WD_module_flatbed;					  /* reset scanmode to flatbed first */
3304 
3305   /* --------------------------------- uta --------------------------------- */
3306 
3307   if (dev->uta != 0)
3308   {
3309     dev->module = WD_module_transparency;
3310     if ( (dev->inquiry_uta == 0) || (dev->inquiry_transavail == 0) )
3311     {
3312       DBG(DBG_error, "ERROR: transparency mode not supported by scanner\n");
3313      return(1);
3314     }
3315   }
3316 
3317   /* --------------------------------- adf --------------------------------- */
3318 
3319   if (dev->adf != 0)
3320   {
3321     if (dev->inquiry_adf == 0)
3322     {
3323       DBG(DBG_error,"ERROR: adf mode not supported by scanner\n");
3324      return(1);
3325     }
3326   }
3327 
3328   /* --------------------------------- dor --------------------------------- */
3329 
3330   if (dev->dor != 0)
3331   {
3332     if (dev->inquiry_dor == 0)
3333     {
3334       DBG(DBG_error, "ERROR: double optical resolution not supported by scanner\n");
3335      return(1);
3336     }
3337   }
3338 
3339   /* ------------------------------- resolution ------------------------ */
3340 
3341   if (dev->dor == 0) /* standard (FB) */
3342   {
3343     dev->relevant_optical_res = dev->inquiry_optical_res;
3344     dev->relevant_max_x_res   = dev->inquiry_x_res;
3345     dev->relevant_max_y_res   = dev->inquiry_y_res;
3346   }
3347   else /* DOR mode */
3348   {
3349     dev->relevant_optical_res = dev->inquiry_dor_optical_res;
3350     dev->relevant_max_x_res   = dev->inquiry_dor_x_res;
3351     dev->relevant_max_y_res   = dev->inquiry_dor_y_res;
3352   }
3353 
3354   if (dev->x_resolution <= 0)
3355   {
3356     DBG(DBG_error,"ERROR: no x-resolution given\n");
3357     return(1);
3358   }
3359 
3360   if (dev->x_resolution > dev->relevant_max_x_res)
3361   {
3362     dev->x_resolution = dev->relevant_max_x_res;
3363   }
3364 
3365   if (dev->x_resolution > dev->relevant_optical_res)
3366   {
3367     dev->scale_x = 2;
3368   }
3369   else
3370   {
3371     dev->scale_x = 1;
3372   }
3373 
3374   if (dev->y_resolution <= 0)
3375   {
3376     DBG(DBG_error,"ERROR: no y-resolution given\n");
3377     return(1);
3378   }
3379 
3380   if (dev->y_resolution > dev->relevant_max_y_res)
3381   {
3382     dev->y_resolution = dev->relevant_max_y_res;
3383   }
3384 
3385   if (dev->y_resolution > dev->relevant_optical_res)
3386   {
3387     dev->scale_y = 2;
3388   }
3389   else if (dev->y_resolution > dev->relevant_optical_res/2)
3390   {
3391     dev->scale_y = 1;
3392   }
3393   else
3394   {
3395     /* astra 600S and 610S need this in umax_forget_line */
3396     dev->scale_y = 0.5;
3397   }
3398 
3399 
3400   /* ------------------------------- scanarea ------------------------ */
3401 
3402   if (dev->module == WD_module_flatbed)							     /* flatbed mode */
3403   {
3404     inquiry_x_orig = 0;								   /* flatbed origin */
3405     inquiry_y_orig = 0;
3406     inquiry_width  = dev->inquiry_fb_width;						    /* flatbed width */
3407     inquiry_length = dev->inquiry_fb_length;
3408   }
3409   else										        /* transparency mode */
3410   {
3411     inquiry_x_orig = dev->inquiry_uta_x_off;						       /* uta origin */
3412     inquiry_y_orig = dev->inquiry_uta_y_off;
3413     inquiry_width  = dev->inquiry_uta_x_off + dev->inquiry_uta_width;				/* uta width */
3414     inquiry_length = dev->inquiry_uta_y_off + dev->inquiry_uta_length;
3415   }
3416 
3417   if (dev->dor != 0)
3418   {
3419     inquiry_x_orig = dev->inquiry_dor_x_off;						       /* dor origin */
3420     inquiry_y_orig = dev->inquiry_dor_y_off;
3421     inquiry_width  = dev->inquiry_dor_x_off + dev->inquiry_dor_width;				/* dor width */
3422     inquiry_length = dev->inquiry_dor_y_off + dev->inquiry_dor_length;
3423   }
3424 
3425 							     /* limit the size to what the scanner can scan. */
3426 					   /* this is particularly important because the scanners don't have */
3427 				  /* built-in checks and will happily grind their gears if this is exceeded. */
3428 
3429 
3430   maxwidth = inquiry_width  * dev->x_coordinate_base - dev->upper_left_x - 1;
3431 
3432   if ( (dev->scanwidth <= 0) || (dev->scanwidth > maxwidth) )
3433   {
3434     dev->scanwidth = maxwidth;
3435   }
3436 
3437   if (dev->upper_left_x < inquiry_x_orig)
3438   {
3439     dev->upper_left_x = inquiry_x_orig;
3440   }
3441 
3442 
3443   maxlength = inquiry_length * dev->y_coordinate_base - dev->upper_left_y - 1;
3444 
3445   if ( (dev->scanlength <= 0) || (dev->scanlength > maxlength) )
3446   {
3447     dev->scanlength = maxlength;
3448   }
3449 
3450   if (dev->upper_left_y < inquiry_y_orig)
3451   {
3452     dev->upper_left_y = inquiry_y_orig;
3453   }
3454 
3455 
3456   /* Now calculate width and length in pixels */
3457   dev->width_in_pixels  = umax_calculate_pixels(dev->scanwidth,  dev->x_resolution,
3458                                                 dev->relevant_optical_res * dev->scale_x, dev->x_coordinate_base);
3459 
3460   dev->length_in_pixels = umax_calculate_pixels(dev->scanlength, dev->y_resolution,
3461                                                 dev->relevant_optical_res * dev->scale_y, dev->y_coordinate_base);
3462 
3463   if ((dev->scanwidth <= 0) || (dev->scanlength <= 0))
3464   {
3465     DBG(DBG_error,"ERROR: scanwidth or scanlength not given\n");
3466     return(1);
3467   }
3468 
3469   if (dev->bits_per_pixel_code == 1)
3470   {
3471     dev->bytes_per_color = 1;
3472   }
3473   else
3474   {
3475     dev->bytes_per_color = 2;
3476   }
3477 
3478   switch(dev->colormode)
3479   {
3480    case LINEART:
3481      dev->width_in_pixels -= dev->width_in_pixels % 8;
3482      dev->row_len = (dev->width_in_pixels / 8);
3483     break;
3484 
3485    case HALFTONE:
3486      dev->width_in_pixels -= dev->width_in_pixels % 8;
3487      dev->row_len = (dev->width_in_pixels / 8);
3488     break;
3489 
3490    case GRAYSCALE:
3491      dev->row_len = dev->width_in_pixels * dev->bytes_per_color;
3492     break;
3493 
3494    case RGB_LINEART:
3495    case RGB_HALFTONE:
3496      if (dev->three_pass)
3497      {
3498        dev->row_len = dev->width_in_pixels / 8 ;
3499      }
3500      else
3501      {
3502        dev->row_len = (dev->width_in_pixels / 8 ) * 3;
3503      }
3504     break;
3505 
3506    case RGB:
3507      if (dev->three_pass)				     /* three (24bpp) or six (30bpp) bytes per pixel */
3508      {
3509        dev->row_len = dev->width_in_pixels * dev->bytes_per_color;
3510      }
3511      else
3512      {
3513        dev->row_len = dev->width_in_pixels * 3 * dev->bytes_per_color;
3514      }
3515     break;
3516   }
3517 
3518 
3519   /* ------------------------------- wdb length ------------------------ */
3520 
3521   if (dev->wdb_len <= 0)
3522   {
3523     dev->wdb_len = dev->inquiry_wdb_len;
3524     if (dev->wdb_len <= 0)
3525     {
3526       DBG(DBG_error,"ERROR: wdb-length not given\n");
3527       return(1);
3528     }
3529   }
3530 
3531   if (dev->wdb_len > used_WDB_size)
3532   {
3533     DBG(DBG_warning,"WARNING:window descriptor block too long, will be shortned!\n");
3534     dev->wdb_len = used_WDB_size;
3535   }
3536 
3537   /* ----------------------------- cbhs-range ----------------------------- */
3538 
3539   dev->threshold   = umax_cbhs_correct(dev->inquiry_threshold_min,  dev->threshold , dev->inquiry_threshold_max);
3540   dev->contrast    = umax_cbhs_correct(dev->inquiry_contrast_min,   dev->contrast  , dev->inquiry_contrast_max);
3541   dev->brightness  = umax_cbhs_correct(dev->inquiry_brightness_min, dev->brightness, dev->inquiry_brightness_max);
3542 
3543   dev->highlight_r = umax_cbhs_correct(dev->inquiry_highlight_min, dev->highlight_r, dev->inquiry_highlight_max);
3544   dev->highlight_g = umax_cbhs_correct(dev->inquiry_highlight_min, dev->highlight_g, dev->inquiry_highlight_max);
3545   dev->highlight_b = umax_cbhs_correct(dev->inquiry_highlight_min, dev->highlight_b, dev->inquiry_highlight_max);
3546 
3547   dev->shadow_r    = umax_cbhs_correct(dev->inquiry_shadow_min, dev->shadow_r, dev->inquiry_shadow_max-1);
3548   dev->shadow_g    = umax_cbhs_correct(dev->inquiry_shadow_min, dev->shadow_g, dev->inquiry_shadow_max-1);
3549   dev->shadow_b    = umax_cbhs_correct(dev->inquiry_shadow_min, dev->shadow_b, dev->inquiry_shadow_max-1);
3550 
3551   if (dev->shadow_r >= dev->highlight_r)
3552   {
3553     dev->shadow_r = dev->highlight_r-1;
3554   }
3555   if (dev->shadow_g >= dev->highlight_g)
3556   {
3557     dev->shadow_g = dev->highlight_g-1;
3558   }
3559   if (dev->shadow_b >= dev->highlight_b)
3560   {
3561     dev->shadow_b = dev->highlight_b-1;
3562   }
3563 
3564   /* ----------------------- quality calibration and preview -------------- */
3565 
3566   if (dev->inquiry_preview == 0)
3567   {
3568     if (dev->preview)
3569     {
3570       DBG(DBG_warning, "WARNING: fast preview function not supported by scanner\n");
3571       dev->preview = 0;
3572     }
3573   }
3574 
3575   /* always set calibration lines because we also need this value if the scanner
3576      requeires calibration by driver */
3577   dev->calib_lines = dev->inquiry_max_calib_lines;
3578 
3579   if (dev->force_quality_calibration)
3580   {
3581     dev->quality = 1; /* always use quality calibration */
3582   }
3583   else if (dev->inquiry_quality_ctrl == 0)
3584   {
3585     if (dev->quality)
3586     {
3587       DBG(DBG_warning, "WARNING: quality calibration not supported by scanner\n");
3588       dev->quality = 0;
3589     }
3590   }
3591   else
3592   {
3593     if (dev->preview != 0)
3594     {
3595       DBG(DBG_info, "quality calibration disabled in preview mode\n");
3596       dev->quality = 0; /* do not use quality calibration in preview mode */
3597     }
3598   }
3599 
3600   /* --------------------------- lamp intensity control ------------------- */
3601 
3602   if (dev->inquiry_lamp_ctrl == 0)
3603   {
3604     if (dev->c_density || dev->s_density)
3605     {
3606       DBG(DBG_warning, "WARNING: scanner doesn't support lamp intensity control\n");
3607     }
3608     dev->c_density = dev->s_density = 0;
3609   }
3610 
3611 
3612   /* --------------------------- reverse (negative) ----------------------- */
3613 
3614   if (dev->reverse != 0)
3615   {
3616     if ( (dev->colormode == LINEART)     || (dev->colormode == HALFTONE) ||
3617          (dev->colormode == RGB_LINEART) || (dev->colormode == RGB_HALFTONE) )
3618     {
3619       if (dev->inquiry_reverse == 0)
3620       {
3621          DBG(DBG_error, "ERROR: reverse for bi-level-image not supported\n");
3622          return(1);
3623       }
3624     }
3625     else
3626     { dev->reverse = 0; }
3627   }
3628 
3629   if (dev->reverse_multi != 0)
3630   {
3631     if ((dev->colormode == RGB) || (dev->colormode == GRAYSCALE) )
3632     {
3633       if (dev->inquiry_reverse_multi == 0)
3634       {
3635          DBG(DBG_error, "ERROR: reverse for multi-level-image not supported\n");
3636          return(1);
3637       }
3638     }
3639     else
3640     {
3641       dev->reverse_multi = 0;
3642     }
3643   }
3644 
3645   /* ----------------------------- analog gamma ---------------------------- */
3646 
3647   if (dev->inquiry_analog_gamma == 0)
3648   {
3649     if (dev->analog_gamma_r + dev->analog_gamma_g + dev->analog_gamma_b != 0)
3650     {
3651       DBG(DBG_warning,"WARNING: analog gamma correction not supported by scanner!\n");
3652     }
3653     dev->analog_gamma_r = dev->analog_gamma_g = dev->analog_gamma_b = 0;
3654   }
3655 
3656   /* ---------------------------- digital gamma ---------------------------- */
3657 
3658   if ( (dev->digital_gamma_r == 0) || (dev->digital_gamma_g == 0) ||
3659        (dev->digital_gamma_b == 0) )
3660   {
3661     if (dev->inquiry_gamma_dwload == 0)
3662     {
3663       DBG(DBG_warning, "WARNING: gamma download not available\n");
3664       dev->digital_gamma_r = dev->digital_gamma_g = dev->digital_gamma_b = 15;
3665     }
3666   }
3667 
3668   /* ---------------------------- speed and smear  ------------------------- */
3669 
3670   if (dev->slow == 1)
3671   {
3672     dev->WD_speed = WD_speed_slow;
3673   }
3674   else
3675   {
3676     dev->WD_speed = WD_speed_fast;
3677   }
3678 
3679   if (dev->smear == 1)
3680   {
3681     dev->WD_speed += WD_speed_smear;
3682   }
3683 
3684   /* ---------------------- test bits per pixel  --------------------------- */
3685 
3686   if ( ( (dev->inquiry_GIB | 1) & dev->gamma_input_bits_code) == 0 )
3687   {
3688     DBG(DBG_warning,"WARNING: selected gamma input bits not supported, gamma ignored\n");
3689     dev->gamma_input_bits_code = 1;
3690     dev->digital_gamma_r = dev->digital_gamma_g = dev->digital_gamma_b = 15;
3691   }
3692 
3693   if ( ( (dev->inquiry_GOB | 1) & dev->bits_per_pixel_code) == 0 )
3694   {
3695     DBG(DBG_error,"ERROR: selected bits per pixel not supported\n");
3696     return(1);
3697   }
3698 
3699   /* ----------------------- scan mode dependencies ------------------------ */
3700 
3701   switch(dev->colormode)
3702   {
3703     case LINEART:							       /* ------------ LINEART ------------- */
3704     case RGB_LINEART:						       /* ---------- RGB_LINEART ----------- */
3705       dev->use_exposure_time_min = dev->inquiry_exposure_time_l_min;
3706 
3707       if (dev->module == WD_module_flatbed)
3708       {
3709         dev->use_exposure_time_def_r = dev->inquiry_exposure_time_l_fb_def;
3710       }
3711       else
3712       {
3713         dev->use_exposure_time_def_r = dev->inquiry_exposure_time_l_uta_def;
3714       }
3715 
3716       if (dev->inquiry_lineart == 0)
3717       {
3718         DBG(DBG_error,"ERROR: lineart mode not supported by scanner\n");
3719        return(1);
3720       }
3721      break;
3722 
3723     case HALFTONE:							 /* ----------- HALFTONE------------ */
3724     case RGB_HALFTONE:							 /* --------- RGB_HALFTONE---------- */
3725       dev->use_exposure_time_min = dev->inquiry_exposure_time_h_min;
3726       if (dev->module == WD_module_flatbed)
3727       {
3728         dev->use_exposure_time_def_r = dev->inquiry_exposure_time_h_fb_def;
3729       }
3730       else
3731       {
3732         dev->use_exposure_time_def_r = dev->inquiry_exposure_time_h_uta_def;
3733       }
3734 
3735       if (dev->inquiry_halftone == 0)
3736       {
3737         DBG(DBG_error,"ERROR: halftone mode not supported by scanner\n");
3738         return(1);
3739       }
3740      break;
3741 
3742     case GRAYSCALE:						       /* ---------- GRAYSCALE ------------- */
3743       dev->use_exposure_time_min = dev->inquiry_exposure_time_g_min;
3744 
3745       if (dev->module == WD_module_flatbed)
3746       {
3747         dev->use_exposure_time_def_r = dev->inquiry_exposure_time_g_fb_def;
3748       }
3749       else
3750       {
3751         dev->use_exposure_time_def_r = dev->inquiry_exposure_time_g_uta_def;
3752       }
3753 
3754       if (dev->inquiry_gray == 0)
3755       {
3756         DBG(DBG_error, "ERROR: grayscale mode not supported by scanner\n");
3757        return(1);
3758       }
3759      break;
3760 
3761     case RGB:							       /* ----------------- COLOR ---------- */
3762       dev->use_exposure_time_min = dev->inquiry_exposure_time_c_min;
3763       if (dev->module == WD_module_flatbed)
3764       {
3765         dev->use_exposure_time_def_r = dev->inquiry_exposure_time_c_fb_def_r;
3766         dev->use_exposure_time_def_g = dev->inquiry_exposure_time_c_fb_def_g;
3767         dev->use_exposure_time_def_b = dev->inquiry_exposure_time_c_fb_def_b;
3768       }
3769       else
3770       {
3771         dev->use_exposure_time_def_r = dev->inquiry_exposure_time_c_uta_def_r;
3772         dev->use_exposure_time_def_g = dev->inquiry_exposure_time_c_uta_def_g;
3773         dev->use_exposure_time_def_b = dev->inquiry_exposure_time_c_uta_def_b;
3774       }
3775 
3776       if (dev->inquiry_color == 0)
3777       {
3778         DBG(DBG_error,"ERROR: color mode not supported by scanner\n");
3779        return(1);
3780       }
3781 
3782       if (dev->inquiry_one_pass_color)
3783       {
3784         DBG(DBG_info,"using one pass scanning mode\n");
3785 
3786         if (dev->inquiry_color_order & IN_color_ordering_pixel)
3787         {
3788           DBG(DBG_info,"scanner uses color-pixel-ordering\n");
3789         }
3790         else if (dev->inquiry_color_order & IN_color_ordering_line_no_ccd)
3791         {
3792           dev->CCD_distance = 0;
3793           dev->do_color_ordering = 1;
3794           DBG(DBG_info,"scanner uses color-line-ordering without CCD-distance\n");
3795         }
3796         else if (dev->inquiry_color_order & IN_color_ordering_line_w_ccd)
3797         {
3798           dev->CCD_distance = dev->inquiry_CCD_line_distance;
3799           dev->do_color_ordering = 1;
3800           switch (dev->inquiry_fb_uta_color_arrangement)		     /* define color order for line ordering */
3801           {
3802             case 1:
3803               dev->CCD_color[0] = CCD_color_green;
3804 
3805               dev->CCD_color[1] = CCD_color_blue;
3806               dev->CCD_color[2] = CCD_color_green;
3807 
3808               dev->CCD_color[3] = CCD_color_blue;
3809               dev->CCD_color[4] = CCD_color_red;
3810               dev->CCD_color[5] = CCD_color_green;
3811 
3812               dev->CCD_color[6] = CCD_color_blue;
3813               dev->CCD_color[7] = CCD_color_red;
3814 
3815               dev->CCD_color[8] = CCD_color_red;
3816              break;
3817 
3818             case 2:
3819               dev->CCD_color[0] = CCD_color_blue;
3820 
3821               dev->CCD_color[1] = CCD_color_green;
3822               dev->CCD_color[2] = CCD_color_blue;
3823 
3824               dev->CCD_color[3] = CCD_color_green;
3825               dev->CCD_color[4] = CCD_color_red;
3826               dev->CCD_color[5] = CCD_color_blue;
3827 
3828               dev->CCD_color[6] = CCD_color_green;
3829               dev->CCD_color[7] = CCD_color_red;
3830 
3831               dev->CCD_color[8] = CCD_color_red;
3832              break;
3833 
3834             case 3:
3835               dev->CCD_color[0] = CCD_color_red;
3836 
3837               dev->CCD_color[1] = CCD_color_blue;
3838               dev->CCD_color[2] = CCD_color_red;
3839 
3840               dev->CCD_color[3] = CCD_color_blue;
3841               dev->CCD_color[4] = CCD_color_green;
3842               dev->CCD_color[5] = CCD_color_red;
3843 
3844               dev->CCD_color[6] = CCD_color_blue;
3845               dev->CCD_color[7] = CCD_color_green;
3846 
3847               dev->CCD_color[8] = CCD_color_green;
3848              break;
3849 
3850             case 4:										 /* may be wrong !!! */
3851               dev->CCD_color[0] = CCD_color_red;
3852 
3853               dev->CCD_color[1] = CCD_color_green;
3854               dev->CCD_color[2] = CCD_color_red;
3855 
3856               dev->CCD_color[3] = CCD_color_green;
3857               dev->CCD_color[4] = CCD_color_red;
3858               dev->CCD_color[5] = CCD_color_blue;
3859 
3860               dev->CCD_color[6] = CCD_color_green;
3861               dev->CCD_color[7] = CCD_color_blue;
3862 
3863               dev->CCD_color[8] = CCD_color_blue;
3864              break;
3865 
3866             case 32:						    /* not defined from UMAX, for Astra 600S */
3867               dev->CCD_color[0] = CCD_color_green;
3868 
3869               dev->CCD_color[1] = CCD_color_green;
3870               dev->CCD_color[2] = CCD_color_blue;
3871 
3872               dev->CCD_color[3] = CCD_color_green;
3873               dev->CCD_color[4] = CCD_color_red;
3874               dev->CCD_color[5] = CCD_color_blue;
3875 
3876               dev->CCD_color[6] = CCD_color_red;
3877               dev->CCD_color[7] = CCD_color_blue;
3878 
3879               dev->CCD_color[8] = CCD_color_red;
3880              break;
3881 
3882             case 33:						    /* not defined from UMAX, for Astra 610S */
3883               dev->CCD_color[0] = CCD_color_red;
3884 
3885               dev->CCD_color[1] = CCD_color_red;
3886               dev->CCD_color[2] = CCD_color_blue;
3887 
3888               dev->CCD_color[3] = CCD_color_red;
3889               dev->CCD_color[4] = CCD_color_green;
3890               dev->CCD_color[5] = CCD_color_blue;
3891 
3892               dev->CCD_color[6] = CCD_color_green;
3893               dev->CCD_color[7] = CCD_color_blue;
3894 
3895               dev->CCD_color[8] = CCD_color_green;
3896              break;
3897 
3898             default:
3899               dev->CCD_color[0] = CCD_color_green;
3900 
3901               dev->CCD_color[1] = CCD_color_blue;
3902               dev->CCD_color[2] = CCD_color_green;
3903 
3904               dev->CCD_color[3] = CCD_color_blue;
3905               dev->CCD_color[4] = CCD_color_red;
3906               dev->CCD_color[5] = CCD_color_green;
3907 
3908               dev->CCD_color[6] = CCD_color_blue;
3909               dev->CCD_color[7] = CCD_color_red;
3910 
3911               dev->CCD_color[8] = CCD_color_red;
3912           }
3913           DBG(DBG_info,"scanner uses color-line-ordering with CCD-distance of %d lines\n", dev->CCD_distance);
3914         }
3915         else
3916         {
3917           DBG(DBG_error,"ERROR: color-ordering-type not supported \n");
3918          return(1);
3919         }
3920       }
3921       else
3922       {
3923         DBG(DBG_info,"using three pass scanning mode\n");
3924         dev->three_pass=1;
3925       }
3926      break;
3927   } /* switch */
3928 
3929   /* ----------------------------- color ordering  ------------------------ */
3930 
3931   if (dev->do_color_ordering != 0)
3932   {
3933     if ( (dev->colormode != RGB) || (dev->three_pass != 0) )
3934     {
3935       dev->do_color_ordering = 0; /* color ordering not necessary */
3936     }
3937   }
3938 
3939  return(0);
3940 }
3941 
3942 
3943 /* ------------------------------------------------------------ UMAX GET INQUIRY VALUES -------------------- */
3944 
3945 
umax_get_inquiry_values(Umax_Device *dev)3946 static void umax_get_inquiry_values(Umax_Device *dev)
3947 {
3948  unsigned char * inquiry_block;
3949 
3950   DBG(DBG_proc,"get_inquiry_values\n");
3951 
3952   inquiry_block   = dev->buffer[0];
3953   dev->inquiry_len = get_inquiry_additional_length(dev->buffer[0])+5;
3954   dev->cbhs_range  = dev->inquiry_cbhs = get_inquiry_CBHS(inquiry_block);
3955 
3956   if (dev->cbhs_range > IN_CBHS_255)
3957   {
3958     dev->cbhs_range = IN_CBHS_255;
3959   }
3960 
3961   if (dev->cbhs_range == IN_CBHS_50)
3962   {
3963     dev->inquiry_contrast_min   = 103;	      /* minimum value for c */
3964     dev->inquiry_contrast_max   = 153;	      /* maximum value for c */
3965     dev->inquiry_brightness_min = 78;	      /* minimum value for b */
3966     dev->inquiry_brightness_max = 178;	      /* maximum value for b */
3967     dev->inquiry_threshold_min  = 78;	      /* minimum value for t */
3968     dev->inquiry_threshold_max  = 178;	      /* maximum value for t */
3969     dev->inquiry_highlight_min  = 1;	      /* minimum value for h */
3970     dev->inquiry_highlight_max  = 50;	      /* maximum value for h */
3971     dev->inquiry_shadow_min     = 0;	      /* minimum value for s */
3972     dev->inquiry_shadow_max     = 49;	      /* maximum value for s */
3973   }
3974 
3975   get_inquiry_vendor( (char *)inquiry_block, dev->vendor);  dev->vendor[8]  ='\0';
3976   get_inquiry_product((char *)inquiry_block, dev->product); dev->product[16]='\0';
3977   get_inquiry_version((char *)inquiry_block, dev->version); dev->version[4] ='\0';
3978 
3979   dev->inquiry_batch_scan       = get_inquiry_fw_batch_scan(inquiry_block);
3980   dev->inquiry_quality_ctrl     = get_inquiry_fw_quality(inquiry_block);
3981   dev->inquiry_preview          = get_inquiry_fw_fast_preview(inquiry_block);
3982   dev->inquiry_lamp_ctrl        = get_inquiry_fw_lamp_int_cont(inquiry_block);
3983   dev->inquiry_calibration      = get_inquiry_fw_calibration(inquiry_block);
3984   dev->inquiry_transavail       = get_inquiry_transavail(inquiry_block);
3985   dev->inquiry_adfmode          = get_inquiry_scanmode(inquiry_block);
3986 
3987   if (dev->inquiry_len<=0x8f)
3988   {
3989     DBG(DBG_warning, "WARNING: inquiry return block is unexpected short.\n");
3990   }
3991 
3992   dev->inquiry_uta              = get_inquiry_sc_uta(inquiry_block);
3993   dev->inquiry_adf              = get_inquiry_sc_adf(inquiry_block);
3994 
3995   dev->inquiry_one_pass_color   = get_inquiry_sc_one_pass_color(inquiry_block);
3996   dev->inquiry_three_pass_color = get_inquiry_sc_three_pass_color(inquiry_block);
3997   dev->inquiry_color            = get_inquiry_sc_color(inquiry_block);
3998   dev->inquiry_gray             = get_inquiry_sc_gray(inquiry_block);
3999   dev->inquiry_halftone         = get_inquiry_sc_halftone(inquiry_block);
4000   dev->inquiry_lineart          = get_inquiry_sc_lineart(inquiry_block);
4001 
4002   dev->inquiry_exposure_adj              = get_inquiry_fw_adjust_exposure_tf(inquiry_block);
4003   dev->inquiry_exposure_time_step_unit   = get_inquiry_exposure_time_step_unit(inquiry_block);
4004   dev->inquiry_exposure_time_max         = get_inquiry_exposure_time_max(inquiry_block);
4005 
4006              /* --- lineart --- */
4007   dev->inquiry_exposure_time_l_min       = get_inquiry_exposure_time_lhg_min(inquiry_block);
4008   dev->inquiry_exposure_time_l_fb_def    = get_inquiry_exposure_time_lh_def_fb(inquiry_block);
4009   dev->inquiry_exposure_time_l_uta_def   = get_inquiry_exposure_time_lh_def_uta(inquiry_block);
4010 
4011              /* --- halftone --- */
4012   dev->inquiry_exposure_time_h_min       = get_inquiry_exposure_time_lhg_min(inquiry_block);
4013   dev->inquiry_exposure_time_h_fb_def    = get_inquiry_exposure_time_lh_def_fb(inquiry_block);
4014   dev->inquiry_exposure_time_h_uta_def   = get_inquiry_exposure_time_lh_def_uta(inquiry_block);
4015 
4016              /* --- grayscale --- */
4017   dev->inquiry_exposure_time_g_min       = get_inquiry_exposure_time_lhg_min(inquiry_block);
4018   dev->inquiry_exposure_time_g_fb_def    = get_inquiry_exposure_time_gray_def_fb(inquiry_block);
4019   dev->inquiry_exposure_time_g_uta_def   = get_inquiry_exposure_time_gray_def_uta(inquiry_block);
4020 
4021              /* --- color --- */
4022   dev->inquiry_exposure_time_c_min       = get_inquiry_exposure_time_color_min(inquiry_block);
4023   dev->inquiry_exposure_time_c_fb_def_r  = get_inquiry_exposure_time_def_r_fb(inquiry_block);
4024   dev->inquiry_exposure_time_c_fb_def_g  = get_inquiry_exposure_time_def_g_fb(inquiry_block);
4025   dev->inquiry_exposure_time_c_fb_def_b  = get_inquiry_exposure_time_def_g_fb(inquiry_block);
4026   dev->inquiry_exposure_time_c_uta_def_r = get_inquiry_exposure_time_def_r_uta(inquiry_block);
4027   dev->inquiry_exposure_time_c_uta_def_g = get_inquiry_exposure_time_def_g_uta(inquiry_block);
4028   dev->inquiry_exposure_time_c_uta_def_b = get_inquiry_exposure_time_def_b_uta(inquiry_block);
4029 
4030 
4031   dev->inquiry_dor           = get_inquiry_sc_double_res(inquiry_block);
4032   dev->inquiry_reverse       = get_inquiry_sc_bi_image_reverse(inquiry_block);
4033   dev->inquiry_reverse_multi = get_inquiry_sc_multi_image_reverse(inquiry_block);
4034   dev->inquiry_shadow        = 1 - get_inquiry_sc_no_shadow(inquiry_block);
4035   dev->inquiry_highlight     = 1 - get_inquiry_sc_no_highlight(inquiry_block);
4036   dev->inquiry_analog_gamma  = get_inquiry_analog_gamma(inquiry_block);
4037   dev->inquiry_lineart_order = get_inquiry_lineart_order(inquiry_block);
4038 
4039   dev->inquiry_lens_cal_in_doc_pos  = get_inquiry_manual_focus(inquiry_block);
4040   dev->inquiry_manual_focus         = get_inquiry_manual_focus(inquiry_block);
4041   dev->inquiry_sel_uta_lens_cal_pos = get_inquiry_manual_focus(inquiry_block);
4042 
4043   dev->inquiry_gamma_dwload  = get_inquiry_gamma_download_available(inquiry_block);
4044 
4045   if (get_inquiry_gamma_type_2(inquiry_block) != 0)
4046   {
4047     dev->inquiry_gamma_DCF = 2;
4048   }
4049 
4050   dev->inquiry_GIB           = get_inquiry_gib(inquiry_block);
4051   dev->inquiry_GOB           = get_inquiry_gob(inquiry_block);
4052   dev->inquiry_color_order   = get_inquiry_color_order(inquiry_block);
4053   dev->inquiry_vidmem        = get_inquiry_max_vidmem(inquiry_block);
4054 
4055   /* optical resolution = [0x73] * 100 + [0x94] , 0x94 is not always defined */
4056   dev->inquiry_optical_res = 100 * get_inquiry_max_opt_res(inquiry_block);
4057   if (dev->inquiry_len > 0x94)
4058   {
4059     dev->inquiry_optical_res += get_inquiry_optical_resolution_residue(inquiry_block);
4060   }
4061 
4062   /* x resolution = [0x74] * 100 + [0x95] , 0x95 is not always defined */
4063   dev->inquiry_x_res = 100 * get_inquiry_max_x_res(inquiry_block);
4064   if (dev->inquiry_len > 0x95)
4065   {
4066     dev->inquiry_x_res+= get_inquiry_x_resolution_residue(inquiry_block);
4067   };
4068 
4069   /* y resolution = [0x75] * 100 + [0x96] , 0x96 is not always defined */
4070   dev->inquiry_y_res = 100 * get_inquiry_max_y_res(inquiry_block);
4071   if (dev->inquiry_len > 0x96)
4072   {
4073     dev->inquiry_y_res+= get_inquiry_y_resolution_residue(inquiry_block);
4074   }
4075 
4076 
4077   /* optical resolution = [0x83] * 100 + [0xa0] , 0xa0 is not always defined */
4078   dev->inquiry_dor_optical_res = 100 * get_inquiry_dor_max_opt_res(inquiry_block);
4079   if (dev->inquiry_len > 0xa0)
4080   {
4081     dev->inquiry_dor_optical_res += get_inquiry_dor_optical_resolution_residue(inquiry_block);
4082   }
4083 
4084   /* x resolution = [0x84] * 100 + [0xa1] , 0xa1 is not always defined */
4085   dev->inquiry_dor_x_res = 100 * get_inquiry_dor_max_x_res(inquiry_block);
4086   if (dev->inquiry_len > 0xa1)
4087   {
4088     dev->inquiry_dor_x_res+= get_inquiry_dor_x_resolution_residue(inquiry_block);
4089   }
4090 
4091   /* y resolution = [0x85] * 100 + [0xa2] , 0xa2 is not always defined */
4092   dev->inquiry_dor_y_res = 100 * get_inquiry_dor_max_y_res(inquiry_block);
4093   if (dev->inquiry_len > 0xa2)
4094   {
4095     dev->inquiry_dor_y_res+= get_inquiry_dor_y_resolution_residue(inquiry_block);
4096   }
4097 
4098   if (dev->inquiry_dor) /* DOR mode available ? */
4099   {
4100     /* if DOR resolutions are not defined, use double of standard resolution */
4101 
4102     if (dev->inquiry_dor_optical_res == 0)
4103     {
4104       dev->inquiry_dor_optical_res = dev->inquiry_optical_res * 2;
4105     }
4106 
4107     if (dev->inquiry_dor_x_res == 0)
4108     {
4109       dev->inquiry_dor_x_res = dev->inquiry_x_res * 2;
4110     }
4111 
4112     if (dev->inquiry_dor_y_res == 0)
4113     {
4114       dev->inquiry_dor_y_res = dev->inquiry_y_res * 2;
4115     }
4116   }
4117 
4118   dev->inquiry_fb_width   = (double)get_inquiry_fb_max_scan_width(inquiry_block)  * 0.01;
4119   dev->inquiry_fb_length  = (double)get_inquiry_fb_max_scan_length(inquiry_block) * 0.01;
4120 
4121   dev->inquiry_uta_width  = (double)get_inquiry_uta_max_scan_width(inquiry_block)  * 0.01;
4122   dev->inquiry_uta_length = (double)get_inquiry_uta_max_scan_length(inquiry_block) * 0.01;
4123   dev->inquiry_uta_x_off  = (double)get_inquiry_uta_x_original_point(inquiry_block) * 0.01;
4124   dev->inquiry_uta_y_off  = (double)get_inquiry_uta_y_original_point(inquiry_block) * 0.01;
4125 
4126   dev->inquiry_dor_width  = (double)get_inquiry_dor_max_scan_width(inquiry_block)  * 0.01;
4127   dev->inquiry_dor_length = (double)get_inquiry_dor_max_scan_length(inquiry_block) * 0.01;
4128   dev->inquiry_dor_x_off  = (double)get_inquiry_dor_x_original_point(inquiry_block) * 0.01;
4129   dev->inquiry_dor_y_off  = (double)get_inquiry_dor_y_original_point(inquiry_block) * 0.01;
4130 
4131   dev->inquiry_max_warmup_time          = get_inquiry_lamp_warmup_maximum_time(inquiry_block) * 2;
4132 
4133   dev->inquiry_wdb_len                  = get_inquiry_wdb_length(inquiry_block);
4134 
4135   /* it is not guaranteed that the following values are in the inquiry return block */
4136 
4137   /* 0x9a */
4138   if (dev->inquiry_len<=0x9a)
4139   {
4140     return;
4141   }
4142   dev->inquiry_max_calib_lines          = get_inquiry_max_calibration_data_lines(inquiry_block);
4143 
4144   /* 0x9b */
4145   if (dev->inquiry_len<=0x9b)
4146   {
4147     return;
4148   }
4149   dev->inquiry_fb_uta_color_arrangement = get_inquiry_fb_uta_line_arrangement_mode(inquiry_block);
4150 
4151   /* 0x9c */
4152   if (dev->inquiry_len<=0x9c)
4153   {
4154     return;
4155   }
4156   dev->inquiry_adf_color_arrangement    = get_inquiry_adf_line_arrangement_mode(inquiry_block);
4157 
4158   /* 0x9d */
4159   if (dev->inquiry_len<=0x9d)
4160   {
4161     return;
4162   }
4163   dev->inquiry_CCD_line_distance        = get_inquiry_CCD_line_distance(inquiry_block);
4164 
4165   return;
4166 }
4167 
4168 
4169 /* ------------------------------------------------------------ UMAX CALCULATE ANALOG GAMMA ---------------- */
4170 
4171 
umax_calculate_analog_gamma(double value)4172 static int umax_calculate_analog_gamma(double value)
4173 {
4174  int gamma;
4175 
4176   if (value < 1.0)
4177    { value=1.0; }
4178 
4179   if (value > 2.0)
4180    { value=2.0; }
4181 
4182   gamma=0;						       /* select gamma_value from analog_gamma_table */
4183   while (value>analog_gamma_table[gamma])
4184   {
4185     gamma++;
4186   }
4187 
4188   if (gamma)
4189   {
4190     if ((analog_gamma_table[gamma-1] + analog_gamma_table[gamma]) /2 > value)
4191     {
4192       gamma--;
4193     }
4194   }
4195 
4196  return(gamma);
4197 }
4198 
4199 /* ------------------------------------------------------------ UMAX OUTPUT IMAGE DATA  -------------------- */
4200 
umax_output_image_data(Umax_Device *dev, FILE *fp, unsigned int data_to_read, int bufnr)4201 static void umax_output_image_data(Umax_Device *dev, FILE *fp, unsigned int data_to_read, int bufnr)
4202 {
4203     if (dev->do_color_ordering == 0)							   /* pixel ordering */
4204     {
4205       if ((dev->inquiry_lineart_order) && (dev->colormode == LINEART)) /* lineart with LSB first */
4206       {
4207        unsigned int i, j;
4208        int new, old;
4209 
4210         for (i=0; i<data_to_read; i++)
4211         {
4212           old = dev->buffer[bufnr][i];
4213           new = 0;
4214           for (j=0; j<8; j++)  /* reverse bit order of 1 byte */
4215           {
4216             new = (new << 1) + (old & 1);
4217             old = old >> 1;
4218           }
4219           dev->buffer[bufnr][i]=new;
4220         }
4221       }
4222       fwrite(dev->buffer[bufnr], 1, data_to_read, fp);
4223     }
4224     else										    /* line ordering */
4225     {
4226      unsigned char *linesource = dev->buffer[bufnr];
4227      unsigned char *pixelsource;
4228      int bytes = 1;
4229      int lines;
4230      int i;
4231 
4232       if (dev->bits_per_pixel_code != 1)							  /* >24 bpp */
4233       {
4234         bytes = 2;
4235       }
4236 
4237       lines = data_to_read / (dev->width_in_pixels * bytes);
4238 
4239       for(i=0; i<lines; i++)
4240       {
4241         umax_order_line(dev, linesource);
4242         linesource += dev->width_in_pixels * bytes;
4243 
4244         pixelsource = umax_get_pixel_line(dev);
4245         if (pixelsource != NULL)
4246         {
4247           fwrite(pixelsource, bytes, dev->width_in_pixels * 3, fp);
4248         }
4249       }
4250     }
4251 }
4252 
4253 /* ------------------------------------------------------------ UMAX READER PROCESS ------------------------ */
4254 
4255 
umax_reader_process(Umax_Device *dev, FILE *fp, unsigned int image_size)4256 static int umax_reader_process(Umax_Device *dev, FILE *fp, unsigned int image_size)
4257 {
4258  int status;
4259  int bytes        = 1;
4260  int queue_filled = 0;
4261  unsigned int bufnr_queue  = 0;
4262  unsigned int bufnr_read   = 0;
4263  unsigned int data_left_to_read  = image_size;
4264  unsigned int data_left_to_queue = image_size;
4265  unsigned int data_to_read;
4266  unsigned int data_to_queue;
4267 
4268   dev->row_bufsize = dev->bufsize;
4269   umax_trim_rowbufsize(dev);								     /* trim bufsize */
4270 
4271   if (dev->bits_per_pixel_code != 1) /* >24 bpp */
4272   {
4273     bytes = 2;
4274   }
4275 
4276   DBG(DBG_read,"reading %u bytes in blocks of %u bytes\n", image_size, dev->row_bufsize);
4277 
4278   if (dev->pixelbuffer != NULL)								   /* buffer exists? */
4279   {
4280     free(dev->pixelbuffer);
4281     dev->pixelbuffer = NULL;
4282   }
4283 
4284   if (dev->do_color_ordering != 0)
4285   {
4286     DBG(DBG_info,"ordering from line-order to pixel-order\n");
4287 
4288     dev->pixelline_max = 3 *  dev->CCD_distance * dev->scale_y + 2;
4289 
4290     dev->pixelbuffer = malloc(dev->width_in_pixels * dev->pixelline_max * bytes * 3);
4291 
4292     if (dev->pixelbuffer == NULL) /* NO MEMORY */
4293     {
4294       return -1;
4295     }
4296   }
4297 
4298   WAIT_SCANNER;
4299 
4300   do
4301   {
4302     if (data_left_to_queue)
4303     {
4304       data_to_queue = (data_left_to_queue < dev->row_bufsize) ? data_left_to_queue : dev->row_bufsize;
4305 
4306       /* umax_get_data_buffer_status(dev); */
4307 
4308       status = umax_queue_read_image_data_req(dev, data_to_queue, bufnr_queue);
4309 
4310       if (status == 0) /* no error but nothing queued */
4311       {
4312         continue;
4313       }
4314 
4315       if (status == -1) /* error */
4316       {
4317         DBG(DBG_error,"ERROR: umax_reader_process: unable to queue read image data request!\n");
4318         free(dev->pixelbuffer);
4319         dev->pixelbuffer = NULL;
4320         return(-1);
4321       }
4322 
4323       data_left_to_queue -= data_to_queue;
4324       DBG(DBG_read, "umax_reader_process: read image data queued for buffer[%d] \n", bufnr_queue);
4325 
4326       bufnr_queue++;
4327       if (bufnr_queue >= dev->scsi_maxqueue)
4328       {
4329         bufnr_queue = 0;
4330         queue_filled = 1; /* ok, we can start to read the queued buffers - if not already started */
4331       }
4332 
4333       if (!data_left_to_queue)
4334       {
4335         queue_filled = 1; /* ok, we can start to read the queued buffer(s) - all read requests are send */
4336       }
4337     }
4338 
4339     if (queue_filled) /* queue filled, ok we can read data */
4340     {
4341       status = umax_wait_queued_image_data(dev, bufnr_read);
4342 
4343       if (status == -1)
4344       {
4345         DBG(DBG_error,"ERROR: umax_reader_process: unable to get image data from scanner!\n");
4346         free(dev->pixelbuffer);
4347         dev->pixelbuffer = NULL;
4348         return(-1);
4349       }
4350 
4351       data_to_read = dev->length_read[bufnr_read]; /* number of bytes in buffer */
4352       umax_output_image_data(dev, fp, data_to_read, bufnr_read);
4353 
4354       data_left_to_read -= data_to_read;
4355       DBG(DBG_read, "umax_reader_process: buffer of %d bytes read; %d bytes to go\n", data_to_read, data_left_to_read);
4356 
4357       /* if we did not get all requested data increase data_left_to_queue so that we get all needed data */
4358       if (dev->length_read[bufnr_read] != dev->length_queued[bufnr_read])
4359       {
4360         data_left_to_queue += dev->length_queued[bufnr_read] - dev->length_read[bufnr_read];
4361       }
4362 
4363       bufnr_read++;
4364       if (bufnr_read >= dev->scsi_maxqueue)
4365       {
4366         bufnr_read = 0;
4367       }
4368     }
4369   } while (data_left_to_read);
4370 
4371   free(dev->pixelbuffer);
4372   dev->pixelbuffer = NULL;
4373 
4374  return 0;
4375 }
4376 
4377 
4378 /* ------------------------------------------------------------ UMAX INITIALIZE VALUES --------------------- */
4379 
4380 
umax_initialize_values(Umax_Device *dev)4381 static void umax_initialize_values(Umax_Device *dev)	      /* called each time before setting scan-values */
4382 {										 /* Initialize dev structure */
4383   DBG(DBG_proc,"initialize_values\n");
4384 
4385   dev->three_pass            = 0;						  /* 1 if threepas_mode only */
4386   dev->row_len               = -1;
4387   dev->max_value             = 255;							    /* maximum value */
4388 
4389   dev->wdb_len               = 0;
4390   dev->width_in_pixels       = 0;						     /* scan width in pixels */
4391   dev->length_in_pixels      = 0;						    /* scan length in pixels */
4392   dev->scanwidth             = 0;			           /* width in inch at x_coordinate_base dpi */
4393   dev->scanlength            = 0;				  /* length in inch at y_coordinate_base dpi */
4394   dev->x_resolution          = 0;
4395   dev->y_resolution          = 0;
4396   dev->upper_left_x          = 0;							   /* at 1200pt/inch */
4397   dev->upper_left_y          = 0;							   /* at 1200pt/inch */
4398   dev->bytes_per_color       = 0;						     /* bytes for each color */
4399 
4400   dev->bits_per_pixel        = 8;						 /* number of bits per pixel */
4401   dev->bits_per_pixel_code   = 1;			    /* 1 =  8/24 bpp,  2 =  9/27 bpp,  4 = 10/30 bpp */
4402   dev->gamma_input_bits_code = 1;			    /* 8 = 12/36 bpp, 16 = 14/42 bpp, 32 = 16/48 bpp */
4403   dev->set_auto              = 0;								   /* 0 or 1 */
4404   dev->preview               = 0;							    /* 1 for preview */
4405   dev->quality               = 0;						      /* quality calibration */
4406   dev->warmup                = 0;							       /* warmup-bit */
4407   dev->fix_focus_position    = 0;						       /* fix focus position */
4408   dev->lens_cal_in_doc_pos   = 0;				    /* lens calibration in document position */
4409   dev->disable_pre_focus     = 0;							/* disable pre focus */
4410   dev->holder_focus_pos_0mm  = 0;				    /* 0.6mm <-> 0.0mm holder focus position */
4411   dev->manual_focus          = 0;					       /* automatic <-> manual focus */
4412   dev->colormode             = 0;				      /* LINEART, HALFTONE, GRAYSCALE or RGB */
4413   dev->adf                   = 0;						   /* 1 if adf shall be used */
4414   dev->uta                   = 0;						   /* 1 if uta shall be used */
4415   dev->module                = WD_module_flatbed;
4416   dev->cbhs_range            = WD_CBHS_255;
4417   dev->dor                   = 0;
4418   dev->halftone              = WD_halftone_8x8_1;
4419   dev->reverse               = 0;
4420   dev->reverse_multi         = 0;
4421   dev->calibration           = 0;
4422 
4423   dev->exposure_time_calibration_r = 0;						 /* use this for calibration */
4424   dev->exposure_time_calibration_g = 0;						 /* use this for calibration */
4425   dev->exposure_time_calibration_b = 0;						 /* use this for calibration */
4426   dev->exposure_time_scan_r        = 0;							/* use this for scan */
4427   dev->exposure_time_scan_g        = 0;							/* use this for scan */
4428   dev->exposure_time_scan_b        = 0;							/* use this for scan */
4429 
4430   dev->c_density           = WD_lamp_c_density_auto;				 /* calibration lamp density */
4431   dev->s_density           = WD_lamp_s_density_auto;				   /* next scan lamp density */
4432 
4433   dev->threshold           = 128;					       /* threshold for lineart mode */
4434   dev->brightness          = 128;					     /* brightness for halftone mode */
4435   dev->contrast            = 128;					       /* contrast for halftone mode */
4436   dev->highlight_r         = 255;						       /* highlight gray/red */
4437   dev->highlight_g         = 255;							  /* highlight green */
4438   dev->highlight_b         = 255;						  	   /* highlight blue */
4439   dev->shadow_r            = 0;							     	  /* shadow gray/red */
4440   dev->shadow_g            = 0;								     /* shadow green */
4441   dev->shadow_b            = 0;								      /* shadow blue */
4442 
4443   dev->digital_gamma_r     = WD_gamma_normal;
4444   dev->digital_gamma_g     = WD_gamma_normal;
4445   dev->digital_gamma_b     = WD_gamma_normal;
4446 
4447   dev->analog_gamma_r      = 0;					     /* analog gamma for red and gray to 1.0 */
4448   dev->analog_gamma_g      = 0;						    /* analog gamma for green to 1.0 */
4449   dev->analog_gamma_b      = 0;						     /* analog gamma for blue to 1.0 */
4450 
4451 
4452   dev->pixelline_ready[0]  = 0;					      /* reset all values for color ordering */
4453   dev->pixelline_ready[1]  = 0;
4454   dev->pixelline_ready[2]  = 0;
4455   dev->pixelline_next[0]   = 0;
4456   dev->pixelline_next[1]   = 0;
4457   dev->pixelline_next[2]   = 0;
4458   dev->pixelline_del[0]    = 1;
4459   dev->pixelline_del[1]    = 1;
4460   dev->pixelline_del[2]    = 1;
4461   dev->pixelline_optic[0]  = 1;
4462   dev->pixelline_optic[1]  = 1;
4463   dev->pixelline_optic[2]  = 1;
4464   dev->pixelline_max       = 0;
4465   dev->pixelline_opt_res   = 0;
4466   dev->pixelline_read      = 0;
4467   dev->pixelline_written   = 0;
4468   dev->CCD_distance        = 0;
4469 
4470   dev->calib_lines         = 0;							/* request calibration lines */
4471   dev->do_calibration      = 0;							 /* no calibration by driver */
4472   dev->do_color_ordering   = 0;						  /* no line- to pixel-mode ordering */
4473 
4474   dev->button0_pressed     = 0;						      /* reset button 0 pressed flag */
4475   dev->button1_pressed     = 0;						      /* reset button 1 pressed flag */
4476   dev->button2_pressed     = 0;						      /* reset button 2 pressed flag */
4477 }
4478 
4479 
4480 /* ------------------------------------------------------------ UMAX INIT ---------------------------------- */
4481 
4482 
umax_init(Umax_Device *dev)4483 static void umax_init(Umax_Device *dev)		     /* umax_init is called once while driver-initialization */
4484 {
4485   DBG(DBG_proc,"init\n");
4486 
4487   dev->devicename  = NULL;
4488   dev->pixelbuffer = NULL;
4489 
4490   /* config file or predefined settings */
4491   if (dev->connection_type == SANE_UMAX_SCSI)
4492   {
4493     dev->request_scsi_maxqueue  = umax_scsi_maxqueue;
4494   }
4495   else /* SANE_UMAX_USB, USB does not support command queueing */
4496   {
4497     DBG(DBG_info2, "setting request_scsi_maxqueue = 1 for USB connection\n");
4498     dev->request_scsi_maxqueue  = 1;
4499   }
4500 
4501   dev->request_preview_lines          = umax_preview_lines;
4502   dev->request_scan_lines             = umax_scan_lines;
4503   dev->handle_bad_sense_error         = umax_handle_bad_sense_error;
4504   dev->execute_request_sense          = umax_execute_request_sense;
4505   dev->scsi_buffer_size_min           = umax_scsi_buffer_size_min;
4506   dev->scsi_buffer_size_max           = umax_scsi_buffer_size_max;
4507   dev->force_preview_bit_rgb          = umax_force_preview_bit_rgb;
4508   dev->slow                           = umax_slow;
4509   dev->smear                          = umax_smear;
4510   dev->calibration_area               = umax_calibration_area;
4511   dev->calibration_width_offset       = umax_calibration_width_offset;
4512   dev->calibration_width_offset_batch = umax_calibration_width_offset_batch;
4513   dev->calibration_bytespp            = umax_calibration_bytespp;
4514   dev->exposure_time_rgb_bind         = umax_exposure_time_rgb_bind;
4515   dev->invert_shading_data            = umax_invert_shading_data;
4516   dev->lamp_control_available         = umax_lamp_control_available;
4517   dev->gamma_lsb_padded               = umax_gamma_lsb_padded;
4518 
4519   DBG(DBG_info, "request_scsi_maxqueue          = %d\n", dev->request_scsi_maxqueue);
4520   DBG(DBG_info, "request_preview_lines          = %d\n", dev->request_preview_lines);
4521   DBG(DBG_info, "request_scan_lines             = %d\n", dev->request_scan_lines);
4522   DBG(DBG_info, "handle_bad_sense_error         = %d\n", dev->handle_bad_sense_error);
4523   DBG(DBG_info, "execute_request_sense          = %d\n", dev->execute_request_sense);
4524   DBG(DBG_info, "scsi_buffer_size_min           = %d\n", dev->scsi_buffer_size_min);
4525   DBG(DBG_info, "scsi_buffer_size_max           = %d\n", dev->scsi_buffer_size_max);
4526   DBG(DBG_info, "force_preview_bit_rgb          = %d\n", dev->force_preview_bit_rgb);
4527   DBG(DBG_info, "slow                           = %d\n", dev->slow);
4528   DBG(DBG_info, "smear                          = %d\n", dev->smear);
4529   DBG(DBG_info, "calibration_area               = %d\n", dev->calibration_area);
4530   DBG(DBG_info, "calibration_width_offset       = %d\n", dev->calibration_width_offset);
4531   DBG(DBG_info, "calibration_width_offset_batch = %d\n", dev->calibration_width_offset_batch);
4532   DBG(DBG_info, "calibration_bytespp            = %d\n", dev->calibration_bytespp);
4533   DBG(DBG_info, "exposure_time_rgb_bind         = %d\n", dev->exposure_time_rgb_bind);
4534   DBG(DBG_info, "invert_shading_data            = %d\n", dev->invert_shading_data);
4535   DBG(DBG_info, "lamp_control_available         = %d\n", dev->lamp_control_available);
4536 
4537 
4538   dev->inquiry_len                       = 0;
4539   dev->inquiry_wdb_len                   = -1;
4540   dev->inquiry_optical_res               = -1;
4541   dev->inquiry_x_res                     = -1;
4542   dev->inquiry_y_res                     = -1;
4543   dev->inquiry_fb_width                  = -1;
4544   dev->inquiry_fb_length                 = -1;
4545   dev->inquiry_uta_width                 = -1;
4546   dev->inquiry_uta_length                = -1;
4547   dev->inquiry_dor_width                 = -1;
4548   dev->inquiry_dor_length                = -1;
4549   dev->inquiry_exposure_adj              = 0;
4550   dev->inquiry_exposure_time_step_unit   = -1;				  /* exposure time unit in micro sec */
4551   dev->inquiry_exposure_time_max         = -1;					    /* exposure time maximum */
4552   dev->inquiry_exposure_time_l_min       = -1;			       /*  exposure time minimum for lineart */
4553   dev->inquiry_exposure_time_l_fb_def    = -1;			/* exposure time default for lineart flatbed */
4554   dev->inquiry_exposure_time_l_uta_def   = -1;			    /* exposure time default for lineart uta */
4555   dev->inquiry_exposure_time_h_min       = -1;			      /*  exposure time minimum for halftone */
4556   dev->inquiry_exposure_time_h_fb_def    = -1;		       /* exposure time default for halftone flatbed */
4557   dev->inquiry_exposure_time_h_uta_def   = -1;			   /* exposure time default for halftone uta */
4558   dev->inquiry_exposure_time_g_min       = -1;			     /*  exposure time minimum for grayscale */
4559   dev->inquiry_exposure_time_g_fb_def    = -1;		      /* exposure time default for grayscale flatbed */
4560   dev->inquiry_exposure_time_g_uta_def   = -1;			  /* exposure time default for grayscale uta */
4561   dev->inquiry_exposure_time_c_min       = -1;				  /* exposure time minimum for color */
4562   dev->inquiry_exposure_time_c_fb_def_r  = -1;		      /* exposure time default for color flatbed red */
4563   dev->inquiry_exposure_time_c_fb_def_g  = -1;		    /* exposure time default for color flatbed green */
4564   dev->inquiry_exposure_time_c_fb_def_b  = -1;		     /* exposure time default for color flatbed blue */
4565   dev->inquiry_exposure_time_c_uta_def_r = -1;			  /* exposure time default for color uta red */
4566   dev->inquiry_exposure_time_c_uta_def_g = -1;			/* exposure time default for color uta green */
4567   dev->inquiry_exposure_time_c_uta_def_b = -1;			 /* exposure time default for color uta blue */
4568   dev->inquiry_max_warmup_time           = 0;					      /* maximum warmup time */
4569   dev->inquiry_cbhs                      = WD_CBHS_255;
4570   dev->inquiry_contrast_min              = 1;					      /* minimum value for c */
4571   dev->inquiry_contrast_max              = 255;					      /* maximum value for c */
4572   dev->inquiry_brightness_min            = 1;					      /* minimum value for b */
4573   dev->inquiry_brightness_max            = 255;					      /* maximum value for b */
4574   dev->inquiry_threshold_min             = 1;					      /* minimum value for t */
4575   dev->inquiry_threshold_max             = 255;					      /* maximum value for t */
4576   dev->inquiry_highlight_min             = 1;					      /* minimum value for h */
4577   dev->inquiry_highlight_max             = 255;					      /* maximum value for h */
4578   dev->inquiry_shadow_min                = 0;					      /* minimum value for s */
4579   dev->inquiry_shadow_max                = 254;					      /* maximum value for s */
4580   dev->inquiry_quality_ctrl              = 0;
4581   dev->inquiry_preview                   = 0;
4582   dev->inquiry_lamp_ctrl                 = 0;
4583   dev->inquiry_transavail                = 0;
4584   dev->inquiry_uta                       = 0;
4585   dev->inquiry_adfmode                   = 0;
4586   dev->inquiry_adf                       = 0;
4587   dev->inquiry_dor                       = 0;
4588   dev->inquiry_reverse                   = 0;
4589   dev->inquiry_reverse_multi             = 0;
4590   dev->inquiry_analog_gamma              = 0;
4591   dev->inquiry_gamma_dwload              = 0;
4592   dev->inquiry_one_pass_color            = 0;
4593   dev->inquiry_three_pass_color          = 0;
4594   dev->inquiry_color                     = 0;
4595   dev->inquiry_gray                      = 0;
4596   dev->inquiry_halftone                  = 0;
4597   dev->inquiry_lineart                   = 0;
4598   dev->inquiry_calibration               = 1;
4599   dev->inquiry_shadow                    = 0;
4600   dev->inquiry_highlight                 = 0;
4601   dev->inquiry_gamma_DCF                 = -1;
4602   dev->inquiry_max_calib_lines           = 66;	 /* most scanners use 66 lines, so lets define it as default */
4603 
4604   dev->common_xy_resolutions             = 0;
4605 
4606   dev->x_coordinate_base = 1200;						/* these are the 1200pt/inch */
4607   dev->y_coordinate_base = 1200;						/* these are the 1200pt/inch */
4608 
4609   dev->button0_pressed   = 0;						      /* reset button 0 pressed flag */
4610   dev->button1_pressed   = 0;						      /* reset button 1 pressed flag */
4611   dev->button2_pressed   = 0;						      /* reset button 2 pressed flag */
4612 
4613   dev->pause_for_color_calibration = 0;			/* pause between start_scan and do_calibration in ms */
4614   dev->pause_for_gray_calibration  = 0;			/* pause between start_scan and do_calibration in ms */
4615   dev->pause_after_calibration     = 0;			 /* pause between do_calibration and read data in ms */
4616   dev->pause_after_reposition      = -1;	    /* pause after repostion scanner in ms, -1 = do not wait */
4617   dev->pause_for_moving            = 0;			         /* pause for moving scanhead over full area */
4618 
4619   if (umax_test_little_endian() == SANE_TRUE)
4620   {
4621     dev->low_byte_first = 1;					        /* in 2 byte mode send lowbyte first */
4622     DBG(DBG_info, "backend runs on little endian machine\n");
4623   }
4624   else
4625   {
4626     dev->low_byte_first = 0;					       /* in 2 byte mode send highbyte first */
4627     DBG(DBG_info, "backend runs on big endian machine\n");
4628   }
4629 
4630 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
4631   DBG(DBG_info,"variable scsi buffer size (usage of sanei_scsi_open_extended)\n");
4632 #else
4633   DBG(DBG_info,"fixed scsi buffer size = %d bytes\n", sanei_scsi_max_request_size);
4634 #endif
4635 }
4636 
4637 
4638 /* ------------------------------------------------------------ MAX STRING SIZE ---------------------------- */
4639 
4640 
max_string_size(SANE_String_Const strings[])4641 static size_t max_string_size(SANE_String_Const strings[])
4642 {
4643  size_t size, max_size = 0;
4644  int i;
4645 
4646   for (i = 0; strings[i]; ++i)
4647   {
4648     size = strlen (strings[i]) + 1;
4649     if (size > max_size)
4650     {
4651       max_size = size;
4652     }
4653   }
4654 
4655  return max_size;
4656 }
4657 
4658 
4659 /* ------------------------------------------------------------ DO CANCEL ---------------------------------- */
4660 
4661 
do_cancel(Umax_Scanner *scanner)4662 static SANE_Status do_cancel(Umax_Scanner *scanner)
4663 {
4664   SANE_Pid pid;
4665   int status;
4666 
4667   DBG(DBG_sane_proc,"do_cancel\n");
4668 
4669   scanner->scanning = SANE_FALSE;
4670 
4671   if (sanei_thread_is_valid (scanner->reader_pid))
4672   {
4673     DBG(DBG_sane_info,"killing reader_process\n");
4674 
4675     sanei_thread_kill(scanner->reader_pid);
4676     pid = sanei_thread_waitpid(scanner->reader_pid, &status);
4677 
4678     if (!sanei_thread_is_valid (pid))
4679     {
4680       DBG(DBG_sane_info, "do_cancel: sanei_thread_waitpid failed, already terminated ? (%s)\n", strerror(errno));
4681     }
4682     else
4683     {
4684       DBG(DBG_sane_info, "do_cancel: reader_process terminated with status: %s\n", sane_strstatus(status));
4685     }
4686 
4687     sanei_thread_invalidate (scanner->reader_pid);
4688 
4689     if (scanner->device->pixelbuffer != NULL)					      /* pixelbuffer exists? */
4690     {
4691       free(scanner->device->pixelbuffer);						 /* free pixelbuffer */
4692       scanner->device->pixelbuffer = NULL;
4693     }
4694   }
4695 
4696   sanei_scsi_req_flush_all(); /* flush SCSI queue, when we do not do this then sanei_scsi crashes next time */
4697 
4698   if (scanner->device->sfd != -1) /* make sure we have a working filedescriptor */
4699   {
4700     umax_give_scanner(scanner->device); /* reposition and release scanner */
4701     DBG(DBG_sane_info,"closing scannerdevice filedescriptor\n");
4702     umax_scsi_close(scanner->device);
4703   }
4704 
4705   scanner->device->three_pass_color = 1; /* reset color in color scanning */
4706 
4707  return SANE_STATUS_CANCELLED;
4708 }
4709 
4710 
4711 /* ------------------------------------------------------------ ATTACH SCANNER ----------------------------- */
4712 
4713 
attach_scanner(const char *devicename, Umax_Device **devp, int connection_type)4714 static SANE_Status attach_scanner(const char *devicename, Umax_Device **devp, int connection_type)
4715 {
4716  Umax_Device *dev;
4717  int i;
4718 
4719   DBG(DBG_sane_proc,"attach_scanner: %s, connection_type %d\n", devicename, connection_type);
4720 
4721   for (dev = first_dev; dev; dev = dev->next) /* search is scanner already is listed in devicelist */
4722   {
4723     if (strcmp(dev->sane.name, devicename) == 0) /* scanner is already listed */
4724     {
4725       if (devp)
4726       {
4727         *devp = dev; /* return pointer to device */
4728       }
4729      return SANE_STATUS_GOOD;
4730     }
4731   }
4732 
4733   /* scanner has not been attached yet */
4734 
4735   dev = malloc( sizeof(*dev) );
4736   if (!dev)
4737   {
4738      return SANE_STATUS_NO_MEM;
4739   }
4740   memset(dev, '\0', sizeof(Umax_Device)); /* clear structure */
4741 
4742   /* If connection type is not known (==0) then try to open the device as an USB device. */
4743   /* If it fails, try the SCSI method. */
4744 
4745 #ifdef UMAX_ENABLE_USB
4746   dev->connection_type = connection_type; /* 0 = unknown, 1=scsi, 2=usb */
4747 
4748   if (dev->connection_type != SANE_UMAX_SCSI)
4749   {
4750     dev->bufsize = 16384; /* 16KB */
4751     DBG(DBG_info, "attach_scanner: opening usb device %s\n", devicename);
4752 
4753     if (sanei_umaxusb_open(devicename, &dev->sfd, sense_handler, dev) == SANE_STATUS_GOOD)
4754     {
4755       dev->connection_type = SANE_UMAX_USB;
4756     }
4757     else /* opening usb device failed */
4758     {
4759       if (dev->connection_type == SANE_UMAX_USB) /* we know it is not a scsi device: error */
4760       {
4761         DBG(DBG_error, "ERROR: attach_scanner: opening usb device %s failed\n", devicename);
4762         free(dev);
4763        return SANE_STATUS_INVAL;
4764       }
4765 
4766       DBG(DBG_info, "attach_scanner: failed to open %s as usb device\n", devicename);
4767     }
4768   }
4769 #else
4770   dev->connection_type = SANE_UMAX_SCSI;
4771 #endif
4772 
4773   if (dev->connection_type != SANE_UMAX_USB) /* not an USB device, then try as SCSI */
4774   {
4775 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
4776     dev->bufsize = 16384; /* 16KB */
4777     DBG(DBG_info, "attach_scanner: opening scsi device %s\n", devicename);
4778 
4779     if (sanei_scsi_open_extended(devicename, &dev->sfd, sense_handler, dev, (int *) &dev->bufsize) != 0)
4780     {
4781       DBG(DBG_error, "ERROR: attach_scanner: opening scsi device %s failed\n", devicename);
4782       free(dev);
4783      return SANE_STATUS_INVAL;
4784     }
4785 
4786     if (dev->bufsize < 4096) /* < 4KB */
4787     {
4788       DBG(DBG_error, "ERROR: attach_scanner: sanei_scsi_open_extended returned too small scsi buffer\n");
4789       umax_scsi_close(dev);
4790       free(dev);
4791      return SANE_STATUS_NO_MEM;
4792     }
4793 
4794     DBG(DBG_info, "attach_scanner: sanei_scsi_open_extended returned scsi buffer size = %d\n", dev->bufsize);
4795 #else
4796     dev->bufsize = sanei_scsi_max_request_size;
4797 
4798     if (sanei_scsi_open(devicename, dev, sense_handler, dev) != 0)
4799     {
4800       DBG(DBG_error, "ERROR: attach_scanner: opening scsi device %s failed\n", devicename);
4801       free(dev);
4802      return SANE_STATUS_INVAL;
4803     }
4804 #endif
4805     dev->connection_type = SANE_UMAX_SCSI; /* set connection type (may have been unknown == 0) */
4806   }
4807 
4808   DBG(DBG_info, "attach_scanner: allocating SCSI buffer[0]\n");
4809   dev->buffer[0] = malloc(dev->bufsize);								/* allocate buffer */
4810 
4811   for (i=1; i<SANE_UMAX_SCSI_MAXQUEUE; i++)
4812   {
4813     dev->buffer[i] = NULL;
4814   }
4815 
4816   if (!dev->buffer[0]) /* malloc failed */
4817   {
4818     DBG(DBG_error, "ERROR: attach scanner: could not allocate buffer[0]\n");
4819     umax_scsi_close(dev);
4820     free(dev);
4821     return SANE_STATUS_NO_MEM;
4822   }
4823 
4824   dev->scsi_maxqueue = 1; /* only one buffer outside the reader process */
4825 
4826   umax_init(dev);									 /* preset values in structure dev */
4827   umax_initialize_values(dev);										   /* reset values */
4828 
4829   dev->devicename = strdup(devicename);
4830 
4831   if (umax_identify_scanner(dev) != 0)
4832   {
4833     DBG(DBG_error, "ERROR: attach_scanner: scanner-identification failed\n");
4834     umax_scsi_close(dev);
4835     free(dev->buffer[0]);
4836     free(dev);
4837     return SANE_STATUS_INVAL;
4838   }
4839 
4840   if (dev->slow == -1) /* option is not predefined in umax.conf and not by backend */
4841   {
4842     dev->slow = 0;
4843   }
4844 
4845   if (dev->smear == -1) /* option is not predefined in umax.conf and not by backend */
4846   {
4847     dev->smear = 0;
4848   }
4849 
4850   if (dev->invert_shading_data == -1) /* nothing defined in umax.conf and not by backend */
4851   {
4852     dev->invert_shading_data = 0;
4853   }
4854 
4855   if (dev->gamma_lsb_padded == -1) /* nothing defined in umax.conf and not by backend */
4856   {
4857     dev->gamma_lsb_padded = 0;
4858   }
4859 
4860   umax_get_inquiry_values(dev);
4861   umax_print_inquiry(dev);
4862   DBG(DBG_inquiry,"\n");
4863   DBG(DBG_inquiry,"==================== end of inquiry ====================\n");
4864   DBG(DBG_inquiry,"\n");
4865 
4866   umax_scsi_close(dev);
4867 
4868   dev->sane.name   = dev->devicename;
4869   dev->sane.vendor = dev->vendor;
4870   dev->sane.model  = dev->product;
4871   dev->sane.type   = "flatbed scanner";
4872 
4873   if (strcmp(dev->sane.model,"PSD ") == 0)
4874   {
4875     dev->sane.type = "page scanner";
4876   }
4877 
4878   dev->x_range.min               = SANE_FIX(0);
4879   dev->x_range.quant             = SANE_FIX(0);
4880   dev->x_range.max               = SANE_FIX(dev->inquiry_fb_width  * MM_PER_INCH);
4881 
4882   dev->y_range.min               = SANE_FIX(0);
4883   dev->y_range.quant             = SANE_FIX(0);
4884   dev->y_range.max               = SANE_FIX(dev->inquiry_fb_length * MM_PER_INCH);
4885 
4886 #if UMAX_RESOLUTION_PERCENT_STEP
4887   dev->x_dpi_range.min           = SANE_FIX(dev->inquiry_optical_res/100);
4888   dev->x_dpi_range.quant         = SANE_FIX(dev->inquiry_optical_res/100);
4889 #else
4890   dev->x_dpi_range.min           = SANE_FIX(5);
4891   dev->x_dpi_range.quant         = SANE_FIX(5);
4892 #endif
4893   dev->x_dpi_range.max           = SANE_FIX(dev->inquiry_x_res);
4894 
4895 #if UMAX_RESOLUTION_PERCENT_STEP
4896   dev->y_dpi_range.min           = SANE_FIX(dev->inquiry_optical_res/100);
4897   dev->y_dpi_range.quant         = SANE_FIX(dev->inquiry_optical_res/100);
4898 #else
4899   dev->y_dpi_range.min           = SANE_FIX(5);
4900   dev->y_dpi_range.quant         = SANE_FIX(5);
4901 #endif
4902   dev->y_dpi_range.max           = SANE_FIX(dev->inquiry_y_res);
4903 
4904   dev->analog_gamma_range.min    = SANE_FIX(1.0);
4905   dev->analog_gamma_range.quant  = SANE_FIX(0.01);
4906   dev->analog_gamma_range.max    = SANE_FIX(2.0);
4907 
4908   DBG(DBG_info,"x_range.max     = %f\n", SANE_UNFIX(dev->x_range.max));
4909   DBG(DBG_info,"y_range.max     = %f\n", SANE_UNFIX(dev->y_range.max));
4910   DBG(DBG_info,"x_dpi_range.max = %f\n", SANE_UNFIX(dev->x_dpi_range.max));
4911   DBG(DBG_info,"y_dpi_range.max = %f\n", SANE_UNFIX(dev->y_dpi_range.max));
4912 
4913   ++num_devices;
4914   dev->next = first_dev;
4915   first_dev = dev;
4916 
4917   if (devp)
4918   {
4919     *devp = dev;
4920   }
4921 
4922  return SANE_STATUS_GOOD;
4923 }
4924 
4925 
4926 /* ------------------------------------------------------------ READER PROCESS SIGTERM HANDLER  ------------ */
4927 
4928 
reader_process_sigterm_handler(int signal)4929 static void reader_process_sigterm_handler(int signal)
4930 {
4931   DBG(DBG_sane_info,"reader_process: terminated by signal %d\n", signal);
4932 
4933   sanei_scsi_req_flush_all(); /* flush SCSI queue */
4934 
4935   _exit (SANE_STATUS_GOOD);
4936 }
4937 
4938 
4939 /* ------------------------------------------------------------ READER PROCESS ----------------------------- */
4940 
4941 
reader_process(void *data)4942 static int reader_process(void *data) /* executed as a child process or as thread */
4943 {
4944  Umax_Scanner *scanner = (Umax_Scanner *)data;
4945  FILE *fp;
4946  int status;
4947  unsigned int data_length;
4948  struct SIGACTION act;
4949  unsigned int i;
4950 
4951   if (sanei_thread_is_forked())
4952   {
4953     DBG(DBG_sane_proc,"reader_process started (forked)\n");
4954     close(scanner->pipe_read_fd);
4955     scanner->pipe_read_fd = -1;
4956 
4957     /* sanei_scsi crashes when the scsi commands are not flushed, done in reader_process_sigterm_handler */
4958     memset(&act, 0, sizeof (act));						   /* define SIGTERM-handler */
4959     act.sa_handler = reader_process_sigterm_handler;
4960     sigaction(SIGTERM, &act, 0);
4961   }
4962   else
4963   {
4964     DBG(DBG_sane_proc,"reader_process started (as thread)\n");
4965   }
4966 
4967 
4968   scanner->device->scsi_maxqueue = scanner->device->request_scsi_maxqueue;
4969 
4970   if (scanner->device->request_scsi_maxqueue > 1)
4971   {
4972     for (i = 1; i<SANE_UMAX_SCSI_MAXQUEUE; i++)
4973     {
4974       if (scanner->device->buffer[i])
4975       {
4976         DBG(DBG_info, "reader_process: freeing SCSI buffer[%d]\n", i);
4977         free(scanner->device->buffer[i]);									     /* free buffer */
4978         scanner->device->buffer[i] = NULL;
4979       }
4980     }
4981 
4982     for (i = 1; i<scanner->device->request_scsi_maxqueue; i++)
4983     {
4984       DBG(DBG_info, "reader_process: allocating SCSI buffer[%d]\n", i);
4985       scanner->device->buffer[i]  = malloc(scanner->device->bufsize);			  /* allocate buffer */
4986 
4987       if (!scanner->device->buffer[i]) /* malloc failed */
4988       {
4989         DBG(DBG_warning, "WARNING: reader_process: only allocated %d/%d scsi buffers\n", i, scanner->device->request_scsi_maxqueue);
4990         scanner->device->scsi_maxqueue = i;
4991         break; /* leave for loop */
4992       }
4993     }
4994   }
4995 
4996   data_length = scanner->params.lines * scanner->params.bytes_per_line;
4997 
4998   fp = fdopen(scanner->pipe_write_fd, "w");
4999   if (!fp)
5000   {
5001     return SANE_STATUS_IO_ERROR;
5002   }
5003 
5004   DBG(DBG_sane_info,"reader_process: starting to READ data\n");
5005 
5006   status = umax_reader_process(scanner->device, fp, data_length);
5007   fclose(fp); /* close write end of pipe */
5008 
5009   for (i = 1; i<scanner->device->request_scsi_maxqueue; i++)
5010   {
5011     if (scanner->device->buffer[i])
5012     {
5013       DBG(DBG_info, "reader_process: freeing SCSI buffer[%d]\n", i);
5014       free(scanner->device->buffer[i]);									     /* free buffer */
5015       scanner->device->buffer[i] = NULL;
5016     }
5017   }
5018   DBG(DBG_sane_info,"reader_process: finished reading data\n");
5019 
5020  return status;
5021 }
5022 
5023 
5024 /* ------------------------------------------------------------ INIT OPTIONS ------------------------------- */
5025 
5026 
init_options(Umax_Scanner *scanner)5027 static SANE_Status init_options(Umax_Scanner *scanner)
5028 {
5029  int i;
5030  int scan_modes;
5031  int bit_depths;
5032 
5033   DBG(DBG_sane_proc,"init_options\n");
5034 
5035   memset(scanner->opt, 0, sizeof (scanner->opt));
5036   memset(scanner->val, 0, sizeof (scanner->val));
5037 
5038   for (i = 0; i < NUM_OPTIONS; ++i)
5039   {
5040     scanner->opt[i].size = sizeof (SANE_Word);
5041     scanner->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
5042   }
5043 
5044   scanner->opt[OPT_NUM_OPTS].name  = SANE_NAME_NUM_OPTIONS; /* empty string */
5045   scanner->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
5046   scanner->opt[OPT_NUM_OPTS].desc  = SANE_DESC_NUM_OPTIONS;
5047   scanner->opt[OPT_NUM_OPTS].type  = SANE_TYPE_INT;
5048   scanner->opt[OPT_NUM_OPTS].cap   = SANE_CAP_SOFT_DETECT;
5049   scanner->val[OPT_NUM_OPTS].w     = NUM_OPTIONS;
5050 
5051   /* "Mode" group: */
5052   scanner->opt[OPT_MODE_GROUP].title = SANE_I18N("Scan Mode");
5053   scanner->opt[OPT_MODE_GROUP].desc  = "";
5054   scanner->opt[OPT_MODE_GROUP].type  = SANE_TYPE_GROUP;
5055   scanner->opt[OPT_MODE_GROUP].cap   = 0;
5056   scanner->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
5057 
5058   scan_modes = -1;
5059 
5060   if (scanner->device->inquiry_lineart)
5061   {
5062     scan_mode_list[++scan_modes] = LINEART_STR;
5063   }
5064 
5065   if (scanner->device->inquiry_halftone)
5066   {
5067     scan_mode_list[++scan_modes]= HALFTONE_STR;
5068   }
5069 
5070   if (scanner->device->inquiry_gray)
5071   {
5072     scan_mode_list[++scan_modes]= GRAY_STR;
5073   }
5074 
5075   if (scanner->device->inquiry_color)
5076   {
5077 /*
5078     if (scanner->device->inquiry_lineart)
5079     { scan_mode_list[++scan_modes]= COLOR_LINEART_STR; }
5080 
5081     if (scanner->device->inquiry_halftone)
5082     { scan_mode_list[++scan_modes]= COLOR_HALFTONE_STR; }
5083 */
5084     scan_mode_list[++scan_modes]= COLOR_STR;
5085   }
5086 
5087   scan_mode_list[scan_modes + 1] = 0;
5088 
5089   {
5090    int i=0;
5091     source_list[i++]= FLB_STR;
5092 
5093     if (scanner->device->inquiry_adfmode)
5094     {
5095       source_list[i++] = ADF_STR;
5096     }
5097 
5098     if (scanner->device->inquiry_transavail)
5099     {
5100       source_list[i++] = UTA_STR;
5101     }
5102 
5103     source_list[i] = 0;
5104   }
5105 
5106   /* scan mode */
5107   scanner->opt[OPT_MODE].name  = SANE_NAME_SCAN_MODE;
5108   scanner->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
5109   scanner->opt[OPT_MODE].desc  = SANE_DESC_SCAN_MODE;
5110   scanner->opt[OPT_MODE].type  = SANE_TYPE_STRING;
5111   scanner->opt[OPT_MODE].size  = max_string_size((SANE_String_Const *) scan_mode_list);
5112   scanner->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
5113   scanner->opt[OPT_MODE].constraint.string_list = (SANE_String_Const *) scan_mode_list;
5114   scanner->val[OPT_MODE].s     = (SANE_Char*)strdup(scan_mode_list[0]);
5115 
5116   /* source */
5117   scanner->opt[OPT_SOURCE].name  = SANE_NAME_SCAN_SOURCE;
5118   scanner->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
5119   scanner->opt[OPT_SOURCE].desc  = SANE_DESC_SCAN_SOURCE;
5120   scanner->opt[OPT_SOURCE].type  = SANE_TYPE_STRING;
5121   scanner->opt[OPT_SOURCE].size  = max_string_size(source_list);
5122   scanner->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
5123   scanner->opt[OPT_SOURCE].constraint.string_list = source_list;
5124   scanner->val[OPT_SOURCE].s     = (SANE_Char*)strdup(source_list[0]);
5125 
5126   /* x-resolution */
5127   scanner->opt[OPT_X_RESOLUTION].name  = SANE_NAME_SCAN_RESOLUTION;
5128   scanner->opt[OPT_X_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
5129   scanner->opt[OPT_X_RESOLUTION].desc  = SANE_DESC_SCAN_RESOLUTION;
5130   scanner->opt[OPT_X_RESOLUTION].type  = SANE_TYPE_FIXED;
5131   scanner->opt[OPT_X_RESOLUTION].unit  = SANE_UNIT_DPI;
5132   scanner->opt[OPT_X_RESOLUTION].constraint_type  = SANE_CONSTRAINT_RANGE;
5133   scanner->opt[OPT_X_RESOLUTION].constraint.range = &scanner->device->x_dpi_range;
5134   scanner->val[OPT_X_RESOLUTION].w     = 100 << SANE_FIXED_SCALE_SHIFT;
5135 
5136   /* y-resolution */
5137   scanner->opt[OPT_Y_RESOLUTION].name  = SANE_NAME_SCAN_Y_RESOLUTION;
5138   scanner->opt[OPT_Y_RESOLUTION].title = SANE_TITLE_SCAN_Y_RESOLUTION;
5139   scanner->opt[OPT_Y_RESOLUTION].desc  = SANE_DESC_SCAN_Y_RESOLUTION;
5140   scanner->opt[OPT_Y_RESOLUTION].type  = SANE_TYPE_FIXED;
5141   scanner->opt[OPT_Y_RESOLUTION].unit  = SANE_UNIT_DPI;
5142   scanner->opt[OPT_Y_RESOLUTION].constraint_type  = SANE_CONSTRAINT_RANGE;
5143   scanner->opt[OPT_Y_RESOLUTION].constraint.range = &scanner->device->y_dpi_range;
5144   scanner->val[OPT_Y_RESOLUTION].w     = 100 << SANE_FIXED_SCALE_SHIFT;
5145   scanner->opt[OPT_Y_RESOLUTION].cap  |= SANE_CAP_INACTIVE;
5146 
5147   /* bind resolution */
5148   scanner->opt[OPT_RESOLUTION_BIND].name  = SANE_NAME_RESOLUTION_BIND;
5149   scanner->opt[OPT_RESOLUTION_BIND].title = SANE_TITLE_RESOLUTION_BIND;
5150   scanner->opt[OPT_RESOLUTION_BIND].desc  = SANE_DESC_RESOLUTION_BIND;
5151   scanner->opt[OPT_RESOLUTION_BIND].type  = SANE_TYPE_BOOL;
5152   scanner->val[OPT_RESOLUTION_BIND].w     = SANE_TRUE;
5153   if (scanner->device->common_xy_resolutions)	/* disable bind if x and y res have to be the same */
5154   {
5155     scanner->opt[OPT_RESOLUTION_BIND].cap  |= SANE_CAP_INACTIVE;
5156   }
5157 
5158 
5159   /* negative */
5160   scanner->opt[OPT_NEGATIVE].name  = SANE_NAME_NEGATIVE;
5161   scanner->opt[OPT_NEGATIVE].title = SANE_TITLE_NEGATIVE;
5162   scanner->opt[OPT_NEGATIVE].desc  = SANE_DESC_NEGATIVE;
5163   scanner->opt[OPT_NEGATIVE].type  = SANE_TYPE_BOOL;
5164   scanner->val[OPT_NEGATIVE].w     = SANE_FALSE;
5165 
5166   if (scanner->device->inquiry_reverse_multi == 0)
5167   {
5168     scanner->opt[OPT_NEGATIVE].cap  |= SANE_CAP_INACTIVE;
5169   }
5170 
5171   /* ------------------------------ */
5172 
5173   /* "Geometry" group: */
5174   scanner->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N("Geometry");
5175   scanner->opt[OPT_GEOMETRY_GROUP].desc  = "";
5176   scanner->opt[OPT_GEOMETRY_GROUP].type  = SANE_TYPE_GROUP;
5177   scanner->opt[OPT_GEOMETRY_GROUP].cap   = SANE_CAP_ADVANCED;
5178   scanner->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
5179 
5180   /* top-left x */
5181   scanner->opt[OPT_TL_X].name  = SANE_NAME_SCAN_TL_X;
5182   scanner->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
5183   scanner->opt[OPT_TL_X].desc  = SANE_DESC_SCAN_TL_X;
5184   scanner->opt[OPT_TL_X].type  = SANE_TYPE_FIXED;
5185   scanner->opt[OPT_TL_X].unit  = SANE_UNIT_MM;
5186   scanner->opt[OPT_TL_X].constraint_type  = SANE_CONSTRAINT_RANGE;
5187   scanner->opt[OPT_TL_X].constraint.range = &(scanner->device->x_range);
5188   scanner->val[OPT_TL_X].w     = 0;
5189 
5190   /* top-left y */
5191   scanner->opt[OPT_TL_Y].name  = SANE_NAME_SCAN_TL_Y;
5192   scanner->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
5193   scanner->opt[OPT_TL_Y].desc  = SANE_DESC_SCAN_TL_Y;
5194   scanner->opt[OPT_TL_Y].type  = SANE_TYPE_FIXED;
5195   scanner->opt[OPT_TL_Y].unit  = SANE_UNIT_MM;
5196   scanner->opt[OPT_TL_Y].constraint_type  = SANE_CONSTRAINT_RANGE;
5197   scanner->opt[OPT_TL_Y].constraint.range = &(scanner->device->y_range);
5198   scanner->val[OPT_TL_Y].w     = 0;
5199 
5200   /* bottom-right x */
5201   scanner->opt[OPT_BR_X].name  = SANE_NAME_SCAN_BR_X;
5202   scanner->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
5203   scanner->opt[OPT_BR_X].desc  = SANE_DESC_SCAN_BR_X;
5204   scanner->opt[OPT_BR_X].type  = SANE_TYPE_FIXED;
5205   scanner->opt[OPT_BR_X].unit  = SANE_UNIT_MM;
5206   scanner->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
5207   scanner->opt[OPT_BR_X].constraint.range = &(scanner->device->x_range);
5208   scanner->val[OPT_BR_X].w     = scanner->device->x_range.max;
5209 
5210   /* bottom-right y */
5211   scanner->opt[OPT_BR_Y].name  = SANE_NAME_SCAN_BR_Y;
5212   scanner->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
5213   scanner->opt[OPT_BR_Y].desc  = SANE_DESC_SCAN_BR_Y;
5214   scanner->opt[OPT_BR_Y].type  = SANE_TYPE_FIXED;
5215   scanner->opt[OPT_BR_Y].unit  = SANE_UNIT_MM;
5216   scanner->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
5217   scanner->opt[OPT_BR_Y].constraint.range = &(scanner->device->y_range);
5218   scanner->val[OPT_BR_Y].w     = scanner->device->y_range.max;
5219 
5220   /* ------------------------------ */
5221 
5222 
5223   /* "Enhancement" group: */
5224   scanner->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N("Enhancement");
5225   scanner->opt[OPT_ENHANCEMENT_GROUP].desc  = "";
5226   scanner->opt[OPT_ENHANCEMENT_GROUP].type  = SANE_TYPE_GROUP;
5227   scanner->opt[OPT_ENHANCEMENT_GROUP].cap   = 0;
5228   scanner->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
5229 
5230 
5231   /* bit depth */
5232   bit_depths = 0;
5233 
5234   if (scanner->device->inquiry_GOB & 1)
5235   {
5236     bit_depth_list[++bit_depths] = 8;
5237   }
5238 
5239   if (scanner->device->inquiry_GOB & 2)
5240   {
5241     bit_depth_list[++bit_depths] = 9;
5242   }
5243 
5244   if (scanner->device->inquiry_GOB & 4)
5245   {
5246     bit_depth_list[++bit_depths] = 10;
5247   }
5248 
5249   if (scanner->device->inquiry_GOB & 8)
5250   {
5251     bit_depth_list[++bit_depths] = 12;
5252   }
5253 
5254   if (scanner->device->inquiry_GOB & 16)
5255   {
5256     bit_depth_list[++bit_depths] = 14;
5257   }
5258 
5259   if (scanner->device->inquiry_GOB & 32)
5260   {
5261     bit_depth_list[++bit_depths] = 16;
5262   }
5263 
5264   bit_depth_list[0] = bit_depths;
5265 
5266   scanner->opt[OPT_BIT_DEPTH].name  = SANE_NAME_BIT_DEPTH;
5267   scanner->opt[OPT_BIT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
5268   scanner->opt[OPT_BIT_DEPTH].desc  = SANE_DESC_BIT_DEPTH;
5269   scanner->opt[OPT_BIT_DEPTH].type  = SANE_TYPE_INT;
5270   scanner->opt[OPT_BIT_DEPTH].unit  = SANE_UNIT_BIT;
5271   scanner->opt[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
5272   scanner->opt[OPT_BIT_DEPTH].constraint.word_list = bit_depth_list;
5273   scanner->val[OPT_BIT_DEPTH].w     = bit_depth_list[1];
5274 
5275 
5276   /* quality-calibration */
5277   scanner->opt[OPT_QUALITY].name  = SANE_NAME_QUALITY_CAL;
5278   scanner->opt[OPT_QUALITY].title = SANE_TITLE_QUALITY_CAL;
5279   scanner->opt[OPT_QUALITY].desc  = SANE_DESC_QUALITY_CAL;
5280   scanner->opt[OPT_QUALITY].type  = SANE_TYPE_BOOL;
5281   scanner->val[OPT_QUALITY].w     = SANE_FALSE;
5282 
5283   if ((scanner->device->inquiry_quality_ctrl == 0) || (scanner->device->force_quality_calibration) )
5284   {
5285     scanner->opt[OPT_QUALITY].cap  |= SANE_CAP_INACTIVE;
5286   }
5287   else /* enable quality calibration when available */
5288   {
5289     scanner->val[OPT_QUALITY].w = SANE_TRUE;
5290   }
5291 
5292 
5293   /* double optical resolution */
5294   scanner->opt[OPT_DOR].name  = SANE_NAME_DOR;
5295   scanner->opt[OPT_DOR].title = SANE_TITLE_DOR;
5296   scanner->opt[OPT_DOR].desc  = SANE_DESC_DOR;
5297   scanner->opt[OPT_DOR].type  = SANE_TYPE_BOOL;
5298   scanner->val[OPT_DOR].w     = SANE_FALSE;
5299 
5300   if (scanner->device->inquiry_dor == 0)
5301   {
5302     scanner->opt[OPT_DOR].cap  |= SANE_CAP_INACTIVE;
5303   }
5304 
5305 
5306   /* warmup */
5307   scanner->opt[OPT_WARMUP].name  = SANE_NAME_WARMUP;
5308   scanner->opt[OPT_WARMUP].title = SANE_TITLE_WARMUP;
5309   scanner->opt[OPT_WARMUP].desc  = SANE_DESC_WARMUP;
5310   scanner->opt[OPT_WARMUP].type  = SANE_TYPE_BOOL;
5311   scanner->val[OPT_WARMUP].w     = SANE_FALSE;
5312 
5313   if (scanner->device->inquiry_max_warmup_time == 0)
5314   {
5315     scanner->opt[OPT_WARMUP].cap  |= SANE_CAP_INACTIVE;
5316   }
5317 
5318   scanner->opt[OPT_RGB_BIND].name  = SANE_NAME_RGB_BIND;
5319   scanner->opt[OPT_RGB_BIND].title = SANE_TITLE_RGB_BIND;
5320   scanner->opt[OPT_RGB_BIND].desc  = SANE_DESC_RGB_BIND;
5321   scanner->opt[OPT_RGB_BIND].type  = SANE_TYPE_BOOL;
5322   scanner->val[OPT_RGB_BIND].w     = SANE_FALSE;
5323 
5324   /* brightness */
5325   scanner->opt[OPT_BRIGHTNESS].name  = SANE_NAME_BRIGHTNESS;
5326   scanner->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
5327   scanner->opt[OPT_BRIGHTNESS].desc  = SANE_DESC_BRIGHTNESS;
5328   scanner->opt[OPT_BRIGHTNESS].type  = SANE_TYPE_FIXED;
5329   scanner->opt[OPT_BRIGHTNESS].unit  = SANE_UNIT_PERCENT;
5330   scanner->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
5331   scanner->opt[OPT_BRIGHTNESS].constraint.range = &percentage_range;
5332   scanner->val[OPT_BRIGHTNESS].w     = 0;
5333 
5334   /* contrast */
5335   scanner->opt[OPT_CONTRAST].name  = SANE_NAME_CONTRAST;
5336   scanner->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
5337   scanner->opt[OPT_CONTRAST].desc  = SANE_DESC_CONTRAST;
5338   scanner->opt[OPT_CONTRAST].type  = SANE_TYPE_FIXED;
5339   scanner->opt[OPT_CONTRAST].unit  = SANE_UNIT_PERCENT;
5340   scanner->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
5341   scanner->opt[OPT_CONTRAST].constraint.range = &percentage_range;
5342   scanner->val[OPT_CONTRAST].w     = 0;
5343 
5344 
5345   /* threshold */
5346   scanner->opt[OPT_THRESHOLD].name  = SANE_NAME_THRESHOLD;
5347   scanner->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
5348   scanner->opt[OPT_THRESHOLD].desc  = SANE_DESC_THRESHOLD;
5349   scanner->opt[OPT_THRESHOLD].type  = SANE_TYPE_FIXED;
5350   scanner->opt[OPT_THRESHOLD].unit  = SANE_UNIT_PERCENT;
5351   scanner->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
5352   scanner->opt[OPT_THRESHOLD].constraint.range = &percentage_range_100;
5353   scanner->val[OPT_THRESHOLD].w     = SANE_FIX(50);
5354 
5355 
5356   /* ------------------------------ */
5357 
5358 
5359   /* highlight, white level */
5360   scanner->opt[OPT_HIGHLIGHT].name  = SANE_NAME_HIGHLIGHT;
5361   scanner->opt[OPT_HIGHLIGHT].title = SANE_TITLE_HIGHLIGHT;
5362   scanner->opt[OPT_HIGHLIGHT].desc  = SANE_DESC_HIGHLIGHT;
5363   scanner->opt[OPT_HIGHLIGHT].type  = SANE_TYPE_FIXED;
5364   scanner->opt[OPT_HIGHLIGHT].unit  = SANE_UNIT_PERCENT;
5365   scanner->opt[OPT_HIGHLIGHT].constraint_type = SANE_CONSTRAINT_RANGE;
5366   scanner->opt[OPT_HIGHLIGHT].constraint.range = &percentage_range_100;
5367   scanner->val[OPT_HIGHLIGHT].w     = SANE_FIX(100);
5368 
5369   scanner->opt[OPT_HIGHLIGHT_R].name  = SANE_NAME_HIGHLIGHT_R;
5370   scanner->opt[OPT_HIGHLIGHT_R].title = SANE_TITLE_HIGHLIGHT_R;
5371   scanner->opt[OPT_HIGHLIGHT_R].desc  = SANE_DESC_HIGHLIGHT_R;
5372   scanner->opt[OPT_HIGHLIGHT_R].type  = SANE_TYPE_FIXED;
5373   scanner->opt[OPT_HIGHLIGHT_R].unit  = SANE_UNIT_PERCENT;
5374   scanner->opt[OPT_HIGHLIGHT_R].constraint_type = SANE_CONSTRAINT_RANGE;
5375   scanner->opt[OPT_HIGHLIGHT_R].constraint.range = &percentage_range_100;
5376   scanner->val[OPT_HIGHLIGHT_R].w     = SANE_FIX(100);
5377 
5378   scanner->opt[OPT_HIGHLIGHT_G].name  = SANE_NAME_HIGHLIGHT_G;
5379   scanner->opt[OPT_HIGHLIGHT_G].title = SANE_TITLE_HIGHLIGHT_G;
5380   scanner->opt[OPT_HIGHLIGHT_G].desc  = SANE_DESC_HIGHLIGHT_G;
5381   scanner->opt[OPT_HIGHLIGHT_G].type  = SANE_TYPE_FIXED;
5382   scanner->opt[OPT_HIGHLIGHT_G].unit  = SANE_UNIT_PERCENT;
5383   scanner->opt[OPT_HIGHLIGHT_G].constraint_type = SANE_CONSTRAINT_RANGE;
5384   scanner->opt[OPT_HIGHLIGHT_G].constraint.range = &percentage_range_100;
5385   scanner->val[OPT_HIGHLIGHT_G].w     = SANE_FIX(100);
5386 
5387   scanner->opt[OPT_HIGHLIGHT_B].name  = SANE_NAME_HIGHLIGHT_B;
5388   scanner->opt[OPT_HIGHLIGHT_B].title = SANE_TITLE_HIGHLIGHT_B;
5389   scanner->opt[OPT_HIGHLIGHT_B].desc  = SANE_DESC_HIGHLIGHT_B;
5390   scanner->opt[OPT_HIGHLIGHT_B].type  = SANE_TYPE_FIXED;
5391   scanner->opt[OPT_HIGHLIGHT_B].unit  = SANE_UNIT_PERCENT;
5392   scanner->opt[OPT_HIGHLIGHT_B].constraint_type = SANE_CONSTRAINT_RANGE;
5393   scanner->opt[OPT_HIGHLIGHT_B].constraint.range = &percentage_range_100;
5394   scanner->val[OPT_HIGHLIGHT_B].w     = SANE_FIX(100);
5395 
5396 
5397   /* shadow, black level */
5398   scanner->opt[OPT_SHADOW].name  = SANE_NAME_SHADOW;
5399   scanner->opt[OPT_SHADOW].title = SANE_TITLE_SHADOW;
5400   scanner->opt[OPT_SHADOW].desc  = SANE_DESC_SHADOW;
5401   scanner->opt[OPT_SHADOW].type  = SANE_TYPE_FIXED;
5402   scanner->opt[OPT_SHADOW].unit  = SANE_UNIT_PERCENT;
5403   scanner->opt[OPT_SHADOW].constraint_type = SANE_CONSTRAINT_RANGE;
5404   scanner->opt[OPT_SHADOW].constraint.range = &percentage_range_100;
5405   scanner->val[OPT_SHADOW].w     = 0;
5406 
5407   scanner->opt[OPT_SHADOW_R].name  = SANE_NAME_SHADOW_R;
5408   scanner->opt[OPT_SHADOW_R].title = SANE_TITLE_SHADOW_R;
5409   scanner->opt[OPT_SHADOW_R].desc  = SANE_DESC_SHADOW_R;
5410   scanner->opt[OPT_SHADOW_R].type  = SANE_TYPE_FIXED;
5411   scanner->opt[OPT_SHADOW_R].unit  = SANE_UNIT_PERCENT;
5412   scanner->opt[OPT_SHADOW_R].constraint_type = SANE_CONSTRAINT_RANGE;
5413   scanner->opt[OPT_SHADOW_R].constraint.range = &percentage_range_100;
5414   scanner->val[OPT_SHADOW_R].w     = 0;
5415 
5416   scanner->opt[OPT_SHADOW_G].name  = SANE_NAME_SHADOW_G;
5417   scanner->opt[OPT_SHADOW_G].title = SANE_TITLE_SHADOW_G;
5418   scanner->opt[OPT_SHADOW_G].desc  = SANE_DESC_SHADOW_G;
5419   scanner->opt[OPT_SHADOW_G].type  = SANE_TYPE_FIXED;
5420   scanner->opt[OPT_SHADOW_G].unit  = SANE_UNIT_PERCENT;
5421   scanner->opt[OPT_SHADOW_G].constraint_type = SANE_CONSTRAINT_RANGE;
5422   scanner->opt[OPT_SHADOW_G].constraint.range = &percentage_range_100;
5423   scanner->val[OPT_SHADOW_G].w     = 0;
5424 
5425   scanner->opt[OPT_SHADOW_B].name  = SANE_NAME_SHADOW_B;
5426   scanner->opt[OPT_SHADOW_B].title = SANE_TITLE_SHADOW_B;
5427   scanner->opt[OPT_SHADOW_B].desc  = SANE_DESC_SHADOW_B;
5428   scanner->opt[OPT_SHADOW_B].type  = SANE_TYPE_FIXED;
5429   scanner->opt[OPT_SHADOW_B].unit  = SANE_UNIT_PERCENT;
5430   scanner->opt[OPT_SHADOW_B].constraint_type = SANE_CONSTRAINT_RANGE;
5431   scanner->opt[OPT_SHADOW_B].constraint.range = &percentage_range_100;
5432   scanner->val[OPT_SHADOW_B].w     = 0;
5433 
5434 
5435 
5436   /* analog-gamma */
5437   scanner->opt[OPT_ANALOG_GAMMA].name  = SANE_NAME_ANALOG_GAMMA;
5438   scanner->opt[OPT_ANALOG_GAMMA].title = SANE_TITLE_ANALOG_GAMMA;
5439   scanner->opt[OPT_ANALOG_GAMMA].desc  = SANE_DESC_ANALOG_GAMMA;
5440   scanner->opt[OPT_ANALOG_GAMMA].type  = SANE_TYPE_FIXED;
5441   scanner->opt[OPT_ANALOG_GAMMA].unit  = SANE_UNIT_NONE;
5442   scanner->opt[OPT_ANALOG_GAMMA].constraint_type  = SANE_CONSTRAINT_RANGE;
5443   scanner->opt[OPT_ANALOG_GAMMA].constraint.range = &(scanner->device->analog_gamma_range);
5444   scanner->val[OPT_ANALOG_GAMMA].w     = 1 << SANE_FIXED_SCALE_SHIFT;
5445 
5446   scanner->opt[OPT_ANALOG_GAMMA_R].name  = SANE_NAME_ANALOG_GAMMA_R;
5447   scanner->opt[OPT_ANALOG_GAMMA_R].title = SANE_TITLE_ANALOG_GAMMA_R;
5448   scanner->opt[OPT_ANALOG_GAMMA_R].desc  = SANE_DESC_ANALOG_GAMMA_R;
5449   scanner->opt[OPT_ANALOG_GAMMA_R].type  = SANE_TYPE_FIXED;
5450   scanner->opt[OPT_ANALOG_GAMMA_R].unit  = SANE_UNIT_NONE;
5451   scanner->opt[OPT_ANALOG_GAMMA_R].constraint_type  = SANE_CONSTRAINT_RANGE;
5452   scanner->opt[OPT_ANALOG_GAMMA_R].constraint.range = &(scanner->device->analog_gamma_range);
5453   scanner->val[OPT_ANALOG_GAMMA_R].w     = 1 << SANE_FIXED_SCALE_SHIFT;
5454 
5455   scanner->opt[OPT_ANALOG_GAMMA_G].name  = SANE_NAME_ANALOG_GAMMA_G;
5456   scanner->opt[OPT_ANALOG_GAMMA_G].title = SANE_TITLE_ANALOG_GAMMA_G;
5457   scanner->opt[OPT_ANALOG_GAMMA_G].desc  = SANE_DESC_ANALOG_GAMMA_G;
5458   scanner->opt[OPT_ANALOG_GAMMA_G].type  = SANE_TYPE_FIXED;
5459   scanner->opt[OPT_ANALOG_GAMMA_G].unit  = SANE_UNIT_NONE;
5460   scanner->opt[OPT_ANALOG_GAMMA_G].constraint_type  = SANE_CONSTRAINT_RANGE;
5461   scanner->opt[OPT_ANALOG_GAMMA_G].constraint.range = &(scanner->device->analog_gamma_range);
5462   scanner->val[OPT_ANALOG_GAMMA_G].w     = 1 << SANE_FIXED_SCALE_SHIFT;
5463 
5464   scanner->opt[OPT_ANALOG_GAMMA_B].name  = SANE_NAME_ANALOG_GAMMA_B;
5465   scanner->opt[OPT_ANALOG_GAMMA_B].title = SANE_TITLE_ANALOG_GAMMA_B;
5466   scanner->opt[OPT_ANALOG_GAMMA_B].desc  = SANE_DESC_ANALOG_GAMMA_B;
5467   scanner->opt[OPT_ANALOG_GAMMA_B].type  = SANE_TYPE_FIXED;
5468   scanner->opt[OPT_ANALOG_GAMMA_B].unit  = SANE_UNIT_NONE;
5469   scanner->opt[OPT_ANALOG_GAMMA_B].constraint_type  = SANE_CONSTRAINT_RANGE;
5470   scanner->opt[OPT_ANALOG_GAMMA_B].constraint.range = &(scanner->device->analog_gamma_range);
5471   scanner->val[OPT_ANALOG_GAMMA_B].w     = 1 << SANE_FIXED_SCALE_SHIFT;
5472 
5473 
5474   /* custom-gamma table */
5475   scanner->opt[OPT_CUSTOM_GAMMA].name  = SANE_NAME_CUSTOM_GAMMA;
5476   scanner->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
5477   scanner->opt[OPT_CUSTOM_GAMMA].desc  = SANE_DESC_CUSTOM_GAMMA;
5478   scanner->opt[OPT_CUSTOM_GAMMA].type  = SANE_TYPE_BOOL;
5479   scanner->val[OPT_CUSTOM_GAMMA].w     = SANE_TRUE;
5480 
5481   /* grayscale gamma vector */
5482   scanner->opt[OPT_GAMMA_VECTOR].name  = SANE_NAME_GAMMA_VECTOR;
5483   scanner->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
5484   scanner->opt[OPT_GAMMA_VECTOR].desc  = SANE_DESC_GAMMA_VECTOR;
5485   scanner->opt[OPT_GAMMA_VECTOR].type  = SANE_TYPE_INT;
5486   scanner->opt[OPT_GAMMA_VECTOR].unit  = SANE_UNIT_NONE;
5487   scanner->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
5488   scanner->val[OPT_GAMMA_VECTOR].wa    = scanner->gamma_table[0];
5489   scanner->opt[OPT_GAMMA_VECTOR].constraint.range = &scanner->output_range;
5490   scanner->opt[OPT_GAMMA_VECTOR].size  = scanner->gamma_length * sizeof(SANE_Word);
5491 
5492   scanner->output_range.min   = 0;
5493 
5494   if (bit_depth_list[1] == 8)
5495   {
5496     scanner->output_range.max = 255;    /* 8 bits/pixel */
5497   }
5498   else
5499   {
5500     scanner->output_range.max = 65535;  /* 9-16 bits/pixel */
5501   }
5502 
5503   scanner->output_range.quant = 0;
5504 
5505   /* red gamma vector */
5506   scanner->opt[OPT_GAMMA_VECTOR_R].name  = SANE_NAME_GAMMA_VECTOR_R;
5507   scanner->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
5508   scanner->opt[OPT_GAMMA_VECTOR_R].desc  = SANE_DESC_GAMMA_VECTOR_R;
5509   scanner->opt[OPT_GAMMA_VECTOR_R].type  = SANE_TYPE_INT;
5510   scanner->opt[OPT_GAMMA_VECTOR_R].unit  = SANE_UNIT_NONE;
5511   scanner->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
5512   scanner->val[OPT_GAMMA_VECTOR_R].wa    = scanner->gamma_table[1];
5513   scanner->opt[OPT_GAMMA_VECTOR_R].constraint.range = &(scanner->gamma_range);
5514   scanner->opt[OPT_GAMMA_VECTOR_R].size  = scanner->gamma_length * sizeof(SANE_Word);
5515 
5516   /* green gamma vector */
5517   scanner->opt[OPT_GAMMA_VECTOR_G].name  = SANE_NAME_GAMMA_VECTOR_G;
5518   scanner->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
5519   scanner->opt[OPT_GAMMA_VECTOR_G].desc  = SANE_DESC_GAMMA_VECTOR_G;
5520   scanner->opt[OPT_GAMMA_VECTOR_G].type  = SANE_TYPE_INT;
5521   scanner->opt[OPT_GAMMA_VECTOR_G].unit  = SANE_UNIT_NONE;
5522   scanner->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
5523   scanner->val[OPT_GAMMA_VECTOR_G].wa    = scanner->gamma_table[2];
5524   scanner->opt[OPT_GAMMA_VECTOR_G].constraint.range = &(scanner->gamma_range);
5525   scanner->opt[OPT_GAMMA_VECTOR_G].size  = scanner->gamma_length * sizeof(SANE_Word);
5526 
5527   /* blue gamma vector */
5528   scanner->opt[OPT_GAMMA_VECTOR_B].name  = SANE_NAME_GAMMA_VECTOR_B;
5529   scanner->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
5530   scanner->opt[OPT_GAMMA_VECTOR_B].desc  = SANE_DESC_GAMMA_VECTOR_B;
5531   scanner->opt[OPT_GAMMA_VECTOR_B].type  = SANE_TYPE_INT;
5532   scanner->opt[OPT_GAMMA_VECTOR_B].unit  = SANE_UNIT_NONE;
5533   scanner->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
5534   scanner->val[OPT_GAMMA_VECTOR_B].wa    = scanner->gamma_table[3];
5535   scanner->opt[OPT_GAMMA_VECTOR_B].constraint.range = &(scanner->gamma_range);
5536   scanner->opt[OPT_GAMMA_VECTOR_B].size  = scanner->gamma_length * sizeof(SANE_Word);
5537 
5538   /* halftone dimension */
5539   scanner->opt[OPT_HALFTONE_DIMENSION].name  = SANE_NAME_HALFTONE_DIMENSION;
5540   scanner->opt[OPT_HALFTONE_DIMENSION].title = SANE_TITLE_HALFTONE_DIMENSION;
5541   scanner->opt[OPT_HALFTONE_DIMENSION].desc  = SANE_DESC_HALFTONE_DIMENSION;
5542   scanner->opt[OPT_HALFTONE_DIMENSION].type  = SANE_TYPE_INT;
5543   scanner->opt[OPT_HALFTONE_DIMENSION].unit  = SANE_UNIT_PIXEL;
5544   scanner->opt[OPT_HALFTONE_DIMENSION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
5545   scanner->opt[OPT_HALFTONE_DIMENSION].constraint.word_list = pattern_dim_list;
5546   scanner->val[OPT_HALFTONE_DIMENSION].w     = pattern_dim_list[1];
5547 
5548   /* halftone pattern */
5549   scanner->opt[OPT_HALFTONE_PATTERN].name  = SANE_NAME_HALFTONE_PATTERN;
5550   scanner->opt[OPT_HALFTONE_PATTERN].title = SANE_TITLE_HALFTONE_PATTERN;
5551   scanner->opt[OPT_HALFTONE_PATTERN].desc  = SANE_DESC_HALFTONE_PATTERN;
5552   scanner->opt[OPT_HALFTONE_PATTERN].type  = SANE_TYPE_INT;
5553   scanner->opt[OPT_HALFTONE_PATTERN].size  = 0;
5554   scanner->opt[OPT_HALFTONE_PATTERN].constraint_type = SANE_CONSTRAINT_RANGE;
5555   scanner->opt[OPT_HALFTONE_PATTERN].constraint.range = &u8_range;
5556   scanner->val[OPT_HALFTONE_PATTERN].wa    = scanner->halftone_pattern;
5557 
5558 
5559   /* ------------------------------ */
5560 
5561 
5562   /* "Advanced" group: */
5563   scanner->opt[OPT_ADVANCED_GROUP].title = SANE_I18N("Advanced");
5564   scanner->opt[OPT_ADVANCED_GROUP].desc  = "";
5565   scanner->opt[OPT_ADVANCED_GROUP].type  = SANE_TYPE_GROUP;
5566   scanner->opt[OPT_ADVANCED_GROUP].cap   = SANE_CAP_ADVANCED;
5567   scanner->opt[OPT_ADVANCED_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
5568 
5569 
5570   /* ------------------------------ */
5571 
5572 
5573   /* select exposure time */
5574   scanner->opt[OPT_SELECT_EXPOSURE_TIME].name  = SANE_NAME_SELECT_EXPOSURE_TIME;
5575   scanner->opt[OPT_SELECT_EXPOSURE_TIME].title = SANE_TITLE_SELECT_EXPOSURE_TIME;
5576   scanner->opt[OPT_SELECT_EXPOSURE_TIME].desc  = SANE_DESC_SELECT_EXPOSURE_TIME;
5577   scanner->opt[OPT_SELECT_EXPOSURE_TIME].type  = SANE_TYPE_BOOL;
5578   scanner->val[OPT_SELECT_EXPOSURE_TIME].w     = SANE_FALSE;
5579 
5580   /* select calibration exposure time */
5581   scanner->opt[OPT_SELECT_CAL_EXPOSURE_TIME].name  = SANE_UMAX_NAME_SELECT_CALIBRATON_EXPOSURE_TIME;
5582   scanner->opt[OPT_SELECT_CAL_EXPOSURE_TIME].title = SANE_UMAX_TITLE_SELECT_CALIBRATION_EXPOSURE_TIME;
5583   scanner->opt[OPT_SELECT_CAL_EXPOSURE_TIME].desc  = SANE_UMAX_DESC_SELECT_CALIBRATION_EXPOSURE_TIME;
5584   scanner->opt[OPT_SELECT_CAL_EXPOSURE_TIME].type  = SANE_TYPE_BOOL;
5585   scanner->val[OPT_SELECT_CAL_EXPOSURE_TIME].w     = SANE_FALSE;
5586   scanner->opt[OPT_SELECT_CAL_EXPOSURE_TIME].cap  |= SANE_CAP_INACTIVE;
5587 
5588   /* calibration exposure time */
5589   scanner->opt[OPT_CAL_EXPOS_TIME].name  = SANE_NAME_CAL_EXPOS_TIME;
5590   scanner->opt[OPT_CAL_EXPOS_TIME].title = SANE_TITLE_CAL_EXPOS_TIME;
5591   scanner->opt[OPT_CAL_EXPOS_TIME].desc  = SANE_DESC_CAL_EXPOS_TIME;
5592   scanner->opt[OPT_CAL_EXPOS_TIME].type  = SANE_TYPE_INT;
5593   scanner->opt[OPT_CAL_EXPOS_TIME].unit  = SANE_UNIT_MICROSECOND;
5594   scanner->opt[OPT_CAL_EXPOS_TIME].constraint_type = SANE_CONSTRAINT_RANGE;
5595   scanner->opt[OPT_CAL_EXPOS_TIME].constraint.range = &(scanner->exposure_time_range);
5596   scanner->val[OPT_CAL_EXPOS_TIME].w     = scanner->device->inquiry_exposure_time_g_fb_def *
5597                                            scanner->device->inquiry_exposure_time_step_unit;
5598   scanner->opt[OPT_CAL_EXPOS_TIME].cap  |= SANE_CAP_INACTIVE;
5599 
5600   /* calibration exposure time red */
5601   scanner->opt[OPT_CAL_EXPOS_TIME_R].name  = SANE_NAME_CAL_EXPOS_TIME_R;
5602   scanner->opt[OPT_CAL_EXPOS_TIME_R].title = SANE_TITLE_CAL_EXPOS_TIME_R;
5603   scanner->opt[OPT_CAL_EXPOS_TIME_R].desc  = SANE_DESC_CAL_EXPOS_TIME_R;
5604   scanner->opt[OPT_CAL_EXPOS_TIME_R].type  = SANE_TYPE_INT;
5605   scanner->opt[OPT_CAL_EXPOS_TIME_R].unit  = SANE_UNIT_MICROSECOND;
5606   scanner->opt[OPT_CAL_EXPOS_TIME_R].constraint_type = SANE_CONSTRAINT_RANGE;
5607   scanner->opt[OPT_CAL_EXPOS_TIME_R].constraint.range = &(scanner->exposure_time_range);
5608   scanner->val[OPT_CAL_EXPOS_TIME_R].w     = scanner->device->inquiry_exposure_time_c_fb_def_r *
5609                                              scanner->device->inquiry_exposure_time_step_unit;
5610   scanner->opt[OPT_CAL_EXPOS_TIME_R].cap  |= SANE_CAP_INACTIVE;
5611 
5612   /* calibration exposure time green */
5613   scanner->opt[OPT_CAL_EXPOS_TIME_G].name  = SANE_NAME_CAL_EXPOS_TIME_G;
5614   scanner->opt[OPT_CAL_EXPOS_TIME_G].title = SANE_TITLE_CAL_EXPOS_TIME_G;
5615   scanner->opt[OPT_CAL_EXPOS_TIME_G].desc  = SANE_DESC_CAL_EXPOS_TIME_G;
5616   scanner->opt[OPT_CAL_EXPOS_TIME_G].type  = SANE_TYPE_INT;
5617   scanner->opt[OPT_CAL_EXPOS_TIME_G].unit  = SANE_UNIT_MICROSECOND;
5618   scanner->opt[OPT_CAL_EXPOS_TIME_G].constraint_type = SANE_CONSTRAINT_RANGE;
5619   scanner->opt[OPT_CAL_EXPOS_TIME_G].constraint.range = &(scanner->exposure_time_range);
5620   scanner->val[OPT_CAL_EXPOS_TIME_G].w     = scanner->device->inquiry_exposure_time_c_fb_def_g *
5621                                              scanner->device->inquiry_exposure_time_step_unit;
5622   scanner->opt[OPT_CAL_EXPOS_TIME_G].cap  |= SANE_CAP_INACTIVE;
5623 
5624   /* calibration exposure time blue */
5625   scanner->opt[OPT_CAL_EXPOS_TIME_B].name  = SANE_NAME_CAL_EXPOS_TIME_B;
5626   scanner->opt[OPT_CAL_EXPOS_TIME_B].title = SANE_TITLE_CAL_EXPOS_TIME_B;
5627   scanner->opt[OPT_CAL_EXPOS_TIME_B].desc  = SANE_DESC_CAL_EXPOS_TIME_B;
5628   scanner->opt[OPT_CAL_EXPOS_TIME_B].type  = SANE_TYPE_INT;
5629   scanner->opt[OPT_CAL_EXPOS_TIME_B].unit  = SANE_UNIT_MICROSECOND;
5630   scanner->opt[OPT_CAL_EXPOS_TIME_B].constraint_type = SANE_CONSTRAINT_RANGE;
5631   scanner->opt[OPT_CAL_EXPOS_TIME_B].constraint.range = &(scanner->exposure_time_range);
5632   scanner->val[OPT_CAL_EXPOS_TIME_B].w     = scanner->device->inquiry_exposure_time_c_fb_def_b *
5633                                              scanner->device->inquiry_exposure_time_step_unit;
5634   scanner->opt[OPT_CAL_EXPOS_TIME_B].cap  |= SANE_CAP_INACTIVE;
5635 
5636   /* scan exposure time */
5637   scanner->opt[OPT_SCAN_EXPOS_TIME].name  = SANE_NAME_SCAN_EXPOS_TIME;
5638   scanner->opt[OPT_SCAN_EXPOS_TIME].title = SANE_TITLE_SCAN_EXPOS_TIME;
5639   scanner->opt[OPT_SCAN_EXPOS_TIME].desc  = SANE_DESC_SCAN_EXPOS_TIME;
5640   scanner->opt[OPT_SCAN_EXPOS_TIME].type  = SANE_TYPE_INT;
5641   scanner->opt[OPT_SCAN_EXPOS_TIME].unit  = SANE_UNIT_MICROSECOND;
5642   scanner->opt[OPT_SCAN_EXPOS_TIME].constraint_type = SANE_CONSTRAINT_RANGE;
5643   scanner->opt[OPT_SCAN_EXPOS_TIME].constraint.range = &(scanner->exposure_time_range);
5644   scanner->val[OPT_SCAN_EXPOS_TIME].w     = scanner->device->inquiry_exposure_time_g_fb_def *
5645                                             scanner->device->inquiry_exposure_time_step_unit;
5646   scanner->opt[OPT_SCAN_EXPOS_TIME].cap  |= SANE_CAP_INACTIVE;
5647 
5648   /* scan exposure time red */
5649   scanner->opt[OPT_SCAN_EXPOS_TIME_R].name  = SANE_NAME_SCAN_EXPOS_TIME_R;
5650   scanner->opt[OPT_SCAN_EXPOS_TIME_R].title = SANE_TITLE_SCAN_EXPOS_TIME_R;
5651   scanner->opt[OPT_SCAN_EXPOS_TIME_R].desc  = SANE_DESC_SCAN_EXPOS_TIME_R;
5652   scanner->opt[OPT_SCAN_EXPOS_TIME_R].type  = SANE_TYPE_INT;
5653   scanner->opt[OPT_SCAN_EXPOS_TIME_R].unit  = SANE_UNIT_MICROSECOND;
5654   scanner->opt[OPT_SCAN_EXPOS_TIME_R].constraint_type = SANE_CONSTRAINT_RANGE;
5655   scanner->opt[OPT_SCAN_EXPOS_TIME_R].constraint.range = &(scanner->exposure_time_range);
5656   scanner->val[OPT_SCAN_EXPOS_TIME_R].w     = scanner->device->inquiry_exposure_time_c_fb_def_r *
5657                                               scanner->device->inquiry_exposure_time_step_unit;
5658   scanner->opt[OPT_SCAN_EXPOS_TIME_R].cap  |= SANE_CAP_INACTIVE;
5659 
5660   /* scan exposure time green */
5661   scanner->opt[OPT_SCAN_EXPOS_TIME_G].name  = SANE_NAME_SCAN_EXPOS_TIME_G;
5662   scanner->opt[OPT_SCAN_EXPOS_TIME_G].title = SANE_TITLE_SCAN_EXPOS_TIME_G;
5663   scanner->opt[OPT_SCAN_EXPOS_TIME_G].desc  = SANE_DESC_SCAN_EXPOS_TIME_G;
5664   scanner->opt[OPT_SCAN_EXPOS_TIME_G].type  = SANE_TYPE_INT;
5665   scanner->opt[OPT_SCAN_EXPOS_TIME_G].unit  = SANE_UNIT_MICROSECOND;
5666   scanner->opt[OPT_SCAN_EXPOS_TIME_G].constraint_type = SANE_CONSTRAINT_RANGE;
5667   scanner->opt[OPT_SCAN_EXPOS_TIME_G].constraint.range = &(scanner->exposure_time_range);
5668   scanner->val[OPT_SCAN_EXPOS_TIME_G].w     = scanner->device->inquiry_exposure_time_c_fb_def_g *
5669                                               scanner->device->inquiry_exposure_time_step_unit;
5670   scanner->opt[OPT_SCAN_EXPOS_TIME_G].cap  |= SANE_CAP_INACTIVE;
5671 
5672   /* scan exposure time blue */
5673   scanner->opt[OPT_SCAN_EXPOS_TIME_B].name  = SANE_NAME_SCAN_EXPOS_TIME_B;
5674   scanner->opt[OPT_SCAN_EXPOS_TIME_B].title = SANE_TITLE_SCAN_EXPOS_TIME_B;
5675   scanner->opt[OPT_SCAN_EXPOS_TIME_B].desc  = SANE_DESC_SCAN_EXPOS_TIME_B;
5676   scanner->opt[OPT_SCAN_EXPOS_TIME_B].type  = SANE_TYPE_INT;
5677   scanner->opt[OPT_SCAN_EXPOS_TIME_B].unit  = SANE_UNIT_MICROSECOND;
5678   scanner->opt[OPT_SCAN_EXPOS_TIME_B].constraint_type = SANE_CONSTRAINT_RANGE;
5679   scanner->opt[OPT_SCAN_EXPOS_TIME_B].constraint.range = &(scanner->exposure_time_range);
5680   scanner->val[OPT_SCAN_EXPOS_TIME_B].w     = scanner->device->inquiry_exposure_time_c_fb_def_b *
5681                                               scanner->device->inquiry_exposure_time_step_unit;
5682   scanner->opt[OPT_SCAN_EXPOS_TIME_B].cap  |= SANE_CAP_INACTIVE;
5683 
5684   if (scanner->device->inquiry_exposure_adj == 0)
5685   {
5686     scanner->opt[OPT_SELECT_EXPOSURE_TIME].cap   |= SANE_CAP_INACTIVE;
5687   }
5688 
5689 
5690   /* ------------------------------ */
5691 
5692 
5693   /* select calibration lamp density */
5694   scanner->opt[OPT_SELECT_LAMP_DENSITY].name  = SANE_NAME_SELECT_LAMP_DENSITY;
5695   scanner->opt[OPT_SELECT_LAMP_DENSITY].title = SANE_TITLE_SELECT_LAMP_DENSITY;
5696   scanner->opt[OPT_SELECT_LAMP_DENSITY].desc  = SANE_DESC_SELECT_LAMP_DENSITY;
5697   scanner->opt[OPT_SELECT_LAMP_DENSITY].type  = SANE_TYPE_BOOL;
5698   scanner->val[OPT_SELECT_LAMP_DENSITY].w     = SANE_FALSE;
5699 
5700   /* calibration lamp density */
5701   scanner->opt[OPT_CAL_LAMP_DEN].name  = SANE_NAME_CAL_LAMP_DEN;
5702   scanner->opt[OPT_CAL_LAMP_DEN].title = SANE_TITLE_CAL_LAMP_DEN;
5703   scanner->opt[OPT_CAL_LAMP_DEN].desc  = SANE_DESC_CAL_LAMP_DEN;
5704   scanner->opt[OPT_CAL_LAMP_DEN].type  = SANE_TYPE_FIXED;
5705   scanner->opt[OPT_CAL_LAMP_DEN].unit  = SANE_UNIT_PERCENT;
5706   scanner->opt[OPT_CAL_LAMP_DEN].constraint_type = SANE_CONSTRAINT_RANGE;
5707   scanner->opt[OPT_CAL_LAMP_DEN].constraint.range = &percentage_range_100;
5708   scanner->val[OPT_CAL_LAMP_DEN].w     = SANE_FIX(50);
5709   scanner->opt[OPT_CAL_LAMP_DEN].cap  |= SANE_CAP_INACTIVE;
5710 
5711   /* scan lamp density */
5712   scanner->opt[OPT_SCAN_LAMP_DEN].name  = SANE_NAME_SCAN_LAMP_DEN;
5713   scanner->opt[OPT_SCAN_LAMP_DEN].title = SANE_TITLE_SCAN_LAMP_DEN;
5714   scanner->opt[OPT_SCAN_LAMP_DEN].desc  = SANE_DESC_SCAN_LAMP_DEN;
5715   scanner->opt[OPT_SCAN_LAMP_DEN].type  = SANE_TYPE_FIXED;
5716   scanner->opt[OPT_SCAN_LAMP_DEN].unit  = SANE_UNIT_PERCENT;
5717   scanner->opt[OPT_SCAN_LAMP_DEN].constraint_type = SANE_CONSTRAINT_RANGE;
5718   scanner->opt[OPT_SCAN_LAMP_DEN].constraint.range = &percentage_range_100;
5719   scanner->val[OPT_SCAN_LAMP_DEN].w     = SANE_FIX(50);
5720   scanner->opt[OPT_SCAN_LAMP_DEN].cap  |= SANE_CAP_INACTIVE;
5721 
5722   if (scanner->device->inquiry_lamp_ctrl == 0)
5723   {
5724     scanner->opt[OPT_SELECT_LAMP_DENSITY].cap  |= SANE_CAP_INACTIVE;
5725   }
5726 
5727   /* ------------------------------ */
5728 
5729   /* disable pre focus */
5730   scanner->opt[OPT_DISABLE_PRE_FOCUS].name  = "disable-pre-focus";
5731   scanner->opt[OPT_DISABLE_PRE_FOCUS].title = SANE_I18N("Disable pre focus");
5732   scanner->opt[OPT_DISABLE_PRE_FOCUS].desc  = SANE_I18N("Do not calibrate focus");
5733   scanner->opt[OPT_DISABLE_PRE_FOCUS].type  = SANE_TYPE_BOOL;
5734   scanner->val[OPT_DISABLE_PRE_FOCUS].w     = SANE_FALSE;
5735 
5736   if (scanner->device->inquiry_manual_focus == 0)
5737   {
5738     scanner->opt[OPT_DISABLE_PRE_FOCUS].cap  |= SANE_CAP_INACTIVE;
5739   }
5740 
5741   /* manual pre focus */
5742   scanner->opt[OPT_MANUAL_PRE_FOCUS].name  = "manual-pre-focus";
5743   scanner->opt[OPT_MANUAL_PRE_FOCUS].title = SANE_I18N("Manual pre focus");
5744   scanner->opt[OPT_MANUAL_PRE_FOCUS].desc  = "";
5745   scanner->opt[OPT_MANUAL_PRE_FOCUS].type  = SANE_TYPE_BOOL;
5746   scanner->val[OPT_MANUAL_PRE_FOCUS].w     = SANE_FALSE;
5747 
5748   if (scanner->device->inquiry_manual_focus == 0)
5749   {
5750     scanner->opt[OPT_MANUAL_PRE_FOCUS].cap  |= SANE_CAP_INACTIVE;
5751   }
5752 
5753   /* fix focus position */
5754   scanner->opt[OPT_FIX_FOCUS_POSITION].name  = "fix-focus-position";
5755   scanner->opt[OPT_FIX_FOCUS_POSITION].title = SANE_I18N("Fix focus position");
5756   scanner->opt[OPT_FIX_FOCUS_POSITION].desc  = "";
5757   scanner->opt[OPT_FIX_FOCUS_POSITION].type  = SANE_TYPE_BOOL;
5758   scanner->val[OPT_FIX_FOCUS_POSITION].w     = SANE_FALSE;
5759 
5760   if (scanner->device->inquiry_manual_focus == 0)
5761   {
5762     scanner->opt[OPT_FIX_FOCUS_POSITION].cap  |= SANE_CAP_INACTIVE;
5763   }
5764 
5765   /* lens calibration in doc position */
5766   scanner->opt[OPT_LENS_CALIBRATION_DOC_POS].name  = "lens-calibration-in-doc-position";
5767   scanner->opt[OPT_LENS_CALIBRATION_DOC_POS].title = SANE_I18N("Lens calibration in doc position");
5768   scanner->opt[OPT_LENS_CALIBRATION_DOC_POS].desc  = SANE_I18N("Calibrate lens focus in document position");
5769   scanner->opt[OPT_LENS_CALIBRATION_DOC_POS].type  = SANE_TYPE_BOOL;
5770   scanner->val[OPT_LENS_CALIBRATION_DOC_POS].w     = SANE_FALSE;
5771 
5772   if (scanner->device->inquiry_lens_cal_in_doc_pos == 0)
5773   {
5774     scanner->opt[OPT_LENS_CALIBRATION_DOC_POS].cap  |= SANE_CAP_INACTIVE;
5775   }
5776 
5777   /* 0mm holder focus position */
5778   scanner->opt[OPT_HOLDER_FOCUS_POS_0MM].name  = "holder-focus-position-0mm";
5779   scanner->opt[OPT_HOLDER_FOCUS_POS_0MM].title = SANE_I18N("Holder focus position 0mm");
5780   scanner->opt[OPT_HOLDER_FOCUS_POS_0MM].desc  = SANE_I18N("Use 0mm holder focus position instead of 0.6mm");
5781   scanner->opt[OPT_HOLDER_FOCUS_POS_0MM].type  = SANE_TYPE_BOOL;
5782   scanner->val[OPT_HOLDER_FOCUS_POS_0MM].w     = SANE_FALSE;
5783 
5784   if (scanner->device->inquiry_sel_uta_lens_cal_pos == 0)
5785   {
5786     scanner->opt[OPT_HOLDER_FOCUS_POS_0MM].cap  |= SANE_CAP_INACTIVE;
5787   }
5788 
5789   /* ------------------------------ */
5790 
5791   /* lamp on */
5792   scanner->opt[OPT_LAMP_ON].name  = "lamp-on";
5793   scanner->opt[OPT_LAMP_ON].title = SANE_I18N("Lamp on");
5794   scanner->opt[OPT_LAMP_ON].desc  = SANE_I18N("Turn on scanner lamp");
5795   scanner->opt[OPT_LAMP_ON].type  = SANE_TYPE_BUTTON;
5796   scanner->opt[OPT_LAMP_ON].unit  = SANE_UNIT_NONE;
5797   scanner->opt[OPT_LAMP_ON].size  = 0;
5798   scanner->opt[OPT_LAMP_ON].constraint_type  = SANE_CONSTRAINT_NONE;
5799   scanner->val[OPT_LAMP_ON].w     = 0;
5800 
5801   if (!scanner->device->lamp_control_available)		/* lamp state can not be controlled by driver */
5802   {
5803     scanner->opt[OPT_LAMP_ON].cap  |= SANE_CAP_INACTIVE;
5804   }
5805 
5806   /* ------------------------------ */
5807 
5808   /* lamp off */
5809   scanner->opt[OPT_LAMP_OFF].name  = "lamp-off";
5810   scanner->opt[OPT_LAMP_OFF].title = SANE_I18N("Lamp off");
5811   scanner->opt[OPT_LAMP_OFF].desc  = SANE_I18N("Turn off scanner lamp");
5812   scanner->opt[OPT_LAMP_OFF].type  = SANE_TYPE_BUTTON;
5813   scanner->opt[OPT_LAMP_OFF].unit  = SANE_UNIT_NONE;
5814   scanner->opt[OPT_LAMP_OFF].size  = 0;
5815   scanner->opt[OPT_LAMP_OFF].constraint_type  = SANE_CONSTRAINT_NONE;
5816   scanner->val[OPT_LAMP_OFF].w     = 0;
5817 
5818   if (!scanner->device->lamp_control_available)		/* lamp state can not be controlled by driver */
5819   {
5820     scanner->opt[OPT_LAMP_OFF].cap  |= SANE_CAP_INACTIVE;
5821   }
5822 
5823   /* ------------------------------ */
5824 
5825   /* lamp off at exit */
5826   scanner->opt[OPT_LAMP_OFF_AT_EXIT].name  = "lamp-off-at-exit";
5827   scanner->opt[OPT_LAMP_OFF_AT_EXIT].title = SANE_I18N("Lamp off at exit");
5828   scanner->opt[OPT_LAMP_OFF_AT_EXIT].desc  = SANE_I18N("Turn off lamp when program exits");
5829   scanner->opt[OPT_LAMP_OFF_AT_EXIT].type  = SANE_TYPE_BOOL;
5830   scanner->val[OPT_LAMP_OFF_AT_EXIT].w     = SANE_FALSE;
5831 
5832   if (!scanner->device->lamp_control_available)		/* lamp state can not be controlled by driver */
5833   {
5834     scanner->opt[OPT_LAMP_OFF_AT_EXIT].cap  |= SANE_CAP_INACTIVE;
5835   }
5836 
5837   /* ------------------------------ */
5838 
5839   /* batch-scan-start */
5840   scanner->opt[OPT_BATCH_SCAN_START].name  = SANE_NAME_BATCH_SCAN_START;
5841   scanner->opt[OPT_BATCH_SCAN_START].title = SANE_TITLE_BATCH_SCAN_START;
5842   scanner->opt[OPT_BATCH_SCAN_START].desc  = SANE_DESC_BATCH_SCAN_START;
5843   scanner->opt[OPT_BATCH_SCAN_START].type  = SANE_TYPE_BOOL;
5844   scanner->val[OPT_BATCH_SCAN_START].w     = SANE_FALSE;
5845 
5846   /* batch-scan-loop */
5847   scanner->opt[OPT_BATCH_SCAN_LOOP].name  = SANE_NAME_BATCH_SCAN_LOOP;
5848   scanner->opt[OPT_BATCH_SCAN_LOOP].title = SANE_TITLE_BATCH_SCAN_LOOP;
5849   scanner->opt[OPT_BATCH_SCAN_LOOP].desc  = SANE_DESC_BATCH_SCAN_LOOP;
5850   scanner->opt[OPT_BATCH_SCAN_LOOP].type  = SANE_TYPE_BOOL;
5851   scanner->val[OPT_BATCH_SCAN_LOOP].w     = SANE_FALSE;
5852 
5853   /* batch-scan-end */
5854   scanner->opt[OPT_BATCH_SCAN_END].name  = SANE_NAME_BATCH_SCAN_END;
5855   scanner->opt[OPT_BATCH_SCAN_END].title = SANE_TITLE_BATCH_SCAN_END;
5856   scanner->opt[OPT_BATCH_SCAN_END].desc  = SANE_DESC_BATCH_SCAN_END;
5857   scanner->opt[OPT_BATCH_SCAN_END].type  = SANE_TYPE_BOOL;
5858   scanner->val[OPT_BATCH_SCAN_END].w     = SANE_FALSE;
5859 
5860   /* batch-scan-next-y */
5861   scanner->opt[OPT_BATCH_NEXT_TL_Y].name  = SANE_NAME_BATCH_NEXT_TL_Y;
5862   scanner->opt[OPT_BATCH_NEXT_TL_Y].title = SANE_TITLE_BATCH_NEXT_TL_Y;
5863   scanner->opt[OPT_BATCH_NEXT_TL_Y].desc  = SANE_DESC_BATCH_NEXT_TL_Y;
5864   scanner->opt[OPT_BATCH_NEXT_TL_Y].type  = SANE_TYPE_FIXED;
5865   scanner->opt[OPT_BATCH_NEXT_TL_Y].unit  = SANE_UNIT_MM;
5866   scanner->opt[OPT_BATCH_NEXT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
5867   scanner->opt[OPT_BATCH_NEXT_TL_Y].constraint.range = &(scanner->device->y_range);
5868   scanner->val[OPT_BATCH_NEXT_TL_Y].w     = 0xFFFF; /* mark value as not touched */
5869 
5870   if (scanner->device->inquiry_batch_scan == 0)
5871   {
5872     scanner->opt[OPT_BATCH_SCAN_START].cap  |= SANE_CAP_INACTIVE;
5873     scanner->opt[OPT_BATCH_SCAN_LOOP].cap   |= SANE_CAP_INACTIVE;
5874     scanner->opt[OPT_BATCH_SCAN_END].cap    |= SANE_CAP_INACTIVE;
5875     scanner->opt[OPT_BATCH_NEXT_TL_Y].cap      |= SANE_CAP_INACTIVE;
5876   }
5877 
5878   /* ------------------------------ */
5879 
5880 #ifdef UMAX_CALIBRATION_MODE_SELECTABLE
5881   /* calibration mode */
5882   scanner->opt[OPT_CALIB_MODE].name  = "calibrationmode";
5883   scanner->opt[OPT_CALIB_MODE].title = SANE_I18N("Calibration mode");
5884   scanner->opt[OPT_CALIB_MODE].desc  = SANE_I18N("Define calibration mode");
5885   scanner->opt[OPT_CALIB_MODE].type  = SANE_TYPE_STRING;
5886   scanner->opt[OPT_CALIB_MODE].size  = max_string_size(calibration_list);
5887   scanner->opt[OPT_CALIB_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
5888   scanner->opt[OPT_CALIB_MODE].constraint.string_list = calibration_list;
5889   scanner->val[OPT_CALIB_MODE].s     = (SANE_Char*)strdup(calibration_list[0]);
5890 
5891   if (scanner->device->inquiry_calibration == 0)
5892   {
5893     scanner->opt[OPT_CALIB_MODE].cap  |= SANE_CAP_INACTIVE;
5894   }
5895 #endif
5896 
5897   /* preview */
5898   scanner->opt[OPT_PREVIEW].name  = SANE_NAME_PREVIEW;
5899   scanner->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
5900   scanner->opt[OPT_PREVIEW].desc  = SANE_DESC_PREVIEW;
5901   scanner->opt[OPT_PREVIEW].type  = SANE_TYPE_BOOL;
5902   scanner->opt[OPT_PREVIEW].cap   = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
5903   scanner->val[OPT_PREVIEW].w     = SANE_FALSE;
5904 
5905   sane_control_option(scanner, OPT_MODE, SANE_ACTION_SET_VALUE,
5906                       (SANE_String *) scan_mode_list[scan_modes], NULL );
5907 
5908  return SANE_STATUS_GOOD;
5909 }
5910 
5911 
5912 /* ------------------------------------------------------------ ATTACH ONE SCSI ----------------------------- */
5913 
5914 /* callback function for sanei_config_attach_matching_devices(dev_name, attach_one_scsi) */
attach_one_scsi(const char *name)5915 static SANE_Status attach_one_scsi(const char *name)
5916 {
5917   attach_scanner(name, 0, SANE_UMAX_SCSI);
5918  return SANE_STATUS_GOOD;
5919 }
5920 
5921 /* ------------------------------------------------------------ ATTACH ONE USB ------------------------------ */
5922 
5923 /* callback function for sanei_usb_attach_matching_devices(dev_name, attach_one_usb) */
attach_one_usb(const char *name)5924 static SANE_Status attach_one_usb(const char *name)
5925 {
5926   attach_scanner(name, 0, SANE_UMAX_USB);
5927  return SANE_STATUS_GOOD;
5928 }
5929 
5930 /* ------------------------------------------------------------ UMAX TEST CONFIGURE OPTION ------------------ */
5931 
umax_test_configure_option(const char *option_str, char *test_name, int *test_value, int test_min, int test_max)5932 static SANE_Status umax_test_configure_option(const char *option_str, char *test_name, int *test_value, int test_min, int test_max)
5933 /* returns with 1 if option was found, 0 if option was not found */
5934 {
5935  const char *value_str;
5936  char *end_ptr;
5937  int value;
5938 
5939   if (strncmp(option_str, test_name, strlen(test_name)) == 0)
5940   {
5941     value_str = sanei_config_skip_whitespace(option_str+strlen(test_name));
5942 
5943     errno = 0;
5944     value = strtol(value_str, &end_ptr, 10);
5945     if (end_ptr == value_str || errno)
5946     {
5947       DBG(DBG_error, "ERROR: invalid value \"%s\" for option %s in %s\n", value_str, test_name, UMAX_CONFIG_FILE);
5948     }
5949     else
5950     {
5951       if (value < test_min)
5952       {
5953         DBG(DBG_error, "ERROR: value \"%d\" is too small for option %s in %s\n", value, test_name, UMAX_CONFIG_FILE);
5954         value = test_min;
5955       }
5956       else if (value > test_max)
5957       {
5958         DBG(DBG_error, "ERROR: value \"%d\" is too large for option %s in %s\n", value, test_name, UMAX_CONFIG_FILE);
5959         value = test_max;
5960       }
5961 
5962       *test_value = value;
5963 
5964       DBG(DBG_info, "option %s = %d\n", test_name, *test_value);
5965     }
5966     return 1;
5967   }
5968  return 0;
5969 }
5970 
5971 /* ------------------------------------------------------------ SANE INIT ---------------------------------- */
5972 
5973 
sane_init(SANE_Int *version_code, SANE_Auth_Callback authorize)5974 SANE_Status sane_init(SANE_Int *version_code, SANE_Auth_Callback authorize)
5975 {
5976  char config_line[PATH_MAX];
5977  const char *option_str;
5978  size_t len;
5979  FILE *fp;
5980 
5981   /* we have to initialize these global variables here because sane_init can be called several times */
5982   num_devices  = 0;
5983   devlist      = NULL;
5984   first_dev    = NULL;
5985   first_handle = NULL;
5986 
5987   DBG_INIT();
5988 
5989   DBG(DBG_sane_init,"sane_init\n");
5990   DBG(DBG_error,"This is sane-umax version %d.%d build %d\n", SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
5991 #ifdef UMAX_ENABLE_USB
5992   DBG(DBG_error,"compiled with USB support for Astra 2200\n");
5993 #else
5994   DBG(DBG_error,"no USB support for Astra 2200\n");
5995 #endif
5996   DBG(DBG_error,"(C) 1997-2002 by Oliver Rauch\n");
5997   DBG(DBG_error,"EMAIL: Oliver.Rauch@rauch-domain.de\n");
5998 
5999   if (version_code)
6000   {
6001     *version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
6002   }
6003 
6004   frontend_authorize_callback = authorize; /* store frontend authorize callback */
6005 
6006   sanei_thread_init(); /* must be called before any other sanei_thread call */
6007 
6008 #ifdef UMAX_ENABLE_USB
6009   sanei_usb_init();
6010   sanei_pv8630_init();
6011 #endif
6012 
6013   fp = sanei_config_open(UMAX_CONFIG_FILE);
6014   if (!fp)
6015   {
6016     /* no config-file: try /dev/scanner and /dev/usbscanner. */
6017     attach_scanner("/dev/scanner",    0, SANE_UMAX_SCSI);
6018 #ifdef UMAX_ENABLE_USB
6019     attach_scanner("/dev/usbscanner", 0, SANE_UMAX_USB);
6020 #endif
6021    return SANE_STATUS_GOOD;
6022   }
6023 
6024   DBG(DBG_info, "reading configure file %s\n", UMAX_CONFIG_FILE);
6025 
6026   while(sanei_config_read(config_line, sizeof(config_line), fp))
6027   {
6028     if (config_line[0] == '#')
6029     {
6030       continue; /* ignore line comments */
6031     }
6032 
6033     if (strncmp(config_line, "option", 6) == 0)
6034     {
6035       option_str = sanei_config_skip_whitespace(config_line+6);
6036 
6037       if      (umax_test_configure_option(option_str, "scsi-maxqueue",                  &umax_scsi_maxqueue, 1, SANE_UMAX_SCSI_MAXQUEUE));
6038       else if (umax_test_configure_option(option_str, "scsi-buffer-size-min",           &umax_scsi_buffer_size_min,   4096, 1048576));
6039       else if (umax_test_configure_option(option_str, "scsi-buffer-size-max",           &umax_scsi_buffer_size_max,   4096, 1048576));
6040       else if (umax_test_configure_option(option_str, "preview-lines",                  &umax_preview_lines,             1,   65535));
6041       else if (umax_test_configure_option(option_str, "scan-lines",                     &umax_scan_lines,                1,   65535));
6042       else if (umax_test_configure_option(option_str, "handle-bad-sense-error",         &umax_handle_bad_sense_error,    0,   3));
6043       else if (umax_test_configure_option(option_str, "execute-request-sense",          &umax_execute_request_sense,     0,   1));
6044       else if (umax_test_configure_option(option_str, "force-preview-bit-rgb",          &umax_force_preview_bit_rgb,     0,   1));
6045       else if (umax_test_configure_option(option_str, "slow-speed",                     &umax_slow,                     -1,   1));
6046       else if (umax_test_configure_option(option_str, "care-about-smearing",            &umax_smear,                    -1,   1));
6047       else if (umax_test_configure_option(option_str, "calibration-full-ccd",           &umax_calibration_area,         -1,   1));
6048       else if (umax_test_configure_option(option_str, "calibration-width-offset-batch", &umax_calibration_width_offset_batch, -99999, 65535));
6049       else if (umax_test_configure_option(option_str, "calibration-width-offset",       &umax_calibration_width_offset, -99999, 65535));
6050       else if (umax_test_configure_option(option_str, "calibration-bytes-pixel",        &umax_calibration_bytespp,      -1,   2));
6051       else if (umax_test_configure_option(option_str, "exposure-time-rgb-bind",         &umax_exposure_time_rgb_bind,   -1,   1));
6052       else if (umax_test_configure_option(option_str, "invert-shading-data",            &umax_invert_shading_data,      -1,   1));
6053       else if (umax_test_configure_option(option_str, "lamp-control-available",         &umax_lamp_control_available,    0,   1));
6054       else if (umax_test_configure_option(option_str, "gamma-lsb-padded",               &umax_gamma_lsb_padded,         -1,   1));
6055       else if (umax_test_configure_option(option_str, "connection-type",                &umax_connection_type,           1,   2));
6056       else
6057       {
6058         DBG(DBG_error,"ERROR: unknown option \"%s\" in %s\n", option_str, UMAX_CONFIG_FILE);
6059       }
6060       continue;
6061     }
6062     else if (strncmp(config_line, "scsi", 4) == 0)
6063     {
6064       DBG(DBG_info,"sanei_config_attach_matching_devices(%s)\n", config_line);
6065       sanei_config_attach_matching_devices(config_line, attach_one_scsi);
6066       continue;
6067     }
6068     else if (strncmp(config_line, "usb", 3) == 0)
6069     {
6070 #ifdef UMAX_ENABLE_USB
6071       DBG(DBG_info,"sanei_usb_attach_matching_devices(%s)\n", config_line);
6072       sanei_usb_attach_matching_devices(config_line, attach_one_usb);
6073 #else
6074       DBG(DBG_info,"USB not supported, ignoring config line: %s\n", config_line);
6075 #endif
6076       continue;
6077     }
6078 
6079     len = strlen(config_line);
6080 
6081     if (!len) /* ignore empty lines */
6082     {
6083       continue;
6084     }
6085 
6086     /* umax_connection_type is set by umax.conf: 1=scsi, 2=usb */
6087     attach_scanner(config_line, 0, umax_connection_type); /* try to open as devicename */
6088   }
6089 
6090   DBG(DBG_info, "finished reading configure file\n");
6091 
6092   fclose(fp);
6093 
6094  return SANE_STATUS_GOOD;
6095 }
6096 
6097 
6098 /* ------------------------------------------------------------ SANE EXIT ---------------------------------- */
6099 
6100 
sane_exit(void)6101 void sane_exit(void)
6102 {
6103  Umax_Device *dev, *next;
6104 
6105   DBG(DBG_sane_init,"sane_exit\n");
6106 
6107   for (dev = first_dev; dev; dev = next)
6108   {
6109     next = dev->next;
6110     free(dev->devicename);
6111     free(dev);
6112   }
6113 
6114   if (devlist)
6115   {
6116     free(devlist);
6117   }
6118 }
6119 
6120 
6121 /* ------------------------------------------------------------ SANE GET DEVICES --------------------------- */
6122 
6123 
sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)6124 SANE_Status sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)
6125 {
6126  Umax_Device *dev;
6127  int i;
6128 
6129   DBG(DBG_sane_init,"sane_get_devices(local_only = %d)\n", local_only);
6130 
6131   if (devlist)
6132   {
6133     free(devlist);
6134   }
6135 
6136   devlist = malloc((num_devices + 1) * sizeof (devlist[0]));
6137   if (!devlist)
6138   {
6139     return SANE_STATUS_NO_MEM;
6140   }
6141 
6142   i = 0;
6143 
6144   for (dev = first_dev; i < num_devices; dev = dev->next)
6145   {
6146     devlist[i++] = &dev->sane;
6147   }
6148 
6149   devlist[i++] = 0;
6150 
6151   *device_list = devlist;
6152 
6153  return SANE_STATUS_GOOD;
6154 }
6155 
6156 
6157 /* ------------------------------------------------------------ SANE OPEN ---------------------------------- */
6158 
6159 
sane_open(SANE_String_Const devicename, SANE_Handle *handle)6160 SANE_Status sane_open(SANE_String_Const devicename, SANE_Handle *handle)
6161 {
6162  Umax_Device *dev;
6163  SANE_Status status;
6164  Umax_Scanner *scanner;
6165  unsigned int i, j;
6166 
6167   DBG(DBG_sane_init,"sane_open\n");
6168 
6169   if (devicename[0])   /* search for devicename */
6170   {
6171     DBG(DBG_sane_info,"sane_open: devicename=%s\n", devicename);
6172 
6173     for (dev = first_dev; dev; dev = dev->next)
6174     {
6175       if (strcmp(dev->sane.name, devicename) == 0)
6176       {
6177         break; /* device found, exit for loop */
6178       }
6179     }
6180 
6181     if (!dev) /* no device found */
6182     {
6183       status = attach_scanner(devicename, &dev, 0 /* connection-type not known */); /* try to open devicename and set dev */
6184       if (status != SANE_STATUS_GOOD)
6185       {
6186         return status;
6187       }
6188     }
6189   }
6190   else
6191   {
6192     DBG(DBG_sane_info,"sane_open: no devicename, opening first device\n");
6193     dev = first_dev; 							/* empty devicename -> use first device */
6194   }
6195 
6196   if (!dev) /* no device found */
6197   {
6198     return SANE_STATUS_INVAL;
6199   }
6200 
6201   scanner = malloc(sizeof (*scanner));
6202   if (!scanner)
6203   {
6204     return SANE_STATUS_NO_MEM;
6205   }
6206 
6207   memset(scanner, 0, sizeof (*scanner));
6208 
6209   scanner->device = dev;
6210 
6211   if (scanner->device->inquiry_GIB & 32)
6212   {
6213     scanner->gamma_length = 65536;							    /* 16 bits input */
6214     DBG(DBG_sane_info, "Using 16 bits for gamma input\n");
6215   }
6216   else if (scanner->device->inquiry_GIB & 16)
6217   {
6218     scanner->gamma_length = 16384;							    /* 14 bits input */
6219     DBG(DBG_sane_info, "Using 14 bits for gamma input\n");
6220   }
6221   else if (scanner->device->inquiry_GIB & 8)
6222   {
6223     scanner->gamma_length = 4096;							    /* 12 bits input */
6224     DBG(DBG_sane_info, "Using 12 bits for gamma input\n");
6225   }
6226   else if (scanner->device->inquiry_GIB & 4)
6227   {
6228     scanner->gamma_length = 1024;							    /* 10 bits input */
6229     DBG(DBG_sane_info, "Using 10 bits for gamma input\n");
6230   }
6231   else if (scanner->device->inquiry_GIB & 2)
6232   {
6233     scanner->gamma_length = 512;							     /* 9 bits input */
6234     DBG(DBG_sane_info, "Using 9 bits for gamma input\n");
6235   }
6236   else
6237   {
6238     scanner->gamma_length = 256;							     /* 8 bits input */
6239     DBG(DBG_sane_info, "Using 8 bits for gamma input\n");
6240   }
6241 
6242   scanner->output_bytes = 1;								    /* 8 bits output */
6243 
6244   scanner->gamma_range.min   = 0;
6245   scanner->gamma_range.max   = scanner->gamma_length-1;
6246   scanner->gamma_range.quant = 0;
6247 
6248   scanner->gamma_table[0] = (SANE_Int *) malloc(scanner->gamma_length * sizeof(SANE_Int));
6249   scanner->gamma_table[1] = (SANE_Int *) malloc(scanner->gamma_length * sizeof(SANE_Int));
6250   scanner->gamma_table[2] = (SANE_Int *) malloc(scanner->gamma_length * sizeof(SANE_Int));
6251   scanner->gamma_table[3] = (SANE_Int *) malloc(scanner->gamma_length * sizeof(SANE_Int));
6252 
6253   for (j = 0; j < scanner->gamma_length; ++j)			     /* gamma_table[0] : converts GIB to GOB */
6254   {
6255     scanner->gamma_table[0][j] = j * scanner->device->max_value / scanner->gamma_length;
6256   }
6257 
6258   for (i = 1; i < 4; ++i)			 /* gamma_table[1,2,3] : doesn't convert anything (GIB->GIB) */
6259   {
6260     for (j = 0; j < scanner->gamma_length; ++j)
6261     {
6262       scanner->gamma_table[i][j] = j;
6263     }
6264   }
6265 
6266   scanner->exposure_time_range.min   = scanner->device->inquiry_exposure_time_c_min *
6267                                        scanner->device->inquiry_exposure_time_step_unit;
6268   scanner->exposure_time_range.quant = scanner->device->inquiry_exposure_time_step_unit;
6269   scanner->exposure_time_range.max   = scanner->device->inquiry_exposure_time_max *
6270                                        scanner->device->inquiry_exposure_time_step_unit;
6271 
6272   init_options(scanner);
6273 
6274   scanner->next = first_handle;			    /* insert newly opened handle into list of open handles: */
6275   first_handle = scanner;
6276 
6277   *handle = scanner;
6278  return SANE_STATUS_GOOD;
6279 }
6280 
6281 
6282 /* ------------------------------------------------------------ SANE CLOSE --------------------------------- */
6283 
6284 
sane_close(SANE_Handle handle)6285 void sane_close(SANE_Handle handle)
6286 {
6287  Umax_Scanner *prev, *scanner;
6288 
6289   DBG(DBG_sane_init,"sane_close\n");
6290 
6291   if (!first_handle)
6292   {
6293     DBG(DBG_error, "ERROR: sane_close: no handles opened\n");
6294     return;
6295   }
6296 
6297 								 /* remove handle from list of open handles: */
6298   prev = 0;
6299 
6300   for (scanner = first_handle; scanner; scanner = scanner->next)
6301   {
6302     if (scanner == handle)
6303     {
6304       break;
6305     }
6306 
6307     prev = scanner;
6308   }
6309 
6310   if (!scanner)
6311   {
6312     DBG(DBG_error, "ERROR: sane_close: invalid handle %p\n", handle);
6313     return;								 /* oops, not a handle we know about */
6314   }
6315 
6316   if (scanner->scanning)						      /* stop scan if still scanning */
6317   {
6318     do_cancel(handle);
6319   }
6320 
6321   if (scanner->device->lamp_control_available)			   /* lamp state can be controlled by driver */
6322   {
6323     if (scanner->val[OPT_LAMP_OFF_AT_EXIT].w)			      /* turn off scanner lamp on sane_close */
6324     {
6325       umax_set_lamp_status(handle, 0 /* lamp off */);
6326     }
6327   }
6328 
6329   if (prev)
6330   {
6331     prev->next = scanner->next;
6332   }
6333   else
6334   {
6335     first_handle = scanner->next;
6336   }
6337 
6338   free(scanner->gamma_table[0]);						 /* free custom gamma tables */
6339   free(scanner->gamma_table[1]);
6340   free(scanner->gamma_table[2]);
6341   free(scanner->gamma_table[3]);
6342 
6343   free(scanner->device->buffer[0]);			  /* free buffer allocated by umax_initialize_values */
6344   scanner->device->buffer[0]  = NULL;
6345   scanner->device->bufsize = 0;
6346 
6347   free(scanner);									     /* free scanner */
6348 }
6349 
6350 
6351 /* ------------------------------------------------------------ SANE GET OPTION DESCRIPTOR ----------------- */
6352 
6353 
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)6354 const SANE_Option_Descriptor *sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)
6355 {
6356  Umax_Scanner *scanner = handle;
6357 
6358   DBG(DBG_sane_option,"sane_get_option_descriptor %d\n", option);
6359 
6360   if ((unsigned) option >= NUM_OPTIONS)
6361   {
6362     return 0;
6363   }
6364 
6365  return scanner->opt + option;
6366 }
6367 
6368 /* ------------------------------------------------------------ UMAX SET MAX GEOMETRY ---------------------- */
6369 
umax_set_max_geometry(Umax_Scanner *scanner)6370 static void umax_set_max_geometry(Umax_Scanner *scanner)
6371 {
6372 
6373   if (scanner->val[OPT_DOR].w)
6374   {
6375     scanner->device->x_range.min = SANE_FIX(scanner->device->inquiry_dor_x_off * MM_PER_INCH);
6376     scanner->device->x_range.max = SANE_FIX( (scanner->device->inquiry_dor_x_off + scanner->device->inquiry_dor_width)  * MM_PER_INCH);
6377     scanner->device->y_range.min = SANE_FIX(scanner->device->inquiry_dor_y_off * MM_PER_INCH);
6378     scanner->device->y_range.max = SANE_FIX( (scanner->device->inquiry_dor_y_off + scanner->device->inquiry_dor_length) * MM_PER_INCH);
6379 
6380     scanner->device->x_dpi_range.max = SANE_FIX(scanner->device->inquiry_dor_x_res);
6381     scanner->device->y_dpi_range.max = SANE_FIX(scanner->device->inquiry_dor_y_res);
6382   }
6383   else if ( (strcmp(scanner->val[OPT_SOURCE].s, FLB_STR) == 0) || (strcmp(scanner->val[OPT_SOURCE].s, ADF_STR) == 0) )
6384   {
6385     scanner->device->x_range.min = 0;
6386     scanner->device->x_range.max = SANE_FIX(scanner->device->inquiry_fb_width  * MM_PER_INCH);
6387     scanner->device->y_range.min = 0;
6388     scanner->device->y_range.max = SANE_FIX(scanner->device->inquiry_fb_length * MM_PER_INCH);
6389 
6390     scanner->device->x_dpi_range.max = SANE_FIX(scanner->device->inquiry_x_res);
6391     scanner->device->y_dpi_range.max = SANE_FIX(scanner->device->inquiry_y_res);
6392   }
6393   else if (strcmp(scanner->val[OPT_SOURCE].s, UTA_STR) == 0)
6394   {
6395     scanner->device->x_range.min = SANE_FIX(scanner->device->inquiry_uta_x_off  * MM_PER_INCH);
6396     scanner->device->x_range.max = SANE_FIX( (scanner->device->inquiry_uta_x_off + scanner->device->inquiry_uta_width) * MM_PER_INCH);
6397     scanner->device->y_range.min = SANE_FIX(scanner->device->inquiry_uta_y_off  * MM_PER_INCH);
6398     scanner->device->y_range.max = SANE_FIX( ( scanner->device->inquiry_uta_y_off + scanner->device->inquiry_uta_length) * MM_PER_INCH);
6399 
6400     scanner->device->x_dpi_range.max = SANE_FIX(scanner->device->inquiry_x_res);
6401     scanner->device->y_dpi_range.max = SANE_FIX(scanner->device->inquiry_y_res);
6402   }
6403 
6404   DBG(DBG_info,"x_range     = [%f .. %f]\n", SANE_UNFIX(scanner->device->x_range.min), SANE_UNFIX(scanner->device->x_range.max));
6405   DBG(DBG_info,"y_range     = [%f .. %f]\n", SANE_UNFIX(scanner->device->y_range.min), SANE_UNFIX(scanner->device->y_range.max));
6406   DBG(DBG_info,"x_dpi_range = [1 .. %f]\n", SANE_UNFIX(scanner->device->x_dpi_range.max));
6407   DBG(DBG_info,"y_dpi_range = [1 .. %f]\n", SANE_UNFIX(scanner->device->y_dpi_range.max));
6408 
6409   /* make sure geometry selection is in bounds */
6410 
6411   if ( scanner->val[OPT_TL_X].w < scanner->device->x_range.min)
6412   {
6413     scanner->val[OPT_TL_X].w = scanner->device->x_range.min;
6414   }
6415 
6416   if (scanner->val[OPT_TL_Y].w < scanner->device->y_range.min)
6417   {
6418     scanner->val[OPT_TL_Y].w = scanner->device->y_range.min;
6419   }
6420 
6421   if ( scanner->val[OPT_BR_X].w > scanner->device->x_range.max)
6422   {
6423     scanner->val[OPT_BR_X].w = scanner->device->x_range.max;
6424   }
6425 
6426   if (scanner->val[OPT_BR_Y].w > scanner->device->y_range.max)
6427   {
6428     scanner->val[OPT_BR_Y].w = scanner->device->y_range.max;
6429   }
6430 }
6431 
6432 /* ------------------------------------------------------------ SANE CONTROL OPTION ------------------------ */
6433 
6434 
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int *info)6435 SANE_Status sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action,
6436                                 void *val, SANE_Int *info)
6437 {
6438  Umax_Scanner *scanner = handle;
6439  SANE_Status status;
6440  SANE_Word w, cap;
6441  SANE_String_Const name;
6442 
6443   if (info)
6444   {
6445     *info = 0;
6446   }
6447 
6448   if (scanner->scanning)
6449   {
6450     return SANE_STATUS_DEVICE_BUSY;
6451   }
6452 
6453   if ((unsigned) option >= NUM_OPTIONS)
6454   {
6455     return SANE_STATUS_INVAL;
6456   }
6457 
6458   cap = scanner->opt[option].cap;
6459   if (!SANE_OPTION_IS_ACTIVE (cap))
6460   {
6461     return SANE_STATUS_INVAL;
6462   }
6463 
6464   name = scanner->opt[option].name;
6465   if (!name)
6466   {
6467     name = "(no name)";
6468   }
6469 
6470   if (action == SANE_ACTION_GET_VALUE)
6471   {
6472     DBG(DBG_sane_option,"get %s [#%d]\n", name, option);
6473 
6474     switch (option)
6475     {
6476        /* word options: */
6477       case OPT_NUM_OPTS:
6478       case OPT_RESOLUTION_BIND:
6479       case OPT_X_RESOLUTION:
6480       case OPT_Y_RESOLUTION:
6481       case OPT_TL_X:
6482       case OPT_TL_Y:
6483       case OPT_BR_X:
6484       case OPT_BR_Y:
6485       case OPT_PREVIEW:
6486       case OPT_BIT_DEPTH:
6487       case OPT_NEGATIVE:
6488       case OPT_BATCH_SCAN_START:
6489       case OPT_BATCH_SCAN_LOOP:
6490       case OPT_BATCH_SCAN_END:
6491       case OPT_BATCH_NEXT_TL_Y:
6492       case OPT_QUALITY:
6493       case OPT_DOR:
6494       case OPT_WARMUP:
6495       case OPT_RGB_BIND:
6496       case OPT_ANALOG_GAMMA:
6497       case OPT_ANALOG_GAMMA_R:
6498       case OPT_ANALOG_GAMMA_G:
6499       case OPT_ANALOG_GAMMA_B:
6500       case OPT_BRIGHTNESS:
6501       case OPT_CONTRAST:
6502       case OPT_THRESHOLD:
6503       case OPT_HIGHLIGHT:
6504       case OPT_HIGHLIGHT_R:
6505       case OPT_HIGHLIGHT_G:
6506       case OPT_HIGHLIGHT_B:
6507       case OPT_SHADOW:
6508       case OPT_SHADOW_R:
6509       case OPT_SHADOW_G:
6510       case OPT_SHADOW_B:
6511       case OPT_CUSTOM_GAMMA:
6512       case OPT_HALFTONE_DIMENSION:
6513       case OPT_SELECT_EXPOSURE_TIME:
6514       case OPT_SELECT_CAL_EXPOSURE_TIME:
6515       case OPT_CAL_EXPOS_TIME:
6516       case OPT_CAL_EXPOS_TIME_R:
6517       case OPT_CAL_EXPOS_TIME_G:
6518       case OPT_CAL_EXPOS_TIME_B:
6519       case OPT_SCAN_EXPOS_TIME:
6520       case OPT_SCAN_EXPOS_TIME_R:
6521       case OPT_SCAN_EXPOS_TIME_G:
6522       case OPT_SCAN_EXPOS_TIME_B:
6523       case OPT_CAL_LAMP_DEN:
6524       case OPT_SCAN_LAMP_DEN:
6525       case OPT_DISABLE_PRE_FOCUS:
6526       case OPT_MANUAL_PRE_FOCUS:
6527       case OPT_FIX_FOCUS_POSITION:
6528       case OPT_LENS_CALIBRATION_DOC_POS:
6529       case OPT_HOLDER_FOCUS_POS_0MM:
6530       case OPT_LAMP_OFF_AT_EXIT:
6531       case OPT_SELECT_LAMP_DENSITY:
6532         *(SANE_Word *) val = scanner->val[option].w;
6533        return SANE_STATUS_GOOD;
6534 
6535       /* word-array options: */
6536       case OPT_GAMMA_VECTOR:
6537       case OPT_GAMMA_VECTOR_R:
6538       case OPT_GAMMA_VECTOR_G:
6539       case OPT_GAMMA_VECTOR_B:
6540       case OPT_HALFTONE_PATTERN:
6541         memcpy (val, scanner->val[option].wa, scanner->opt[option].size);
6542        return SANE_STATUS_GOOD;
6543 
6544       /* string options: */
6545       case OPT_SOURCE:
6546       /* fall through */
6547       case OPT_MODE:
6548       /* fall through */
6549 #ifdef UMAX_CALIBRATION_MODE_SELECTABLE
6550       case OPT_CALIB_MODE:
6551       /* fall through */
6552 #endif
6553         strcpy (val, scanner->val[option].s);
6554        return SANE_STATUS_GOOD;
6555     }
6556   }
6557   else if (action == SANE_ACTION_SET_VALUE)
6558   {
6559     switch (scanner->opt[option].type)
6560     {
6561       case SANE_TYPE_INT:
6562         DBG(DBG_sane_option, "set %s [#%d] to %d\n", name, option, *(SANE_Word *) val);
6563        break;
6564 
6565       case SANE_TYPE_FIXED:
6566         DBG(DBG_sane_option, "set %s [#%d] to %f\n", name, option, SANE_UNFIX(*(SANE_Word *) val));
6567        break;
6568 
6569       case SANE_TYPE_STRING:
6570         DBG(DBG_sane_option, "set %s [#%d] to %s\n", name, option, (char *) val);
6571        break;
6572 
6573       case SANE_TYPE_BOOL:
6574         DBG(DBG_sane_option, "set %s [#%d] to %d\n", name, option, *(SANE_Word *) val);
6575        break;
6576 
6577       default:
6578         DBG(DBG_sane_option, "set %s [#%d]\n", name, option);
6579     }
6580 
6581     if (!SANE_OPTION_IS_SETTABLE(cap))
6582     {
6583       DBG(DBG_error, "could not set option, not settable\n");
6584      return SANE_STATUS_INVAL;
6585     }
6586 
6587     status = sanei_constrain_value(scanner->opt+option, val, info);
6588     if (status != SANE_STATUS_GOOD)
6589     {
6590       DBG(DBG_error, "could not set option, invalid value\n");
6591      return status;
6592     }
6593 
6594     switch (option)
6595     {
6596       /* (mostly) side-effect-free word options: */
6597       case OPT_X_RESOLUTION:
6598       case OPT_Y_RESOLUTION:
6599       case OPT_TL_X:
6600       case OPT_TL_Y:
6601       case OPT_BR_X:
6602       case OPT_BR_Y:
6603         if (info)
6604         {
6605           *info |= SANE_INFO_RELOAD_PARAMS;
6606         }
6607         /* fall through */
6608       case OPT_NUM_OPTS:
6609       case OPT_NEGATIVE:
6610       case OPT_BATCH_SCAN_START:
6611       case OPT_BATCH_SCAN_LOOP:
6612       case OPT_BATCH_SCAN_END:
6613       case OPT_BATCH_NEXT_TL_Y:
6614       case OPT_QUALITY:
6615       case OPT_WARMUP:
6616       case OPT_PREVIEW:
6617       case OPT_ANALOG_GAMMA:
6618       case OPT_ANALOG_GAMMA_R:
6619       case OPT_ANALOG_GAMMA_G:
6620       case OPT_ANALOG_GAMMA_B:
6621       case OPT_BRIGHTNESS:
6622       case OPT_CONTRAST:
6623       case OPT_THRESHOLD:
6624       case OPT_HIGHLIGHT:
6625       case OPT_HIGHLIGHT_R:
6626       case OPT_HIGHLIGHT_G:
6627       case OPT_HIGHLIGHT_B:
6628       case OPT_SHADOW:
6629       case OPT_SHADOW_R:
6630       case OPT_SHADOW_G:
6631       case OPT_SHADOW_B:
6632       case OPT_CAL_EXPOS_TIME:
6633       case OPT_CAL_EXPOS_TIME_R:
6634       case OPT_CAL_EXPOS_TIME_G:
6635       case OPT_CAL_EXPOS_TIME_B:
6636       case OPT_SCAN_EXPOS_TIME:
6637       case OPT_SCAN_EXPOS_TIME_R:
6638       case OPT_SCAN_EXPOS_TIME_G:
6639       case OPT_SCAN_EXPOS_TIME_B:
6640       case OPT_CAL_LAMP_DEN:
6641       case OPT_SCAN_LAMP_DEN:
6642       case OPT_DISABLE_PRE_FOCUS:
6643       case OPT_MANUAL_PRE_FOCUS:
6644       case OPT_FIX_FOCUS_POSITION:
6645       case OPT_LENS_CALIBRATION_DOC_POS:
6646       case OPT_HOLDER_FOCUS_POS_0MM:
6647       case OPT_LAMP_OFF_AT_EXIT:
6648         scanner->val[option].w = *(SANE_Word *) val;
6649        return SANE_STATUS_GOOD;
6650 
6651       case OPT_DOR:
6652       {
6653         if (scanner->val[option].w != *(SANE_Word *) val)
6654         {
6655           scanner->val[option].w = *(SANE_Word *) val; /* update valure for umax_set_max_geometry */
6656 
6657           if (info)
6658           {
6659             *info |= SANE_INFO_RELOAD_PARAMS;
6660             *info |= SANE_INFO_RELOAD_OPTIONS;
6661           }
6662 
6663           DBG(DBG_info,"sane_control_option: set DOR = %d\n", scanner->val[option].w);
6664           umax_set_max_geometry(scanner);
6665         }
6666        return SANE_STATUS_GOOD;
6667       }
6668 
6669       case OPT_BIT_DEPTH:
6670       {
6671         if (scanner->val[option].w != *(SANE_Word *) val)
6672         {
6673           scanner->val[option].w = *(SANE_Word *) val;
6674 
6675           if (info)
6676           {
6677             *info |= SANE_INFO_RELOAD_OPTIONS;
6678           }
6679 
6680           scanner->output_range.min   = 0;
6681           scanner->output_range.quant = 0;
6682 
6683           if (scanner->val[option].w == 8)						       /* 8 bit mode */
6684           {
6685             scanner->output_bytes  = 1;							    /* 1 bytes output */
6686             scanner->output_range.max = 255;
6687           }
6688           else										      /* > 8 bit mode */
6689           {
6690             scanner->output_bytes  = 2;							    /* 2 bytes output */
6691 
6692             if (scanner->device->gamma_lsb_padded) /* e.g. astra 1220s need lsb padded data */
6693             {
6694               scanner->output_range.max   = (int) pow(2, scanner->val[option].w) - 1;
6695             }
6696             else
6697             {
6698               scanner->output_range.max = 65535; /* define maxval for msb padded data */
6699             }
6700           }
6701 
6702 
6703           if (info)
6704           {
6705             *info |= SANE_INFO_RELOAD_PARAMS;
6706           }
6707         }
6708        return SANE_STATUS_GOOD;
6709       }
6710 
6711       case OPT_RGB_BIND:
6712       {
6713         if (scanner->val[option].w != *(SANE_Word *) val)
6714         {
6715           scanner->val[option].w = *(SANE_Word *) val;
6716           if (info)
6717           {
6718             *info |= SANE_INFO_RELOAD_OPTIONS;
6719           }
6720 
6721           umax_set_rgb_bind(scanner);
6722         }
6723        return SANE_STATUS_GOOD;
6724       }
6725 
6726       case OPT_RESOLUTION_BIND:
6727       {
6728         if (scanner->val[option].w != *(SANE_Word *) val)
6729 	{
6730           scanner->val[option].w = *(SANE_Word *) val;
6731 
6732           if (info)
6733           {
6734             *info |= SANE_INFO_RELOAD_OPTIONS;
6735           }
6736           if (scanner->val[option].w == SANE_FALSE)
6737           { /* don't bind */
6738             scanner->opt[OPT_Y_RESOLUTION].cap &= ~SANE_CAP_INACTIVE;
6739             scanner->opt[OPT_X_RESOLUTION].title = SANE_TITLE_SCAN_X_RESOLUTION;
6740             scanner->opt[OPT_X_RESOLUTION].name  = SANE_NAME_SCAN_RESOLUTION;
6741             scanner->opt[OPT_X_RESOLUTION].desc  = SANE_DESC_SCAN_X_RESOLUTION;
6742           }
6743           else
6744           { /* bind */
6745             scanner->opt[OPT_Y_RESOLUTION].cap |= SANE_CAP_INACTIVE;
6746             scanner->opt[OPT_X_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
6747             scanner->opt[OPT_X_RESOLUTION].name  = SANE_NAME_SCAN_RESOLUTION;
6748             scanner->opt[OPT_X_RESOLUTION].desc  = SANE_DESC_SCAN_RESOLUTION;
6749           }
6750 	}
6751        return SANE_STATUS_GOOD;
6752       }
6753 
6754       case OPT_SELECT_EXPOSURE_TIME:
6755       case OPT_SELECT_CAL_EXPOSURE_TIME:
6756       {
6757         if (scanner->val[option].w != *(SANE_Word *) val)
6758 	{
6759           scanner->val[option].w = *(SANE_Word *) val;
6760 
6761           if (info)
6762           {
6763             *info |= SANE_INFO_RELOAD_OPTIONS;
6764           }
6765 
6766           if (scanner->val[OPT_SELECT_EXPOSURE_TIME].w == SANE_FALSE)
6767 	  {
6768             scanner->opt[OPT_SELECT_CAL_EXPOSURE_TIME].cap |= SANE_CAP_INACTIVE;
6769 
6770             scanner->opt[OPT_CAL_EXPOS_TIME].cap    |= SANE_CAP_INACTIVE;
6771             scanner->opt[OPT_CAL_EXPOS_TIME_R].cap  |= SANE_CAP_INACTIVE;
6772             scanner->opt[OPT_CAL_EXPOS_TIME_G].cap  |= SANE_CAP_INACTIVE;
6773             scanner->opt[OPT_CAL_EXPOS_TIME_B].cap  |= SANE_CAP_INACTIVE;
6774 
6775             scanner->opt[OPT_SCAN_EXPOS_TIME].cap   |= SANE_CAP_INACTIVE;
6776             scanner->opt[OPT_SCAN_EXPOS_TIME_R].cap |= SANE_CAP_INACTIVE;
6777             scanner->opt[OPT_SCAN_EXPOS_TIME_G].cap |= SANE_CAP_INACTIVE;
6778             scanner->opt[OPT_SCAN_EXPOS_TIME_B].cap |= SANE_CAP_INACTIVE;
6779 	  }
6780 	  else /* exposure time selection active */
6781 	  {
6782             scanner->opt[OPT_SELECT_CAL_EXPOSURE_TIME].cap &= ~SANE_CAP_INACTIVE;
6783 
6784             if ( (strcmp(scanner->val[OPT_MODE].s, COLOR_STR) != 0) ||
6785 	         (scanner->val[OPT_RGB_BIND].w == SANE_TRUE) ||
6786                  (scanner->device->exposure_time_rgb_bind) ) /* RGB bind */
6787             {
6788               if (scanner->val[OPT_SELECT_CAL_EXPOSURE_TIME].w)
6789               {
6790                 scanner->opt[OPT_CAL_EXPOS_TIME].cap &= ~SANE_CAP_INACTIVE;
6791               }
6792               else
6793               {
6794                 scanner->opt[OPT_CAL_EXPOS_TIME].cap |= SANE_CAP_INACTIVE;
6795               }
6796 
6797               scanner->opt[OPT_SCAN_EXPOS_TIME].cap &= ~SANE_CAP_INACTIVE;
6798             }
6799             else /* no RGB bind */
6800             {
6801               if (scanner->val[OPT_SELECT_CAL_EXPOSURE_TIME].w)
6802               {
6803                 scanner->opt[OPT_CAL_EXPOS_TIME_R].cap &= ~SANE_CAP_INACTIVE;
6804                 scanner->opt[OPT_CAL_EXPOS_TIME_G].cap &= ~SANE_CAP_INACTIVE;
6805                 scanner->opt[OPT_CAL_EXPOS_TIME_B].cap &= ~SANE_CAP_INACTIVE;
6806               }
6807               else
6808               {
6809                 scanner->opt[OPT_CAL_EXPOS_TIME_R].cap |= SANE_CAP_INACTIVE;
6810                 scanner->opt[OPT_CAL_EXPOS_TIME_G].cap |= SANE_CAP_INACTIVE;
6811                 scanner->opt[OPT_CAL_EXPOS_TIME_B].cap |= SANE_CAP_INACTIVE;
6812               }
6813 
6814               scanner->opt[OPT_SCAN_EXPOS_TIME_R].cap &= ~SANE_CAP_INACTIVE;
6815               scanner->opt[OPT_SCAN_EXPOS_TIME_G].cap &= ~SANE_CAP_INACTIVE;
6816               scanner->opt[OPT_SCAN_EXPOS_TIME_B].cap &= ~SANE_CAP_INACTIVE;
6817             }
6818 	  }
6819 	}
6820        return SANE_STATUS_GOOD;
6821       }
6822 
6823       case OPT_SELECT_LAMP_DENSITY:
6824       {
6825         if (scanner->val[option].w != *(SANE_Word *) val)
6826 	{
6827           scanner->val[option].w = *(SANE_Word *) val;
6828 
6829           if (info)
6830           {
6831             *info |= SANE_INFO_RELOAD_OPTIONS;
6832           }
6833           if (scanner->val[option].w == SANE_FALSE)
6834 	  {
6835             scanner->opt[OPT_CAL_LAMP_DEN].cap  |= SANE_CAP_INACTIVE;
6836             scanner->opt[OPT_SCAN_LAMP_DEN].cap |= SANE_CAP_INACTIVE;
6837 	  }
6838 	  else
6839 	  {
6840             scanner->opt[OPT_CAL_LAMP_DEN].cap  &= ~SANE_CAP_INACTIVE;
6841             scanner->opt[OPT_SCAN_LAMP_DEN].cap &= ~SANE_CAP_INACTIVE;
6842 	  }
6843 	}
6844        return SANE_STATUS_GOOD;
6845       }
6846 
6847       /* side-effect-free word-array options: */
6848       case OPT_HALFTONE_PATTERN:
6849       case OPT_GAMMA_VECTOR:
6850       case OPT_GAMMA_VECTOR_R:
6851       case OPT_GAMMA_VECTOR_G:
6852       case OPT_GAMMA_VECTOR_B:
6853         memcpy (scanner->val[option].wa, val, scanner->opt[option].size);
6854        return SANE_STATUS_GOOD;
6855 
6856       /* single string-option with side-effect: */
6857       case OPT_SOURCE:
6858       {
6859         if (scanner->val[option].s)
6860         {
6861           free(scanner->val[option].s);
6862         }
6863         scanner->val[option].s = (SANE_Char *) strdup(val); /* update string for umax_set_max_geometry */
6864 
6865         DBG(DBG_info,"sane_control_option: set SOURCE = %s\n", (SANE_Char *) val);
6866         umax_set_max_geometry(scanner);
6867 
6868         if (info)
6869         {
6870           *info |= SANE_INFO_RELOAD_PARAMS;
6871           *info |= SANE_INFO_RELOAD_OPTIONS;
6872         }
6873        return SANE_STATUS_GOOD;
6874       }
6875       break;
6876 
6877       /* side-effect-free single-string options: */
6878 #ifdef UMAX_CALIBRATION_MODE_SELECTABLE
6879       case OPT_CALIB_MODE:
6880       /* fall through */
6881 #endif
6882       {
6883         if (scanner->val[option].s)
6884         {
6885           free (scanner->val[option].s);
6886         }
6887         scanner->val[option].s = (SANE_Char*)strdup(val);
6888        return SANE_STATUS_GOOD;
6889       }
6890 
6891       /* options with side-effects: */
6892 
6893       case OPT_CUSTOM_GAMMA:
6894       {
6895         w = *(SANE_Word *) val;
6896         if (w == scanner->val[OPT_CUSTOM_GAMMA].w) { return SANE_STATUS_GOOD; }
6897 
6898         scanner->val[OPT_CUSTOM_GAMMA].w = w;
6899         if (w)									   /* use custom_gamma_table */
6900         {
6901            const char *mode = scanner->val[OPT_MODE].s;
6902 
6903            if ( (strcmp(mode, LINEART_STR) == 0) ||
6904                 (strcmp(mode, HALFTONE_STR) == 0) ||
6905                 (strcmp(mode, GRAY_STR) == 0) )
6906            { scanner->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; }
6907            else if (strcmp(mode, COLOR_STR) == 0)
6908            {
6909              scanner->opt[OPT_GAMMA_VECTOR].cap   &= ~SANE_CAP_INACTIVE;
6910              scanner->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
6911              scanner->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
6912              scanner->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
6913            }
6914         }
6915         else								     /* don't use custom_gamma_table */
6916         {
6917           scanner->opt[OPT_GAMMA_VECTOR].cap   |= SANE_CAP_INACTIVE;
6918           scanner->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
6919           scanner->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
6920           scanner->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
6921         }
6922         if (info)
6923         {
6924           *info |= SANE_INFO_RELOAD_OPTIONS;
6925         }
6926        return SANE_STATUS_GOOD;
6927       }
6928 
6929       case OPT_MODE:
6930       {
6931        int halftoning;
6932 
6933         if (scanner->val[option].s)
6934         {
6935           free (scanner->val[option].s);
6936         }
6937 
6938         scanner->val[option].s = (SANE_Char*)strdup(val);
6939 
6940         if (info)
6941         {
6942           *info |=SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
6943         }
6944 
6945         scanner->opt[OPT_NEGATIVE].cap           |= SANE_CAP_INACTIVE;
6946 
6947         scanner->opt[OPT_BIT_DEPTH].cap          |= SANE_CAP_INACTIVE;
6948 
6949         scanner->opt[OPT_CUSTOM_GAMMA].cap       |= SANE_CAP_INACTIVE;
6950         scanner->opt[OPT_GAMMA_VECTOR].cap       |= SANE_CAP_INACTIVE;
6951         scanner->opt[OPT_GAMMA_VECTOR_R].cap     |= SANE_CAP_INACTIVE;
6952         scanner->opt[OPT_GAMMA_VECTOR_G].cap     |= SANE_CAP_INACTIVE;
6953         scanner->opt[OPT_GAMMA_VECTOR_B].cap     |= SANE_CAP_INACTIVE;
6954 
6955         scanner->opt[OPT_CONTRAST].cap           |= SANE_CAP_INACTIVE;
6956         scanner->opt[OPT_BRIGHTNESS].cap         |= SANE_CAP_INACTIVE;
6957         scanner->opt[OPT_THRESHOLD].cap          |= SANE_CAP_INACTIVE;
6958 
6959         scanner->opt[OPT_RGB_BIND].cap           |= SANE_CAP_INACTIVE;
6960 
6961         scanner->opt[OPT_ANALOG_GAMMA].cap       |= SANE_CAP_INACTIVE;
6962         scanner->opt[OPT_ANALOG_GAMMA_R].cap     |= SANE_CAP_INACTIVE;
6963         scanner->opt[OPT_ANALOG_GAMMA_G].cap     |= SANE_CAP_INACTIVE;
6964         scanner->opt[OPT_ANALOG_GAMMA_B].cap     |= SANE_CAP_INACTIVE;
6965 
6966         scanner->opt[OPT_HIGHLIGHT].cap          |= SANE_CAP_INACTIVE;
6967         scanner->opt[OPT_HIGHLIGHT_R].cap        |= SANE_CAP_INACTIVE;
6968         scanner->opt[OPT_HIGHLIGHT_G].cap        |= SANE_CAP_INACTIVE;
6969         scanner->opt[OPT_HIGHLIGHT_B].cap        |= SANE_CAP_INACTIVE;
6970 
6971         scanner->opt[OPT_SHADOW].cap             |= SANE_CAP_INACTIVE;
6972         scanner->opt[OPT_SHADOW_R].cap           |= SANE_CAP_INACTIVE;
6973         scanner->opt[OPT_SHADOW_G].cap           |= SANE_CAP_INACTIVE;
6974         scanner->opt[OPT_SHADOW_B].cap           |= SANE_CAP_INACTIVE;
6975 
6976         scanner->opt[OPT_CAL_EXPOS_TIME].cap     |= SANE_CAP_INACTIVE;
6977         scanner->opt[OPT_CAL_EXPOS_TIME_R].cap   |= SANE_CAP_INACTIVE;
6978         scanner->opt[OPT_CAL_EXPOS_TIME_G].cap   |= SANE_CAP_INACTIVE;
6979         scanner->opt[OPT_CAL_EXPOS_TIME_B].cap   |= SANE_CAP_INACTIVE;
6980 
6981         scanner->opt[OPT_SCAN_EXPOS_TIME].cap    |= SANE_CAP_INACTIVE;
6982         scanner->opt[OPT_SCAN_EXPOS_TIME_R].cap  |= SANE_CAP_INACTIVE;
6983         scanner->opt[OPT_SCAN_EXPOS_TIME_G].cap  |= SANE_CAP_INACTIVE;
6984         scanner->opt[OPT_SCAN_EXPOS_TIME_B].cap  |= SANE_CAP_INACTIVE;
6985 
6986         scanner->opt[OPT_HALFTONE_DIMENSION].cap |= SANE_CAP_INACTIVE;
6987         scanner->opt[OPT_HALFTONE_PATTERN].cap   |= SANE_CAP_INACTIVE;
6988 
6989 
6990         halftoning = (strcmp(val, HALFTONE_STR) == 0 || strcmp(val, COLOR_HALFTONE_STR) == 0);
6991 
6992         if (halftoning || strcmp(val, LINEART_STR) == 0 || strcmp(val, COLOR_LINEART_STR) == 0)
6993         {										    /* one bit modes */
6994           if (scanner->device->inquiry_reverse)
6995           {
6996             scanner->opt[OPT_NEGATIVE].cap  &= ~SANE_CAP_INACTIVE;
6997           }
6998 
6999           if (halftoning)
7000           {										 /* halftoning modes */
7001             scanner->opt[OPT_CONTRAST].cap   &= ~SANE_CAP_INACTIVE;
7002             scanner->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
7003 
7004 	    if (scanner->device->inquiry_highlight)
7005             {
7006               scanner->opt[OPT_HIGHLIGHT].cap &= ~SANE_CAP_INACTIVE;
7007             }
7008 
7009 	    if (scanner->device->inquiry_shadow)
7010             {
7011               scanner->opt[OPT_SHADOW].cap &= ~SANE_CAP_INACTIVE;
7012             }
7013 
7014 /* disable halftone pattern download options */
7015 #if 0
7016             scanner->opt[OPT_HALFTONE_DIMENSION].cap &= ~SANE_CAP_INACTIVE;
7017 
7018             if (scanner->val[OPT_HALFTONE_DIMENSION].w)
7019             {
7020               scanner->opt[OPT_HALFTONE_PATTERN].cap &= ~SANE_CAP_INACTIVE;
7021             }
7022 #endif
7023 
7024             if (scanner->val[OPT_SELECT_EXPOSURE_TIME].w == SANE_TRUE)
7025             {
7026               scanner->opt[OPT_CAL_EXPOS_TIME].cap   &= ~SANE_CAP_INACTIVE;
7027               scanner->opt[OPT_SCAN_EXPOS_TIME].cap  &= ~SANE_CAP_INACTIVE;
7028             }
7029 
7030             scanner->exposure_time_range.min = scanner->device->inquiry_exposure_time_h_min
7031 	                                       * scanner->device->inquiry_exposure_time_step_unit;
7032           }
7033 	  else
7034 	  {										    /* lineart modes */
7035             scanner->opt[OPT_THRESHOLD].cap  &= ~SANE_CAP_INACTIVE;
7036 
7037             if (scanner->val[OPT_SELECT_EXPOSURE_TIME].w == SANE_TRUE)
7038             {
7039               scanner->opt[OPT_CAL_EXPOS_TIME].cap   &= ~SANE_CAP_INACTIVE;
7040               scanner->opt[OPT_SCAN_EXPOS_TIME].cap   &= ~SANE_CAP_INACTIVE;
7041             }
7042 
7043             scanner->exposure_time_range.min = scanner->device->inquiry_exposure_time_l_min
7044 	                                       * scanner->device->inquiry_exposure_time_step_unit;
7045 	  }
7046         }
7047         else
7048         {								   /* multi-bit modes(gray or color) */
7049           scanner->opt[OPT_BIT_DEPTH].cap &= ~SANE_CAP_INACTIVE;
7050 
7051           if (scanner->device->inquiry_highlight)
7052           {
7053             scanner->opt[OPT_HIGHLIGHT].cap &= ~SANE_CAP_INACTIVE;
7054           }
7055 
7056           if (scanner->device->inquiry_shadow)
7057           {
7058             scanner->opt[OPT_SHADOW].cap &= ~SANE_CAP_INACTIVE;
7059           }
7060 
7061           if (scanner->device->inquiry_reverse_multi)
7062           {
7063             scanner->opt[OPT_NEGATIVE].cap &= ~SANE_CAP_INACTIVE;
7064           }
7065 
7066           if (scanner->device->inquiry_gamma_dwload)
7067           {
7068             scanner->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
7069           }
7070           else
7071           {
7072             scanner->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE;
7073           }
7074 
7075           if (scanner->device->inquiry_analog_gamma)
7076           {
7077             scanner->opt[OPT_ANALOG_GAMMA].cap &= ~SANE_CAP_INACTIVE;
7078           }
7079 
7080           if (scanner->val[OPT_SELECT_EXPOSURE_TIME].w == SANE_TRUE)
7081           {
7082             scanner->opt[OPT_CAL_EXPOS_TIME].cap  &= ~SANE_CAP_INACTIVE;
7083             scanner->opt[OPT_SCAN_EXPOS_TIME].cap &= ~SANE_CAP_INACTIVE;
7084           }
7085 
7086           if (strcmp(val, COLOR_STR) == 0)
7087           {
7088             if ( (scanner->device->inquiry_analog_gamma) ||
7089                  (scanner->device->inquiry_highlight)    ||
7090                  (scanner->device->inquiry_shadow)       ||
7091                  (scanner->device->inquiry_exposure_adj) )
7092             {
7093               scanner->opt[OPT_RGB_BIND].cap &= ~SANE_CAP_INACTIVE;
7094             }
7095 
7096             scanner->exposure_time_range.min = scanner->device->inquiry_exposure_time_c_min
7097 	                                       * scanner->device->inquiry_exposure_time_step_unit;
7098           }
7099 	  else /* grayscale */
7100 	  {
7101             scanner->exposure_time_range.min = scanner->device->inquiry_exposure_time_g_min
7102 	                                       * scanner->device->inquiry_exposure_time_step_unit;
7103 	  }
7104 	}
7105 
7106         umax_set_rgb_bind(scanner);
7107 
7108         if (scanner->val[OPT_CUSTOM_GAMMA].w)
7109         {
7110           if (strcmp(val, GRAY_STR) == 0)
7111           {
7112             scanner->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
7113           }
7114           else if (strcmp(val, COLOR_STR) == 0)
7115           {
7116             scanner->opt[OPT_GAMMA_VECTOR].cap   &= ~SANE_CAP_INACTIVE;
7117             scanner->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
7118             scanner->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
7119             scanner->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
7120           }
7121 	}
7122        return SANE_STATUS_GOOD;
7123       }
7124 
7125       case OPT_HALFTONE_DIMENSION: /* halftone pattern dimension affects halftone pattern option: */
7126       {
7127         unsigned dim = *(SANE_Word *) val;
7128 
7129          scanner->val[option].w = dim;
7130 
7131          if (info)
7132          {
7133            *info |= SANE_INFO_RELOAD_OPTIONS;
7134          }
7135 
7136          scanner->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
7137 
7138          if (dim > 0)
7139          {
7140            scanner->opt[OPT_HALFTONE_PATTERN].cap &= ~SANE_CAP_INACTIVE;
7141            scanner->opt[OPT_HALFTONE_PATTERN].size = dim * sizeof (SANE_Word);
7142          }
7143         return SANE_STATUS_GOOD;
7144       }
7145 
7146       case OPT_LAMP_ON:
7147       {
7148         if (!umax_set_lamp_status(handle, 1 /* lamp on */))
7149         {
7150           return SANE_STATUS_GOOD;
7151         }
7152         else
7153         {
7154           return SANE_STATUS_UNSUPPORTED;
7155         }
7156       }
7157 
7158       case OPT_LAMP_OFF:
7159       {
7160         if (!umax_set_lamp_status(handle, 0 /* lamp off */))
7161         {
7162           return SANE_STATUS_GOOD;
7163         }
7164         else
7165         {
7166           return SANE_STATUS_UNSUPPORTED;
7167         }
7168       }
7169     }
7170   } /* else */
7171  return SANE_STATUS_INVAL;
7172 }
7173 
7174 
7175 /* ------------------------------------------------------------ SANE GET PARAMETERS ------------------------ */
7176 
7177 
sane_get_parameters(SANE_Handle handle, SANE_Parameters *params)7178 SANE_Status sane_get_parameters(SANE_Handle handle, SANE_Parameters *params)
7179 {
7180  Umax_Scanner *scanner = handle;
7181  const char *mode;
7182 
7183   DBG(DBG_sane_info,"sane_get_parameters\n");
7184 
7185   if (!scanner->scanning)
7186   {								  /* not scanning, so lets use recent values */
7187     double width, length, x_dpi, y_dpi;
7188 
7189     memset(&scanner->params, 0, sizeof (scanner->params));
7190 
7191     width  = SANE_UNFIX(scanner->val[OPT_BR_X].w - scanner->val[OPT_TL_X].w);
7192     length = SANE_UNFIX(scanner->val[OPT_BR_Y].w - scanner->val[OPT_TL_Y].w);
7193     x_dpi  = SANE_UNFIX(scanner->val[OPT_X_RESOLUTION].w);
7194     y_dpi  = SANE_UNFIX(scanner->val[OPT_Y_RESOLUTION].w);
7195 
7196     if ( (scanner->val[OPT_RESOLUTION_BIND].w == SANE_TRUE) || (scanner->val[OPT_PREVIEW].w == SANE_TRUE) )
7197     {
7198       y_dpi = x_dpi;
7199     }
7200 
7201     if (x_dpi > 0.0 && y_dpi > 0.0 && width > 0.0 && length > 0.0)
7202     {
7203       double x_dots_per_mm = x_dpi / MM_PER_INCH;
7204       double y_dots_per_mm = y_dpi / MM_PER_INCH;
7205 
7206       scanner->params.pixels_per_line = width *  x_dots_per_mm;
7207       scanner->params.lines           = length * y_dots_per_mm;
7208     }
7209   }
7210 
7211   mode = scanner->val[OPT_MODE].s;
7212 
7213   if (strcmp(mode, LINEART_STR) == 0 || strcmp(mode, HALFTONE_STR) == 0)
7214   {
7215     scanner->params.format         = SANE_FRAME_GRAY;
7216     scanner->params.bytes_per_line = (scanner->params.pixels_per_line + 7) / 8;
7217     scanner->params.depth          = 1;
7218   }
7219   else if (strcmp(mode, GRAY_STR) == 0)
7220   {
7221     scanner->params.format         = SANE_FRAME_GRAY;
7222     scanner->params.bytes_per_line = scanner->params.pixels_per_line * scanner->output_bytes;
7223     scanner->params.depth          = 8 * scanner->output_bytes;
7224   }
7225   else if (strcmp(mode, COLOR_LINEART_STR) == 0 || strcmp(mode, COLOR_HALFTONE_STR) == 0 )
7226   {
7227     if (scanner->device->inquiry_one_pass_color)
7228     {
7229       scanner->device->three_pass = 0;
7230       scanner->params.format         = SANE_FRAME_RGB;
7231       scanner->params.bytes_per_line = 3 * scanner->params.pixels_per_line;
7232       scanner->params.depth          = 8;
7233     }
7234     else										 /* three pass color */
7235     {
7236       scanner->device->three_pass = 1;
7237       scanner->params.format         = SANE_FRAME_RED + scanner->device->three_pass_color - 1;
7238       scanner->params.bytes_per_line = scanner->params.pixels_per_line;
7239       scanner->params.depth          = 8;
7240     }
7241   }
7242   else												      /* RGB */
7243   {
7244     if (scanner->device->inquiry_one_pass_color)
7245     {
7246       scanner->device->three_pass = 0;
7247       scanner->params.format         = SANE_FRAME_RGB;
7248       scanner->params.bytes_per_line = 3 * scanner->params.pixels_per_line * scanner->output_bytes;
7249       scanner->params.depth          = 8 * scanner->output_bytes;
7250     }
7251     else										 /* three pass color */
7252     {
7253       scanner->device->three_pass = 1;
7254       scanner->params.format         = SANE_FRAME_RED + scanner->device->three_pass_color - 1;
7255       scanner->params.bytes_per_line = scanner->params.pixels_per_line * scanner->output_bytes;
7256       scanner->params.depth          = 8 * scanner->output_bytes;
7257     }
7258   }
7259 
7260   scanner->params.last_frame = (scanner->params.format != SANE_FRAME_RED && scanner->params.format != SANE_FRAME_GREEN);
7261 
7262   if (params)
7263   {
7264     *params = scanner->params;
7265   }
7266 
7267  return SANE_STATUS_GOOD;
7268 }
7269 
7270 
7271 /* ------------------------------------------------------------ SANE START --------------------------------- */
7272 
7273 
sane_start(SANE_Handle handle)7274 SANE_Status sane_start(SANE_Handle handle)
7275 {
7276  Umax_Scanner *scanner = handle;
7277  const char *mode;
7278  double xbasedots, ybasedots;
7279  const char *scan_source;
7280  int pause;
7281  int status;
7282  int fds[2];
7283 
7284   DBG(DBG_sane_init,"sane_start\n");
7285 
7286   /* Invalidate reader_pid so a subsequent error and following call to
7287    * do_cancel() won't trip over it. */
7288   sanei_thread_invalidate(scanner->reader_pid);
7289 
7290   mode = scanner->val[OPT_MODE].s;
7291 
7292   if (scanner->device->sfd == -1)   /* first call, don`t run this routine again on multi frame or multi image scan */
7293   {
7294     umax_initialize_values(scanner->device);								    /* reset values */
7295 
7296     scanner->device->three_pass_color = 1;
7297 
7298     /* test for adf and uta */
7299     scan_source = scanner->val[OPT_SOURCE].s;
7300 
7301     if (strcmp(scan_source, UTA_STR) == 0)
7302     {
7303       if ( (scanner->device->inquiry_uta != 0) && (scanner->device->inquiry_transavail != 0) )
7304       {
7305         scanner->device->uta = 1;
7306       }
7307       else
7308       {
7309         DBG(DBG_error,"ERROR: Transparency Adapter not available\n");
7310         umax_scsi_close(scanner->device);
7311        return SANE_STATUS_INVAL;
7312       }
7313     }
7314     else /* Test if ADF is selected */
7315     {
7316       scanner->device->uta = 0;
7317 
7318       if (strcmp(scan_source, ADF_STR) == 0)
7319       {
7320         if ( (scanner->device->inquiry_adf) && (scanner->device->inquiry_adfmode) )
7321         {
7322           scanner->device->adf = 1;
7323         }
7324         else
7325         {
7326           DBG(DBG_error,"ERROR: Automatic Document Feeder not available\n");
7327          umax_scsi_close(scanner->device);
7328          return SANE_STATUS_INVAL;
7329         }
7330       }
7331       else
7332       {
7333         scanner->device->adf = 0;
7334       }
7335     }
7336 
7337     if (scanner->device->inquiry_GIB & 32)						/* 16 bit input mode */
7338     {
7339       scanner->device->gamma_input_bits_code = 32;
7340       DBG(DBG_sane_info, "Using 16 bits for gamma input\n");
7341     }
7342     else if (scanner->device->inquiry_GIB & 16)						/* 14 bit input mode */
7343     {
7344       scanner->device->gamma_input_bits_code = 16;
7345       DBG(DBG_sane_info, "Using 14 bits for gamma input\n");
7346     }
7347     else if (scanner->device->inquiry_GIB & 8)						/* 12 bit input mode */
7348     {
7349       scanner->device->gamma_input_bits_code = 8;
7350       DBG(DBG_sane_info, "Using 12 bits for gamma input\n");
7351     }
7352     else if (scanner->device->inquiry_GIB & 4)						/* 10 bit input mode */
7353     {
7354       scanner->device->gamma_input_bits_code = 4;
7355       DBG(DBG_sane_info, "Using 10 bits for gamma input\n");
7356     }
7357     else if (scanner->device->inquiry_GIB & 2)						 /* 9 bit input mode */
7358     {
7359       scanner->device->gamma_input_bits_code = 2;
7360       DBG(DBG_sane_info, "Using 9 bits for gamma input\n");
7361     }
7362     else										 /* 8 bit input mode */
7363     {
7364       scanner->device->gamma_input_bits_code = 1;
7365       DBG(DBG_sane_info, "Using 8 bits for gamma input\n");
7366     }
7367 
7368     if (scanner->val[OPT_BIT_DEPTH].w == 16)					       /* 16 bit output mode */
7369     {
7370       scanner->device->bits_per_pixel      = 16;
7371       scanner->device->bits_per_pixel_code = 32;
7372       scanner->device->max_value      = 65535;
7373       DBG(DBG_sane_info,"Using 16 bits for output\n");
7374     }
7375     else if (scanner->val[OPT_BIT_DEPTH].w == 14)				       /* 14 bit output mode */
7376     {
7377       scanner->device->bits_per_pixel      = 14;
7378       scanner->device->bits_per_pixel_code = 16;
7379       scanner->device->max_value      = 16383;
7380       DBG(DBG_sane_info,"Using 14 bits for output\n");
7381     }
7382     else if (scanner->val[OPT_BIT_DEPTH].w == 12)				       /* 12 bit output mode */
7383     {
7384       scanner->device->bits_per_pixel      = 12;
7385       scanner->device->bits_per_pixel_code = 8;
7386       scanner->device->max_value      = 4095;
7387       DBG(DBG_sane_info,"Using 12 bits for output\n");
7388     }
7389     else if (scanner->val[OPT_BIT_DEPTH].w == 10)				       /* 10 bit output mode */
7390     {
7391       scanner->device->bits_per_pixel      = 10;
7392       scanner->device->bits_per_pixel_code = 4;
7393       scanner->device->max_value      = 1023;
7394       DBG(DBG_sane_info,"Using 10 bits for output\n");
7395     }
7396     else if (scanner->val[OPT_BIT_DEPTH].w == 9)				        /* 9 bit output mode */
7397     {
7398       scanner->device->bits_per_pixel      = 9;
7399       scanner->device->bits_per_pixel_code = 2;
7400       scanner->device->max_value      = 511;
7401       DBG(DBG_sane_info,"Using 9 bits for output\n");
7402     }
7403     else										/* 8 bit output mode */
7404     {
7405       scanner->device->bits_per_pixel      = 8;
7406       scanner->device->bits_per_pixel_code = 1;
7407       scanner->device->max_value      = 255;
7408       DBG(DBG_sane_info,"Using 8 bits for output\n");
7409     }
7410 
7411     scanner->device->reverse = scanner->device->reverse_multi = scanner->val[OPT_NEGATIVE].w;
7412 
7413     scanner->device->threshold         = P_100_TO_255(scanner->val[OPT_THRESHOLD].w);
7414     scanner->device->brightness        = P_200_TO_255(scanner->val[OPT_BRIGHTNESS].w);
7415     scanner->device->contrast          = P_200_TO_255(scanner->val[OPT_CONTRAST].w);
7416 
7417     scanner->device->batch_scan        = ( scanner->val[OPT_BATCH_SCAN_START].w ||
7418                                            scanner->val[OPT_BATCH_SCAN_LOOP].w ||
7419                                            scanner->val[OPT_BATCH_SCAN_END].w );
7420     scanner->device->batch_end         = scanner->val[OPT_BATCH_SCAN_END].w;
7421     scanner->device->batch_next_tl_y   = SANE_UNFIX(scanner->val[OPT_BATCH_NEXT_TL_Y].w) * scanner->device->y_coordinate_base / MM_PER_INCH;
7422 
7423     if (scanner->val[OPT_BATCH_NEXT_TL_Y].w == 0xFFFF)  /* option not set: use br_y => scanhead stops at end of batch area */
7424     {
7425       scanner->device->batch_next_tl_y = SANE_UNFIX(scanner->val[OPT_BR_Y].w) * scanner->device->y_coordinate_base / MM_PER_INCH;
7426     }
7427 
7428     if ((scanner->device->batch_scan) && !scanner->val[OPT_BATCH_SCAN_START].w)
7429     {
7430       scanner->device->calibration = 9; /* no calibration - otherwise the scanhead will go into calibration position */
7431     }
7432     else
7433     {
7434       scanner->device->calibration = 0; /* calibration defined by image type */
7435     }
7436 
7437     scanner->device->quality           = scanner->val[OPT_QUALITY].w;
7438     scanner->device->dor               = scanner->val[OPT_DOR].w;
7439     scanner->device->preview           = scanner->val[OPT_PREVIEW].w;
7440     scanner->device->warmup            = scanner->val[OPT_WARMUP].w;
7441 
7442     scanner->device->fix_focus_position   = scanner->val[OPT_FIX_FOCUS_POSITION].w;
7443     scanner->device->lens_cal_in_doc_pos  = scanner->val[OPT_LENS_CALIBRATION_DOC_POS].w;
7444     scanner->device->disable_pre_focus    = scanner->val[OPT_DISABLE_PRE_FOCUS].w;
7445     scanner->device->holder_focus_pos_0mm = scanner->val[OPT_HOLDER_FOCUS_POS_0MM].w;
7446     scanner->device->manual_focus         = scanner->val[OPT_MANUAL_PRE_FOCUS].w;
7447 
7448     scanner->device->analog_gamma_r =
7449     scanner->device->analog_gamma_g =
7450     scanner->device->analog_gamma_b = umax_calculate_analog_gamma(SANE_UNFIX(scanner->val[OPT_ANALOG_GAMMA].w));
7451 
7452     scanner->device->highlight_r =
7453     scanner->device->highlight_g =
7454     scanner->device->highlight_b = P_100_TO_255(scanner->val[OPT_HIGHLIGHT].w);
7455 
7456     scanner->device->shadow_r =
7457     scanner->device->shadow_g =
7458     scanner->device->shadow_b = P_100_TO_255(scanner->val[OPT_SHADOW].w);
7459 
7460     if (scanner->val[OPT_SELECT_EXPOSURE_TIME].w == SANE_TRUE)
7461     {
7462       if (scanner->val[OPT_SELECT_CAL_EXPOSURE_TIME].w) /* separate calibration exposure time */
7463       {
7464         scanner->device->exposure_time_calibration_r =
7465         scanner->device->exposure_time_calibration_g =
7466         scanner->device->exposure_time_calibration_b = scanner->val[OPT_CAL_EXPOS_TIME].w;
7467       }
7468       else /* same exposure times for calibration as for scanning */
7469       {
7470         scanner->device->exposure_time_calibration_r =
7471         scanner->device->exposure_time_calibration_g =
7472         scanner->device->exposure_time_calibration_b = scanner->val[OPT_SCAN_EXPOS_TIME].w;
7473       }
7474 
7475       scanner->device->exposure_time_scan_r =
7476       scanner->device->exposure_time_scan_g =
7477       scanner->device->exposure_time_scan_b = scanner->val[OPT_SCAN_EXPOS_TIME].w;
7478     }
7479 
7480     if (scanner->val[OPT_SELECT_LAMP_DENSITY].w == SANE_TRUE)
7481     {
7482       scanner->device->c_density = P_100_TO_254(scanner->val[OPT_CAL_LAMP_DEN].w);
7483       scanner->device->s_density = P_100_TO_254(scanner->val[OPT_SCAN_LAMP_DEN].w);
7484     }
7485 
7486     if (strcmp(mode, LINEART_STR) == 0)
7487     {
7488       scanner->device->colormode = LINEART;
7489     }
7490     else if (strcmp(mode, HALFTONE_STR) == 0)
7491     {
7492       scanner->device->colormode = HALFTONE;
7493     }
7494     else if (strcmp(mode, GRAY_STR) == 0)
7495     {
7496       scanner->device->colormode = GRAYSCALE;
7497     }
7498     else if (strcmp(mode, COLOR_LINEART_STR) == 0)
7499     {
7500       scanner->device->colormode = RGB_LINEART;
7501     }
7502     else if (strcmp(mode, COLOR_HALFTONE_STR) == 0)
7503     {
7504       scanner->device->colormode = RGB_HALFTONE;
7505     }
7506     else if (strcmp(mode, COLOR_STR) == 0)
7507     {
7508       scanner->device->colormode = RGB;
7509       if (scanner->val[OPT_RGB_BIND].w == SANE_FALSE)
7510       {
7511         scanner->device->analog_gamma_r =
7512                  umax_calculate_analog_gamma( SANE_UNFIX(scanner->val[OPT_ANALOG_GAMMA_R].w) );
7513         scanner->device->analog_gamma_g =
7514                  umax_calculate_analog_gamma( SANE_UNFIX(scanner->val[OPT_ANALOG_GAMMA_G].w) );
7515         scanner->device->analog_gamma_b =
7516                  umax_calculate_analog_gamma( SANE_UNFIX(scanner->val[OPT_ANALOG_GAMMA_B].w) );
7517 
7518         scanner->device->highlight_r = P_100_TO_255(scanner->val[OPT_HIGHLIGHT_R].w);
7519         scanner->device->highlight_g = P_100_TO_255(scanner->val[OPT_HIGHLIGHT_G].w);
7520         scanner->device->highlight_b = P_100_TO_255(scanner->val[OPT_HIGHLIGHT_B].w);
7521 
7522         scanner->device->shadow_r = P_100_TO_255(scanner->val[OPT_SHADOW_R].w);
7523         scanner->device->shadow_g = P_100_TO_255(scanner->val[OPT_SHADOW_G].w);
7524         scanner->device->shadow_b = P_100_TO_255(scanner->val[OPT_SHADOW_B].w);
7525 
7526         if ((scanner->val[OPT_SELECT_EXPOSURE_TIME].w == SANE_TRUE) && (!scanner->device->exposure_time_rgb_bind))
7527         {
7528           if (scanner->val[OPT_SELECT_CAL_EXPOSURE_TIME].w) /* separate calibration exposure time */
7529           {
7530             scanner->device->exposure_time_calibration_r = scanner->val[OPT_CAL_EXPOS_TIME_R].w;
7531             scanner->device->exposure_time_calibration_g = scanner->val[OPT_CAL_EXPOS_TIME_G].w;
7532             scanner->device->exposure_time_calibration_b = scanner->val[OPT_CAL_EXPOS_TIME_B].w;
7533           }
7534           else /* same exposure times for calibration as for scanning */
7535           {
7536             scanner->device->exposure_time_calibration_r = scanner->val[OPT_SCAN_EXPOS_TIME_R].w;
7537             scanner->device->exposure_time_calibration_g = scanner->val[OPT_SCAN_EXPOS_TIME_G].w;
7538             scanner->device->exposure_time_calibration_b = scanner->val[OPT_SCAN_EXPOS_TIME_B].w;
7539           }
7540 
7541           scanner->device->exposure_time_scan_r = scanner->val[OPT_SCAN_EXPOS_TIME_R].w;
7542           scanner->device->exposure_time_scan_g = scanner->val[OPT_SCAN_EXPOS_TIME_G].w;
7543           scanner->device->exposure_time_scan_b = scanner->val[OPT_SCAN_EXPOS_TIME_B].w;
7544         }
7545       }
7546     }
7547 
7548     if (scanner->device->force_preview_bit_rgb != 0)          /* in RGB-mode set preview bit, eg. for UMAX S6E */
7549     {
7550       if (scanner->device->colormode == RGB)
7551       {
7552         DBG(DBG_sane_info,"setting preview bit = 1 (option force-preview-bit-rgb)\n");
7553         scanner->device->preview = SANE_TRUE;
7554       }
7555     }
7556 
7557 
7558 #ifdef UMAX_CALIBRATION_MODE_SELECTABLE
7559     if (strcmp(scanner->val[OPT_CALIB_MODE].s, CALIB_MODE_0000) == 0)
7560     {
7561       scanner->device->calibration = 0;
7562     }
7563     else if (strcmp(scanner->val[OPT_CALIB_MODE].s, CALIB_MODE_1111) == 0)
7564     {
7565       scanner->device->calibration = 15;
7566     }
7567     else if (strcmp(scanner->val[OPT_CALIB_MODE].s, CALIB_MODE_1110) == 0)
7568     {
7569       scanner->device->calibration = 14;
7570     }
7571     else if (strcmp(scanner->val[OPT_CALIB_MODE].s, CALIB_MODE_1101) == 0)
7572     {
7573       scanner->device->calibration = 13;
7574     }
7575     else if (strcmp(scanner->val[OPT_CALIB_MODE].s, CALIB_MODE_1010) == 0)
7576     {
7577       scanner->device->calibration = 10;
7578     }
7579     else if (strcmp(scanner->val[OPT_CALIB_MODE].s, CALIB_MODE_1001) == 0)
7580     {
7581       scanner->device->calibration = 9;
7582     }
7583 #endif
7584 
7585     /* get and set geometric values for scanning */
7586     scanner->device->x_resolution = SANE_UNFIX(scanner->val[OPT_X_RESOLUTION].w);
7587     scanner->device->y_resolution = SANE_UNFIX(scanner->val[OPT_Y_RESOLUTION].w);
7588 
7589     if ( (scanner->val[OPT_RESOLUTION_BIND].w == SANE_TRUE) || (scanner->val[OPT_PREVIEW].w == SANE_TRUE) )
7590     {
7591       scanner->device->y_resolution = scanner->device->x_resolution;
7592     }
7593 
7594     xbasedots = scanner->device->x_coordinate_base / MM_PER_INCH;
7595     ybasedots = scanner->device->y_coordinate_base / MM_PER_INCH;
7596 
7597 #if 0
7598     scanner->device->upper_left_x = ((int) (SANE_UNFIX(scanner->val[OPT_TL_X].w) * xbasedots)) & 65534;
7599     scanner->device->upper_left_y = ((int) (SANE_UNFIX(scanner->val[OPT_TL_Y].w) * ybasedots)) & 65534;
7600 
7601     scanner->device->scanwidth    = ((int)((SANE_UNFIX(scanner->val[OPT_BR_X].w - scanner->val[OPT_TL_X].w)) * xbasedots)) & 65534;
7602     scanner->device->scanlength   = ((int)((SANE_UNFIX(scanner->val[OPT_BR_Y].w - scanner->val[OPT_TL_Y].w)) * ybasedots)) & 65534;
7603 #endif
7604 
7605     scanner->device->upper_left_x = (int) (SANE_UNFIX(scanner->val[OPT_TL_X].w) * xbasedots);
7606     scanner->device->upper_left_y = (int) (SANE_UNFIX(scanner->val[OPT_TL_Y].w) * ybasedots);
7607 
7608     scanner->device->scanwidth    = (int)((SANE_UNFIX(scanner->val[OPT_BR_X].w - scanner->val[OPT_TL_X].w)) * xbasedots);
7609     scanner->device->scanlength   = (int)((SANE_UNFIX(scanner->val[OPT_BR_Y].w - scanner->val[OPT_TL_Y].w)) * ybasedots);
7610 
7611 
7612     if (umax_check_values(scanner->device) != 0)
7613     {
7614       DBG(DBG_error,"ERROR: invalid scan-values\n");
7615       scanner->scanning = SANE_FALSE;
7616      return SANE_STATUS_INVAL;
7617     }
7618 
7619     /* The scanner defines a x-origin-offset for DOR mode, this offset is used for the */
7620     /* x range in this backend, so the frontend/user knows the correct positions related to */
7621     /* scanner's surface. But the scanner wants x values from origin 0 instead */
7622     /* of the x-origin defined by the scanner`s inquiry */
7623     if (scanner->device->dor != 0) /* dor mode active */
7624     {
7625       DBG(DBG_info,"subtracting DOR x-origin-offset from upper left x\n");
7626       scanner->device->upper_left_x -= scanner->device->inquiry_dor_x_off * scanner->device->x_coordinate_base; /* correct DOR x-origin */
7627 
7628       if (scanner->device->upper_left_x < 0) /* rounding errors may create a negative value */
7629       {
7630         scanner->device->upper_left_x = 0; /* but negative values are not allowed */
7631       }
7632     }
7633 
7634     scanner->params.bytes_per_line  = scanner->device->row_len;
7635     scanner->params.pixels_per_line = scanner->device->width_in_pixels;
7636     scanner->params.lines           = scanner->device->length_in_pixels;
7637 
7638 
7639     /* set exposure times */
7640     if ( scanner->device->inquiry_exposure_adj )
7641     {
7642       umax_calculate_exposure_time(scanner->device, scanner->device->use_exposure_time_def_r, &scanner->device->exposure_time_calibration_r);
7643       umax_calculate_exposure_time(scanner->device, scanner->device->use_exposure_time_def_g, &scanner->device->exposure_time_calibration_g);
7644       umax_calculate_exposure_time(scanner->device, scanner->device->use_exposure_time_def_b, &scanner->device->exposure_time_calibration_b);
7645 
7646       umax_calculate_exposure_time(scanner->device, scanner->device->use_exposure_time_def_r, &scanner->device->exposure_time_scan_r);
7647       umax_calculate_exposure_time(scanner->device, scanner->device->use_exposure_time_def_g, &scanner->device->exposure_time_scan_g);
7648       umax_calculate_exposure_time(scanner->device, scanner->device->use_exposure_time_def_b, &scanner->device->exposure_time_scan_b);
7649     }
7650     else
7651     {
7652       scanner->device->exposure_time_calibration_r = scanner->device->exposure_time_calibration_g = scanner->device->exposure_time_calibration_b =
7653       scanner->device->exposure_time_scan_r = scanner->device->exposure_time_scan_g = scanner->device->exposure_time_scan_b = 0;
7654     }
7655 
7656 
7657     scanner->scanning = SANE_TRUE;
7658     sane_get_parameters(scanner, 0);
7659 
7660     DBG(DBG_sane_info,"x_resolution (dpi)      = %u\n", scanner->device->x_resolution);
7661     DBG(DBG_sane_info,"y_resolution (dpi)      = %u\n", scanner->device->y_resolution);
7662     DBG(DBG_sane_info,"x_coordinate_base (dpi) = %u\n", scanner->device->x_coordinate_base);
7663     DBG(DBG_sane_info,"y_coordinate_base (dpi) = %u\n", scanner->device->y_coordinate_base);
7664     DBG(DBG_sane_info,"upper_left_x (xbase)    = %d\n", scanner->device->upper_left_x);
7665     DBG(DBG_sane_info,"upper_left_y (ybase)    = %d\n", scanner->device->upper_left_y);
7666     DBG(DBG_sane_info,"scanwidth    (xbase)    = %u\n", scanner->device->scanwidth);
7667     DBG(DBG_sane_info,"scanlength   (ybase)    = %u\n", scanner->device->scanlength);
7668     DBG(DBG_sane_info,"width in pixels         = %u\n", scanner->device->width_in_pixels);
7669     DBG(DBG_sane_info,"length in pixels        = %u\n", scanner->device->length_in_pixels);
7670     DBG(DBG_sane_info,"bits per pixel/color    = %u\n", scanner->device->bits_per_pixel);
7671     DBG(DBG_sane_info,"bytes per line          = %d\n", scanner->params.bytes_per_line);
7672     DBG(DBG_sane_info,"pixels_per_line         = %d\n", scanner->params.pixels_per_line);
7673     DBG(DBG_sane_info,"lines                   = %d\n", scanner->params.lines);
7674     DBG(DBG_sane_info,"negative                = %d\n", scanner->device->reverse);
7675     DBG(DBG_sane_info,"threshold  (lineart)    = %d\n", scanner->device->threshold);
7676     DBG(DBG_sane_info,"brightness (halftone)   = %d\n", scanner->device->brightness);
7677     DBG(DBG_sane_info,"contrast   (halftone)   = %d\n", scanner->device->contrast);
7678 
7679     DBG(DBG_sane_info,"analog_gamma            = %d %d %d\n",
7680             scanner->device->analog_gamma_r,
7681             scanner->device->analog_gamma_g,
7682             scanner->device->analog_gamma_b);
7683     DBG(DBG_sane_info,"highlight               = %d %d %d\n",
7684             scanner->device->highlight_r,
7685             scanner->device->highlight_g,
7686             scanner->device->highlight_b);
7687     DBG(DBG_sane_info,"shadow                  = %d %d %d\n",
7688             scanner->device->shadow_r,
7689             scanner->device->shadow_g,
7690             scanner->device->shadow_b);
7691     DBG(DBG_sane_info,"calibrat. exposure time = %d %d %d\n",
7692             scanner->device->exposure_time_calibration_r,
7693             scanner->device->exposure_time_calibration_g,
7694             scanner->device->exposure_time_calibration_b);
7695     DBG(DBG_sane_info,"scan exposure time      = %d %d %d\n",
7696             scanner->device->exposure_time_scan_r,
7697             scanner->device->exposure_time_scan_g,
7698             scanner->device->exposure_time_scan_b);
7699 
7700 #ifdef UMAX_CALIBRATION_MODE_SELECTABLE
7701     DBG(DBG_sane_info,"calibration             = %s\n", scanner->val[OPT_CALIB_MODE].s);
7702 #endif
7703     DBG(DBG_sane_info,"calibration mode number = %d\n", scanner->device->calibration);
7704 
7705     DBG(DBG_sane_info,"batch scan              = %d\n", scanner->device->batch_scan);
7706     DBG(DBG_sane_info,"batch end               = %d\n", scanner->device->batch_end);
7707     DBG(DBG_sane_info,"batch next top left y   = %d\n", scanner->device->batch_next_tl_y);
7708     DBG(DBG_sane_info,"quality calibration     = %d\n", scanner->device->quality);
7709     DBG(DBG_sane_info,"warm up                 = %d\n", scanner->device->warmup);
7710     DBG(DBG_sane_info,"fast preview function   = %d\n", scanner->device->preview);
7711     DBG(DBG_sane_info,"DOR                     = %d\n", scanner->device->dor);
7712     DBG(DBG_sane_info,"ADF                     = %d\n", scanner->device->adf);
7713     DBG(DBG_sane_info,"manual focus            = %d\n", scanner->device->manual_focus);
7714     DBG(DBG_sane_info,"fix focus position      = %d\n", scanner->device->fix_focus_position);
7715     DBG(DBG_sane_info,"disable pre focus       = %d\n", scanner->device->disable_pre_focus);
7716     DBG(DBG_sane_info,"lens cal in doc pos     = %d\n", scanner->device->lens_cal_in_doc_pos);
7717     DBG(DBG_sane_info,"holder focus pos 0mm    = %d\n", scanner->device->holder_focus_pos_0mm);
7718 
7719     if (scanner->val[OPT_PREVIEW].w) /* preview mode */
7720     {
7721       scanner->device->lines_max = scanner->device->request_preview_lines;
7722     }
7723     else /* scan mode */
7724     {
7725       scanner->device->lines_max = scanner->device->request_scan_lines;
7726     }
7727 
7728 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
7729     {
7730      unsigned int scsi_bufsize  = 0;
7731 
7732       scsi_bufsize = scanner->device->width_in_pixels * scanner->device->lines_max;
7733 
7734       if (scsi_bufsize == 0) /* no scsi buffer size, take scanner buffer size */
7735       {
7736         scsi_bufsize = scanner->device->inquiry_vidmem;
7737       }
7738 
7739       if (scsi_bufsize < scanner->device->scsi_buffer_size_min) /* make sure buffer has at least minimum size */
7740       {
7741         scsi_bufsize = scanner->device->scsi_buffer_size_min;
7742       }
7743       else if (scsi_bufsize > scanner->device->scsi_buffer_size_max) /* make sure buffer does not exceed maximum size */
7744       {
7745         scsi_bufsize = scanner->device->scsi_buffer_size_max;
7746       }
7747 
7748       if (umax_scsi_open_extended(scanner->device->sane.name, scanner->device, sense_handler,
7749                                    scanner->device, (int *) &scsi_bufsize) != 0)
7750       {
7751         DBG(DBG_error, "ERROR: sane_start: open failed\n");
7752         scanner->scanning = SANE_FALSE;
7753         return SANE_STATUS_INVAL;
7754       }
7755 
7756       if (scsi_bufsize < scanner->device->scsi_buffer_size_min) /* minimum size must be available */
7757       {
7758         DBG(DBG_error, "ERROR: sane_start: umax_scsi_open_extended returned too small scsi buffer\n");
7759         umax_scsi_close((scanner->device));
7760         scanner->scanning = SANE_FALSE;
7761         return SANE_STATUS_NO_MEM;
7762       }
7763       DBG(DBG_info, "sane_start: umax_scsi_open_extended returned scsi buffer size = %d\n", scsi_bufsize);
7764 
7765       if (scsi_bufsize < scanner->device->width_in_pixels) /* print warning when buffer is smaller than one scanline */
7766       {
7767         DBG(DBG_warning, "WARNING: sane_start: scsi buffer is smaller than one scanline\n");
7768       }
7769 
7770       if (scsi_bufsize != scanner->device->bufsize)
7771       {
7772         DBG(DBG_info, "sane_start: buffer size has changed, reallocating buffer\n");
7773 
7774         if (scanner->device->buffer[0])
7775         {
7776           DBG(DBG_info, "sane_start: freeing SCSI buffer[0]\n");
7777           free(scanner->device->buffer[0]);									     /* free buffer */
7778         }
7779 
7780         scanner->device->bufsize = scsi_bufsize;
7781 
7782         DBG(DBG_info, "sane_start: allocating SCSI buffer[0]\n");
7783         scanner->device->buffer[0]  = malloc(scanner->device->bufsize);					  /* allocate buffer */
7784 
7785         if (!scanner->device->buffer[0]) /* malloc failed */
7786         {
7787           DBG(DBG_error, "ERROR: sane_start: could not allocate buffer[0]\n");
7788           umax_scsi_close(scanner->device);
7789           scanner->device->bufsize = 0;
7790           scanner->scanning = SANE_FALSE;
7791          return SANE_STATUS_NO_MEM;
7792         }
7793       }
7794     }
7795 #else
7796     if ( umax_scsi_open(scanner->device->sane.name, scanner->device, sense_handler,
7797                          scanner->device) != SANE_STATUS_GOOD )
7798     {
7799       scanner->scanning = SANE_FALSE;
7800       DBG(DBG_error, "ERROR: sane_start: open of %s failed:\n", scanner->device->sane.name);
7801       return SANE_STATUS_INVAL;
7802     }
7803 
7804     /* there is no need to reallocate the buffer because the size is fixed */
7805 #endif
7806 
7807     /* grab scanner */
7808     if (umax_grab_scanner(scanner->device))
7809     {
7810       umax_scsi_close(scanner->device);
7811       scanner->scanning = SANE_FALSE;
7812       DBG(DBG_warning,"WARNING: unable to reserve scanner: device busy\n");
7813      return SANE_STATUS_DEVICE_BUSY;
7814     }
7815 
7816 /* halftone pattern download is not ready in this version */
7817 #if 0
7818 										     /* send halftonepattern */
7819     if ( (strcmp(mode, HALFTONE_STR) == 0) || (strcmp(mode, COLOR_HALFTONE_STR) == 0) )
7820     {
7821       umax_send_halftone_pattern(scanner->device, (char *) &(scanner->halftone_pattern[0]),
7822                                  scanner->val[OPT_HALFTONE_DIMENSION].w );
7823       scanner->device->halftone = WD_halftone_download;
7824     }									      /* end of send halftonepattern */
7825 #endif
7826 
7827   } /* ------------ end of first call -------------- */
7828 
7829 
7830   /* send gammacurves */
7831   if (scanner->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE)
7832   {
7833     if (strcmp(mode, COLOR_STR) == 0)
7834     {
7835       if (scanner->device->three_pass == 0)					      /* one pass color scan */
7836       {
7837        unsigned int i, dest, color, value;
7838        char *gamma;
7839 
7840         gamma = malloc( (size_t) (3 * scanner->gamma_length * scanner->output_bytes) );
7841         if (gamma == NULL)
7842         {
7843           DBG(DBG_warning,"WARNING: not able to allocate memory for gamma table, gamma ignored !!!\n");
7844         }
7845         else
7846         {
7847           dest=0;
7848           for(color=1; color <= 3; color++)
7849           {
7850             for(i=0; i < scanner->gamma_length; i++)
7851             {
7852               value = scanner->gamma_table[color][i];
7853               if (scanner->output_bytes == 2)
7854               {
7855                 gamma[dest++] = scanner->gamma_table[0][value] / 256;
7856               }
7857               gamma[dest++] = (scanner->gamma_table[0][value] & 255);
7858             }
7859           }
7860 
7861           DBG(DBG_sane_info,"sending 3 * %d bytes of gamma data for RGB\n",
7862               scanner->gamma_length * scanner->output_bytes);
7863 
7864           umax_send_gamma_data(scanner->device, &gamma[0], 3);
7865           scanner->device->digital_gamma_r =
7866           scanner->device->digital_gamma_g =
7867           scanner->device->digital_gamma_b = WD_gamma_download;
7868           free(gamma);
7869         }
7870       }
7871       else									    /* three pass color scan */
7872       {
7873        unsigned int i, dest, color, value;
7874        char *gamma;
7875 
7876         gamma = malloc( (size_t) (scanner->gamma_length * scanner->output_bytes) );
7877         if (gamma == NULL)
7878         {
7879           DBG(DBG_warning,"not able to allocate memory for gamma table, gamma ignored !!!\n");
7880         }
7881         else
7882         {
7883           dest  = 0;
7884           color = scanner->device->three_pass_color;
7885 
7886           for(i = 0; i < scanner->gamma_length; i++)
7887           {
7888             value = scanner->gamma_table[color][i];
7889 
7890             if (scanner->output_bytes == 2)
7891             {
7892               gamma[dest++] = scanner->gamma_table[0][value] / 256;
7893             }
7894             gamma[dest++] = (scanner->gamma_table[0][value] & 255);
7895           }
7896 
7897           DBG(DBG_sane_info,"sending %d bytes of gamma data for color %d\n",
7898               scanner->gamma_length * scanner->output_bytes, color);
7899 
7900           umax_send_gamma_data(scanner->device, &gamma[0], 1);
7901           scanner->device->digital_gamma_r =
7902           scanner->device->digital_gamma_g =
7903           scanner->device->digital_gamma_b = WD_gamma_download;
7904           free(gamma);
7905         }
7906       }
7907     }
7908     else if (strcmp(mode, GRAY_STR) == 0) /* grayscale scan */
7909     {
7910      unsigned int i, dest;
7911      char *gamma;
7912 
7913       gamma = malloc( (size_t) (scanner->gamma_length * scanner->output_bytes) );
7914       if (gamma == NULL)
7915       {
7916         DBG(DBG_warning,"WARNING: not able to allocate memory for gamma table, gamma ignored !!!\n");
7917       }
7918       else
7919       {
7920         dest=0;
7921         for(i=0; i < scanner->gamma_length; i++)
7922         {
7923             if (scanner->output_bytes == 2)
7924             {
7925               gamma[dest++] = scanner->gamma_table[0][i] / 256;
7926             }
7927             gamma[dest++] = (scanner->gamma_table[0][i] & 255);
7928         }
7929 
7930         DBG(DBG_sane_info,"sending %d bytes of gamma data for gray\n",
7931             scanner->gamma_length * scanner->output_bytes);
7932 
7933         umax_send_gamma_data(scanner->device, &gamma[0], 1);
7934         scanner->device->digital_gamma_r = WD_gamma_download;
7935 	free(gamma);
7936       }
7937     }
7938   }										  /* end of send gammacurves */
7939 
7940   if ( scanner->device->three_pass_color > WD_wid_red) /* three pass scan, not first pass */
7941   {
7942     umax_reposition_scanner(scanner->device);
7943   }
7944 
7945   umax_set_window_param(scanner->device);
7946   status = umax_start_scan(scanner->device);
7947   if (status) /* error */
7948   {
7949     umax_give_scanner(scanner->device); /* reposition and release scanner */
7950     return status;
7951   }
7952 
7953   pause = scanner->device->pause_for_color_calibration;
7954 
7955   if (scanner->device->colormode != RGB)
7956   {
7957     pause = scanner->device->pause_for_gray_calibration;
7958   }
7959 
7960   if (pause) /* Astra 2400S needs this pause (7sec in color, 4sec in gray mode) */
7961   {
7962     DBG(DBG_info2,"pause for calibration %d msec ...\n", pause);
7963     usleep(((long) pause) * 1000); /* time in ms */
7964     DBG(DBG_info2,"pause done\n");
7965   }
7966 
7967   status = umax_do_calibration(scanner->device);
7968   if (status) /* error */
7969   {
7970     umax_give_scanner(scanner->device); /* reposition and release scanner */
7971     return status;
7972   }
7973 
7974   if (scanner->device->pause_after_calibration) /* may be useful */
7975   {
7976     DBG(DBG_info2,"pause after calibration %d msec ...\n", scanner->device->pause_after_calibration);
7977     usleep(((long) scanner->device->pause_after_calibration) * 1000); /* time in ms */
7978     DBG(DBG_info2,"pause done\n");
7979   }
7980 
7981 
7982   if (pipe(fds) < 0)
7983   {
7984     DBG(DBG_error,"ERROR: could not create pipe\n");
7985     scanner->scanning = SANE_FALSE;
7986     umax_give_scanner(scanner->device); /* reposition and release scanner */
7987     umax_scsi_close(scanner->device);
7988    return SANE_STATUS_IO_ERROR;
7989   }
7990 
7991   scanner->pipe_read_fd  = fds[0];
7992   scanner->pipe_write_fd = fds[1];
7993 
7994   /* start reader_process, deponds on OS if fork() or threads are used */
7995   scanner->reader_pid = sanei_thread_begin(reader_process, (void *) scanner);
7996 
7997   if (!sanei_thread_is_valid (scanner->reader_pid))
7998   {
7999     DBG(DBG_error, "ERROR: sanei_thread_begin failed (%s)\n", strerror(errno));
8000     scanner->scanning = SANE_FALSE;
8001     umax_give_scanner(scanner->device); /* reposition and release scanner */
8002     umax_scsi_close(scanner->device);
8003     return SANE_STATUS_NO_MEM; /* any other reason than no memory possible ? */
8004   }
8005 
8006   if (sanei_thread_is_forked())
8007   {
8008     close(scanner->pipe_write_fd);
8009     scanner->pipe_write_fd = -1;
8010   }
8011 
8012  return SANE_STATUS_GOOD;
8013 }
8014 
8015 
8016 /* ------------------------------------------------------------ SANE READ ---------------------------------- */
8017 
8018 
sane_read(SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len, SANE_Int *len)8019 SANE_Status sane_read(SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len, SANE_Int *len)
8020 {
8021  Umax_Scanner *scanner = handle;
8022  ssize_t nread;
8023 
8024   *len = 0;
8025 
8026   nread = read(scanner->pipe_read_fd, buf, max_len);
8027 
8028   DBG(DBG_sane_info, "sane_read: read %ld bytes\n", (long) nread);
8029 
8030   if (!(scanner->scanning)) /* OOPS, not scanning */
8031   {
8032     return do_cancel(scanner);
8033   }
8034 
8035   if (nread < 0)
8036   {
8037     if (errno == EAGAIN)
8038     {
8039       DBG(DBG_sane_info, "sane_read: EAGAIN\n");
8040       return SANE_STATUS_GOOD;
8041     }
8042     else
8043     {
8044       do_cancel(scanner); /* we had an error, stop scanner */
8045      return SANE_STATUS_IO_ERROR;
8046     }
8047   }
8048 
8049   *len = nread;
8050 
8051   if (nread == 0) /* EOF */
8052   {
8053     if ( (scanner->device->three_pass == 0) ||
8054          (scanner->device->colormode <= RGB_LINEART) ||
8055          (++(scanner->device->three_pass_color) > 3) )
8056     {
8057       do_cancel(scanner);
8058     }
8059 
8060     DBG(DBG_sane_proc,"closing read end of pipe\n");
8061 
8062     if (scanner->pipe_read_fd >= 0)
8063     {
8064       close(scanner->pipe_read_fd);
8065       scanner->pipe_read_fd = -1;
8066     }
8067 
8068     return SANE_STATUS_EOF;
8069   }
8070 
8071  return SANE_STATUS_GOOD;
8072 }
8073 
8074 
8075 /* ------------------------------------------------------------ SANE CANCEL -------------------------------- */
8076 
8077 
sane_cancel(SANE_Handle handle)8078 void sane_cancel(SANE_Handle handle)
8079 {
8080  Umax_Scanner *scanner = handle;
8081 
8082   DBG(DBG_sane_init,"sane_cancel\n");
8083 
8084   if (scanner->scanning)
8085   {
8086     do_cancel(scanner);
8087   }
8088 }
8089 
8090 
8091 /* ------------------------------------------------------------ SANE SET IO MODE --------------------------- */
8092 
8093 
sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)8094 SANE_Status sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)
8095 {
8096  Umax_Scanner *scanner = handle;
8097 
8098   DBG(DBG_sane_init,"sane_set_io_mode: non_blocking=%d\n", non_blocking);
8099 
8100   if (!scanner->scanning) { return SANE_STATUS_INVAL; }
8101 
8102   if (fcntl(scanner->pipe_read_fd, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0)
8103   {
8104     return SANE_STATUS_IO_ERROR;
8105   }
8106  return SANE_STATUS_GOOD;
8107 }
8108 
8109 
8110 /* ------------------------------------------------------------ SANE GET SELECT FD ------------------------- */
8111 
8112 
sane_get_select_fd(SANE_Handle handle, SANE_Int *fd)8113 SANE_Status sane_get_select_fd(SANE_Handle handle, SANE_Int *fd)
8114 {
8115  Umax_Scanner *scanner = handle;
8116 
8117   DBG(DBG_sane_init,"sane_get_select_fd\n");
8118 
8119   if (!scanner->scanning)
8120   {
8121     return SANE_STATUS_INVAL;
8122   }
8123 
8124   *fd = scanner->pipe_read_fd;
8125 
8126  return SANE_STATUS_GOOD;
8127 }
8128 
8129 /* ------------------------------------------------------------ EOF ---------------------------------------- */
8130