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