1 /* sane - Scanner Access Now Easy.
2
3 This file is part of the SANE package, and implements a SANE backend
4 for various Fujitsu scanners.
5
6 Copyright (C) 2000 Randolph Bentson
7 Copyright (C) 2001 Frederik Ramm
8 Copyright (C) 2001-2004 Oliver Schirrmeister
9 Copyright (C) 2003-2022 m. allan noah
10
11 JPEG output and low memory usage support funded by:
12 Archivista GmbH, www.archivista.ch
13 Endorser support funded by:
14 O A S Oilfield Accounting Service Ltd, www.oas.ca
15 Automatic length detection support funded by:
16 Martin G. Miller, mgmiller at optonline.net
17 Software image enhancement routines and recent scanner support funded by:
18 PFU America, Inc., fujitsuscanners.com
19
20 --------------------------------------------------------------------------
21
22 This program is free software; you can redistribute it and/or
23 modify it under the terms of the GNU General Public License as
24 published by the Free Software Foundation; either version 2 of the
25 License, or (at your option) any later version.
26
27 This program is distributed in the hope that it will be useful, but
28 WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 General Public License for more details.
31
32 You should have received a copy of the GNU General Public License
33 along with this program. If not, see <https://www.gnu.org/licenses/>.
34
35 As a special exception, the authors of SANE give permission for
36 additional uses of the libraries contained in this release of SANE.
37
38 The exception is that, if you link a SANE library with other files
39 to produce an executable, this does not by itself cause the
40 resulting executable to be covered by the GNU General Public
41 License. Your use of that executable is in no way restricted on
42 account of linking the SANE library code into it.
43
44 This exception does not, however, invalidate any other reasons why
45 the executable file might be covered by the GNU General Public
46 License.
47
48 If you submit changes to SANE to the maintainers to be included in
49 a subsequent release, you agree by submitting the changes that
50 those changes may be distributed with this exception intact.
51
52 If you write modifications of your own for SANE, it is your choice
53 whether to permit this exception to apply to your modifications.
54 If you do not wish that, delete this exception notice.
55
56 --------------------------------------------------------------------------
57
58 The source code is divided in sections which you can easily find by
59 searching for the tag "@@".
60
61 Section 1 - Boilerplate: Init & static stuff
62 Section 2 - Init: sane_init, _get_devices, _open ...
63 Section 3 - Options: sane_*_option functions
64 Section 4 - Scanning: sane_start, _get_param, _read ...
65 Section 5 - Cleanup: sane_cancel, ...
66 Section 6 - Misc: sense_handler, hexdump, ...
67 Section 7 - Image processing: deskew, crop, despeck
68
69 Changes:
70 v1, 2002-05-05, OS
71 - release memory allocated by sane_get_devices
72 - several bugfixes
73 - supports the M3097
74 - get threshold, contrast and brightness from vpd
75 - imprinter support
76 - get_hardware_status now works before calling sane_start
77 - avoid unnecessary reload of options when using source=fb
78 v2, 2002-08-08, OS
79 - bugfix. Imprinter didn't print the first time after
80 switching on the scanner
81 - bugfix. reader_generic_passthrough ignored the number of bytes
82 returned by the scanner
83 v3, 2002-09-13, OS
84 - 3092 support (mgoppold a t tbz-pariv.de)
85 - tested 4097 support
86 - changed some functions to receive compressed data
87 v4, 2003-02-13, OS
88 - fi-4220C support (ron a t roncemer.com)
89 - SCSI over USB support (ron a t roncemer.com)
90 v5, 2003-02-20, OS
91 - set availability of options THRESHOLD und VARIANCE
92 - option RIF is available for 3091 and 3092
93 v6, 2003-03-04, OS
94 - renamed some variables
95 - bugfix: duplex scanning now works when disconnect is enabled
96 v7, 2003-03-10, OS
97 - displays the offending byte in the window descriptor block
98 v8, 2003-03-28, OS
99 - fi-4120C support, MAN
100 - display information about gamma in vital_product_data
101 v9 2003-06-04, MAN
102 - separated the 4120 and 4220 into another model
103 - color support for the 4x20
104 v10 2003-06-04, MAN
105 - removed SP15 code
106 - sane_open actually opens the device you request
107 v11 2003-06-11, MAN
108 - fixed bug in that code when a scanner is disconnected
109 v12 2003-10-06, MAN
110 - added code to support color modes of more recent scanners
111 v13 2003-11-07, OS
112 - Bugfix. If a scanner returned a color image
113 in format rr...r gg...g bb...b the reader process crashed
114 - Bugfix. Disable option gamma was for the fi-4120
115 v14 2003-12-15, OS
116 - Bugfix: set default threshold range to 0..255 There is a problem
117 with the M3093 when you are not allows to set the threshold to 0
118 - Bugfix: set the allowable x- and y-DPI values from VPD. Scanning
119 with x=100 and y=100 dpi with an fi4120 resulted in an image
120 with 100,75 dpi
121 - Bugfix: Set the default value of gamma to 0x80 for all scanners
122 that don't have built in gamma patterns
123 - Bugfix: fi-4530 and fi-4210 don't support standard paper size
124 v15 2003-12-16, OS
125 - Bugfix: pagewidth and pageheight were disabled for the fi-4530C
126 v16 2004-02-20, OS
127 - merged the 3092-routines with the 3091-routines
128 - inverted the image in mode color and grayscale
129 - jpg hardware compression support (fi-4530C)
130 v17 2004-03-04, OS
131 - enabled option dropoutcolor for the fi-4530C, and fi-4x20C
132 v18 2004-06-02, OS
133 - bugfix: can read duplex color now
134 v19 2004-06-28, MAN
135 - 4220 use model code not strcmp (stan a t saticed.me.uk)
136 v20 2004-08-24, OS
137 - bugfix: 3091 did not work since 15.12.2003
138 - M4099 supported (bw only)
139 v21 2006-05-01, MAN
140 - Complete rewrite, half code size
141 - better (read: correct) usb command support
142 - basic support for most fi-series
143 - most scanner capabilities read from VPD
144 - reduced model-specific code
145 - improved scanner detection/initialization
146 - improved SANE_Option handling
147 - basic button support
148 - all IPC and Imprinter options removed temporarily
149 - duplex broken temporarily
150 v22 2006-05-04, MAN
151 - do_scsi_cmd gets basic looping capability
152 - reverse now divided by mode
153 - re-write sane_fix/unfix value handling
154 - fix several bugs in options code
155 - some options' ranges modified by other options vals
156 - added advanced read-only options for all
157 known hardware sensors and buttons
158 - rewrote hw status function
159 - initial testing with M3091dc- color mode broken
160 v23 2006-05-14, MAN
161 - initial attempt to recover duplex mode
162 - fix bad usb prodID when config file missing
163 v24 2006-05-17, MAN
164 - sane_read must set len=0 when return != good
165 - simplify do_cmd() calls by removing timeouts
166 - lengthen most timeouts, shorten those for wait_scanner()
167 v25 2006-05-19, MAN
168 - rename scsi-buffer-size to buffer-size, usb uses it too
169 - default buffer-size increased to 64k
170 - use sanei_scsi_open_extended() to set buffer size
171 - fix some compiler warns: 32&64 bit gcc
172 v26 2006-05-23, MAN
173 - don't send scanner control (F1) if unsupported
174 v27 2006-05-30, MAN
175 - speed up hexdump (adeuring A T gmx D O T net)
176 - duplex request same size block from both sides
177 - don't #include or call sanei_thread
178 - split usb/scsi command DBG into 25 and 30
179 v28 2006-06-01, MAN
180 - sane_read() usleep if scanner is busy
181 - do_*_cmd() no looping (only one caller used it),
182 remove unneeded casts, cleanup/add error messages
183 - scanner_control() look at correct has_cmd_* var,
184 handles own looping on busy
185 v29 2006-06-04, MAN
186 - M3091/2 Color mode support (duplex still broken)
187 - all sensors option names start with 'button-'
188 - rewrite sane_read and helpers to use buffers,
189 currently an extreme waste of ram, but should
190 work with saned and scanimage -T
191 - merge color conversion funcs into read_from_buf()
192 - compare bytes tx v/s rx instead of storing EOFs
193 - remove scanner cmd buf, use buf per func instead
194 - print color and duplex raster offsets (inquiry)
195 - print EOM, ILI, and info bytes (request sense)
196 v30 2006-06-06, MAN
197 - M3091/2 duplex support, color/gray/ht/lineart ok
198 - sane_read helpers share code, report more errors
199 - add error msg if VPD missing or non-extended
200 - remove references to color_lineart and ht units
201 - rework init_model to support more known models
202 - don't send paper size data if using flatbed
203 v31 2006-06-13, MAN
204 - add 5220C usb id
205 - don't show ink level buttons if no imprinter
206 - run ghs/rs every second instead of every other
207 v32 2006-06-14, MAN
208 - add 4220C2 usb id
209 v33 2006-06-14, MAN (SANE v1.0.18)
210 - add Fi-5900 usb id and init_model section
211 v34 2006-07-04, MAN
212 - add S500 usb id
213 - gather more data from inq and vpd
214 - allow background color setting
215 v35 2006-07-05, MAN
216 - allow double feed sensor settings
217 - more consistent naming of global strings
218 v36 2006-07-06, MAN
219 - deal with fi-5900 even bytes problem
220 - less verbose calculateDerivedValues()
221 v37 2006-07-14, MAN
222 - mode sense command support
223 - detect mode page codes instead of hardcoding
224 - send command support
225 - brightness/contrast support via LUT
226 - merge global mode page buffers
227 v38 2006-07-15, MAN
228 - add 'useless noise' debug level (35)
229 - move mode sense probe errors to DBG 35
230 v39 2006-07-17, MAN
231 - rewrite contrast slope math for readability
232 v40 2006-08-26, MAN
233 - rewrite brightness/contrast more like xsane
234 - initial gamma support
235 - add fi-5530 usb id
236 - rewrite do_*_cmd functions to handle short reads
237 and to use ptr to return read in length
238 - new init_user function split from init_model
239 - init_vpd allows short vpd block for older models
240 - support MS buffer (s.scipioni AT harvardgroup DOT it)
241 - support MS prepick
242 - read only 1 byte of mode sense output
243 v41 2006-08-28, MAN
244 - do_usb_cmd() returns io error on cmd/out/status/rs EOF
245 - fix bug in MS buffer/prepick scsi data block
246 v42 2006-08-31, MAN
247 - fix bug in get_hardware_status (#303798)
248 v43 2006-09-19, MAN
249 - add model-specific code to init_vpd for M3099
250 v44 2007-01-26, MAN
251 - set SANE_CAP_HARD_SELECT on all buttons/sensors
252 - disable sending gamma LUT, seems wrong on some units?
253 - support MS overscan
254 - clamp the scan area to the pagesize on ADF
255 v45 2007-01-28, MAN
256 - update overscan code to extend max scan area
257 v46 2007-03-08, MAN
258 - tweak fi-4x20c2 and M3093 settings
259 - add fi-5110EOXM usb id
260 - add M3093 non-alternating duplex code
261 v47 2007-04-13, MAN
262 - change window_gamma determination
263 - add fi-5650C usb id and color mode
264 v48 2007-04-16, MAN
265 - re-enable brightness/contrast for built-in models
266 v49 2007-06-28, MAN
267 - add fi-5750C usb id and color mode
268 v50 2007-07-10, MAN
269 - updated overscan and bgcolor option descriptions
270 - added jpeg output support
271 - restructured usb reading code to use RS len for short reads
272 - combined calcDerivedValues with sane_get_params
273 v51 2007-07-26, MAN
274 - fix bug in jpeg output support
275 v52 2007-07-27, MAN
276 - remove unused jpeg function
277 - reactivate look-up-table based brightness and contrast options
278 - change range of hardware brightness/contrast to match LUT versions
279 - call send_lut() from sane_control_option instead of sane_start
280 v53 2007-11-18, MAN
281 - add S510 usb id
282 - OPT_NUM_OPTS type is SANE_TYPE_INT (jblache)
283 v54 2007-12-29, MAN
284 - disable SANE_FRAME_JPEG support until SANE 1.1.0
285 v55 2007-12-29, MAN (SANE v1.0.19)
286 - add S500M usb id
287 v56 2008-02-14, MAN
288 - sanei_config_read has already cleaned string (#310597)
289 v57 2008-02-24, MAN
290 - fi-5900 does not (initially) interlace colors
291 - add mode sense for color interlacing? (page code 32)
292 - more debug output in init_ms()
293 v58 2008-04-19, MAN
294 - page code 32 is not color interlacing, rename to 'unknown'
295 - increase number of bytes in response buffer of init_ms()
296 - protect debug modification code in init_ms() if NDEBUG is set
297 - proper async sane_cancel support
298 - re-enable JPEG support
299 - replace s->img_count with s->side
300 - sane_get_parameters(): don't round up larger than current paper size
301 - sane_start() rewritten, shorter, more clear
302 - return values are SANE_Status, not int
303 - hide unused functions
304 v59 2008-04-22, MAN
305 - add fi-6140 usb ID, and fi-6x40 color mode
306 v60 2008-04-27, MAN
307 - move call to sanei_usb_init() from sane_init() to find_scanners
308 - free sane_devArray before calloc'ing a new one
309 v61 2008-05-11, MAN
310 - minor cleanups to init_ms()
311 - add fi-5530C2 usb id
312 - merge find_scanners into sane_get_devices
313 - inspect correct bool to enable prepick mode option
314 v62 2008-05-20, MAN
315 - check for all supported scsi commands
316 - use well-known option group strings from saneopts.h
317 - rename pagewidth to page-width, to meet sane 1.1.0, same for height
318 - add unused get_window()
319 v63 2008-05-21, MAN
320 - use sane 1.1.0 well-known option names for some buttons
321 - remove 'button-' from other buttons and sensors
322 v64 2008-05-28, MAN
323 - strcpy device_name[] instead of strdup/free *device_name
324 - add send/read diag commands to get scanner serial number
325 - use model and serial to build sane.name (idea from Ryan Duryea)
326 - allow both serial_name and device_name to sane_open scanner
327 - correct mode select/sense 6 vs 10 booleans
328 - rename product_name to model_name
329 - simulate missing VPD data for M3097G
330 - hide get_window
331 - improve handling of vendor unique section of set_window
332 - add init_interlace to detect proper color mode without hardcoding
333 - add ascii output to hexdump
334 v65 2008-06-24, MAN
335 - detect endorser type during init_inquiry()
336 - add endorser options
337 - add send_endorser() and call from sane_control_option()
338 - add endorser() and call from sane_start()
339 - convert set_window() to use local cmd and payload copies
340 - remove get_window()
341 - mode_select_buff() now clears the buffer, and called in sane_close()
342 - fi-4990 quirks added, including modified even_scan_line code
343 v66 2008-06-26, MAN
344 - restructure double feed detection options for finer-grained control
345 - add endorser side option
346 - prevent init_interlace() from overriding init_model()
347 - simplify sane_start() and fix interlaced duplex jpeg support
348 - simplify sane_read() and add non-interlaced duplex jpeg support
349 - removed unused code
350 v67 2008-07-01, MAN
351 - add IPC/DTC/SDTC options
352 - call check_for_cancel() in sane_cancel, unless s->reader flag is set
353 v68 2008-07-02, MAN
354 - add halftone type and pattern options
355 - support M3097G with IPC and CMP options via modified VPD response
356 v69 2008-07-03, MAN
357 - support hot-unplugging scanners
358 v70 2008-07-05, MAN
359 - fix bug in sane_get_parameters (failed to copy values)
360 - autodetect jpeg duplex interlacing mode by inspecting scan width
361 v71 2008-07-13, MAN
362 - disable overscan option if vpd does not tell overscan size
363 - fi-5110EOX crops scan area based on absolute maximum, not paper
364 - fi-5530C/2 and fi-5650C can't handle 10 bit LUT via USB
365 - fi-5900 has background color, though it reports otherwise
366 v72 2008-07-13, MAN
367 - use mode_sense to determine background color support
368 - remove fi-5900 background color override
369 v73 2008-07-14, MAN
370 - correct overscan dimension calculation
371 - provide correct overscan size overrides for fi-5110C and fi-4x20C2
372 - add fi-6130 usb ID
373 - fi-5750C can't handle 10 bit LUT via USB
374 v74 2008-08-02, MAN
375 - replace global scsi blocks with local ones in each function
376 v75 2008-08-07, ReneR
377 - added fi-6230 usb ID
378 v76 2008-08-13, MAN
379 - add independent maximum area values for flatbed
380 - override said values for fi-4220C, fi-4220C2 and fi-5220C
381 v77 2008-08-26, MAN
382 - override flatbed maximum area for fi-6230C and fi-6240C
383 - set PF bit in all mode_select(6) CDB's
384 - set SANE_CAP_INACTIVE on all disabled options
385 - fix bug in mode_select page for sleep timer
386 v78 2008-08-26, MAN
387 - recent model names (fi-6xxx) don't end in 'C'
388 - simplify flatbed area overrides
389 - call scanner_control to change source during sane_start
390 v79 2008-10-01, MAN
391 - add usb ids for several models
392 - print additional hardware capability bits
393 - detect front-side endorser
394 - disable endorser-side controls if only one side installed
395 - add quirks for fi-6x70
396 v80 2008-10-08, MAN
397 - front-side endorser uses data ID 0x80
398 v81 2008-10-20, MAN
399 - increase USB timeouts
400 - enable get_pixelsize() to update scan params after set_window()
401 - remove even_scan_line hack
402 v82 2008-10-31, MAN
403 - improved front-side endorser vpd detection
404 - send scanner_control_ric during sane_read of each side
405 - add fi-6770A and fi-6670A USB ID's
406 v83 2008-11-06, MAN
407 - round binary bpl and Bpl up to byte boundary
408 - use s->params instead of user data in set_window()
409 - read_from_scanner() only grabs an even number of lines
410 v84 2008-11-07, MAN
411 - round lines down to even number to get even # of total bytes
412 - round binary bpl and Bpl down to byte boundary
413 v85 2008-12-10, MAN
414 - round pixels_per_line down to arbitrary limits for fi-4990 & fi-4860
415 - fi-4860 returns random garbage to serial number queries
416 - initialize *info to 0 in sane_control_option()
417 v86 2008-12-18, MAN
418 - get_pixelsize() sets back window ID for back side scans
419 v87 2008-12-21, MAN
420 - accept null pointer as empty device name
421 - track frontend reading sensor/button values to reload
422 - deactivate double feed options if df-action == default
423 v88 2009-01-21, MAN
424 - don't export private symbols
425 v89 2009-02-20, MAN
426 - fi-4750 returns random garbage to serial number queries
427 v90 2009-02-23, MAN
428 - added ScanSnap S510M usb ids
429 v91 2009-03-20, MAN
430 - remove unused temp file code
431 v92 2009-04-12, MAN
432 - disable SANE_FRAME_JPEG support (again)
433 v93 2009-04-14, MAN (SANE 1.0.20)
434 - return cmd status for reads on sensors
435 - ignore errors in scanner_control(),
436 M3091 has not worked since sane 1.0.19, due to this.
437 - copy_buffer needs to count lines, or M309[12] cannot duplex
438 v94 2009-05-22, MAN
439 - add side option to show which duplex image is being transferred
440 - convert front and simplex buffers to use much less ram
441 - add lowmemory option which makes duplex back buffer small too
442 - refactor image handling code to track eof's instead of lengths
443 - do color deinterlacing after reading from scanner, before buffering
444 v95 2009-06-02, MAN
445 - scanner_control_ric should return a subset of the possible errors
446 v96 2009-08-07, MAN
447 - split sane_get_parameters into two functions
448 - remove unused code from get_pixelsize
449 - support hardware based auto length detection
450 v97 2009-09-14, MAN
451 - use sanei_magic to provide software deskew, autocrop and despeckle
452 v98 2010-02-09, MAN (SANE 1.0.21)
453 - clean up #include lines and copyright
454 - add SANE_I18N to static strings
455 - don't fail if scsi buffer is too small
456 - disable bg_color for S1500
457 - enable flatbed for M3092
458 v99 2010-05-14, MAN
459 - sense_handler(): collect rs_info for any ILI, not just EOM
460 - do_usb_cmd(): use rs_info whenever set, not just EOF
461 - read_from_*(): better handling of EOF from lower level functions
462 - sane_read(): improve duplexing logic
463 v100 2010-06-01, MAN
464 - store more Request Sense data in scanner struct
465 - clear Request Sense data at start of every do_cmd() call
466 - track per-side ILI and global EOM flags
467 - set per-side EOF flag if ILI and EOM are set
468 v101 2010-06-23, MAN
469 - fix compilation bug when jpeg is enabled
470 v102 2010-09-22, MAN
471 - fix infinite loop when scan is an odd number of lines
472 v103 2010-11-23, MAN
473 - remove compiled-in default config file
474 - initial support for new fi-6xxx machines
475 v104 2010-11-24, MAN
476 - never request more than s->buffer_size from scanner
477 - silence noisy set_window() calls from init_interlace()
478 v105 2010-12-02, MAN
479 - backup and restore image params around image processing code
480 - cache software crop/deskew parameters for use on backside of duplex
481 - fi-6110 does not support bgcolor or prepick
482 v106 2011-01-30, MAN (SANE 1.0.22)
483 - don't call mode_select with a page code the scanner does not support
484 v107 2011-11-03, MAN
485 - M3091 does not support scanner_control(adf)
486 - Correct buffer overflow in read_from_3091duplex()
487 - sane_read() now always calls read_from_*()
488 - read_from_*() are callable when there is no data, and read to eof
489 - sane_read() will keep alternate duplex reads to similar length
490 - Added debugging statements
491 - Corrected comments
492 - Updated Copyright
493 v108 2011-11-21, MAN
494 - merged x/y resolution options
495 - moved page width/height to start of geometry group
496 - use mode to pick resolution list v/s range
497 - improved M3091 resolution choices
498 v109 2011-12-20, MAN
499 - added some MS and INQ information
500 - increased default buffer size for later machines in config file
501 - renamed new fi-6xx0Z models
502 v110 2012-05-09, MAN
503 - correct max_y_fb for fi-62x0 series
504 - add must_fully_buffer helper routine
505 - add hwdeskewcrop option, with fallback to software versions
506 - add 'actual' param to get_pixelsize for post-scan
507 - add recent model VPD params
508 - only set params->lines = -1 when using ald without buffering
509 - fix bugs in background color when using software deskew
510 v111 2012-05-10, MAN (SANE 1.0.23)
511 - call send_* and mode_select_* from sane_start
512 - split read payloads into new debug level
513 - add paper-protect, staple-detect and df-recovery options
514 v112 2013-02-22, MAN
515 - some scanners (fi-6x70 and later) don't enable IPC by default
516 v113 2013-02-24, MAN
517 - support for ScanSnap iX500
518 - fix bug with jpeg de-interlacing code
519 - allow has_MS_* and has_pixelsize to be set in init_model
520 - fix use of uninitialized buffer in send_lut
521 - add send_q_table()
522 - allow wait_scanner() to be bypassed in object_position
523 - moved send_lut() to after set_window
524 v114 2013-03-01, MAN
525 - support resolutions > 300 for iX500 using diag_preread()
526 - remove most communication with scanner during sane_control_option()
527 v115 2013-03-09, MAN
528 - separate s->mode into s_mode and u_mode
529 - separate s->params into s_params and u_params
530 - generate grayscale and binary in software if required (iX500)
531 v116 2013-03-23, MAN
532 - call set_mode() in init_interlace
533 - add swskip option
534 v117 2013-06-11, MAN (SANE 1.0.24)
535 - default buffer-mode to off
536 - improved error handling in sane_start
537 - image width must be multiple of 8 when swcrop is used before binarization (iX500)
538 - check hopper sensor before calling object_position(load) on iX500
539 v118 2013-12-09, MAN
540 - support fi-7160, fi-7260, fi-7180 and fi-7280
541 - remove unused var from do_scsi_cmd()
542 - added more request_sense options
543 - add adv_paper_protect option
544 - enable paper protection by default
545 - increase max_x_fb for fi-6240 and fi-6230
546 v119 2013-12-18, MAN
547 - call get_pixelsize after start_scan, not before
548 - extend get_pixelsize to request backside data
549 - stop using backup/restore_params
550 - don't use extended get_pixelsize on M3091 or M3092
551 - call software crop code on backside images too
552 v120 2014-01-29, MAN
553 - only call hopper_before_op code at batch start
554 - remove unused backup/restore_params
555 v121 2014-04-07, MAN
556 - add JFIF APP0 marker with resolution to jpeg images
557 - improve jpeg duplex parsing code
558 - simplify jpeg ifdefs
559 - add offtimer option for more recent scanners
560 - don't print 0 length line in hexdump
561 v122 2014-10-28, MAN
562 - add support for object_position halt
563 - call object_position halt in check_for_cancel when requested
564 v123 2014-11-06, MAN
565 - workaround Linux USB3 bugs by adding command counting code and
566 sending an even number of reads and writes during disconnect_fd
567 v124 2014-12-09, MAN
568 - support resolution controlled max page-height (fi-6/7xxx scanners)
569 - reorder scanner sections in init_model chronologically
570 v125 2014-12-16, MAN
571 - remove USB packet counting code from v123, fix sanei_usb instead
572 v126 2015-08-23, MAN
573 - initial support for iX100
574 - add late_lut support for iX500/iX100
575 v127 2015-08-25, MAN (SANE 1.0.25)
576 - separate iX100 from iX500 settings
577 - iX100 has gray and lineart
578 v128 2015-11-08, MAN
579 - do not ask fi-4340 for serial number
580 v129 2015-11-21, MAN
581 - br_x and br_y locked to page_width/height until changed
582 v130 2016-02-23, MAN
583 - run init_model before init_ms so some scanners can override
584 - set all M309x and M409x scanners s->broken_diag_serial = 1
585 v131 2016-06-06, MAN
586 - hide compression-arg option when jpeg disabled
587 - add Send/SC/GHS macros for recent scanners
588 - add initial support for fi-74x0
589 - add initial support for fi-7030
590 - set has_MS_lamp=0 for fi-71x0
591 - add I18N macros to all option titles and descriptions
592 v132 2016-10-07, MAN
593 - remove ipc_mode option and variables
594 - set ipc mode based on other options
595 - cleanup inverted logic DTC options
596 - fixes threshold option reported in #315069
597 v133 2017-04-08, MAN
598 - initial support for fi-7600/7700
599 - autodetect various double feed capabilities using VPD
600 - call send_lut if we are using a downloaded gamma table
601 v134 2019-02-23, MAN
602 - rewrite init_vpd for scanners which fail to report
603 overscan correctly
604 v135 2019-11-10, MAN (SANE 1.0.29)
605 - set has_MS_lamp=0 for fi-72x0, bug #134
606 v136 2020-02-07, MAN
607 - add support for fi-800R
608 - add support for card scanning slot (Return Path)
609 - fix bug with reading hardware sensors on first invocation
610 v137 2020-09-23, MAN
611 - fix JPEG duplex memory corruption
612 - change window_gamma init (fixes bright/contrast for iX1500)
613 - only call send_lut after set_window (remove late_lut)
614 v138 2022-06-01, MAN
615 - minor updates to company name (FCPA -> PFU)
616 v139 2022-11-15, MAN
617 - move updated window_gamma logic to set_window
618 - use internal gamma table if possible (fixes #618)
619
620 SANE FLOW DIAGRAM
621
622 - sane_init() : initialize backend
623 . - sane_get_devices() : query list of scanner devices
624 . - sane_open() : open a particular scanner device
625 . . - sane_set_io_mode : set blocking mode
626 . . - sane_get_select_fd : get scanner fd
627 . .
628 . . - sane_get_option_descriptor() : get option information
629 . . - sane_control_option() : change option values
630 . . - sane_get_parameters() : returns estimated scan parameters
631 . . - (repeat previous 3 functions)
632 . .
633 . . - sane_start() : start image acquisition
634 . . - sane_get_parameters() : returns actual scan parameters
635 . . - sane_read() : read image data (from pipe)
636 . . (sane_read called multiple times; after sane_read returns EOF,
637 . . loop may continue with sane_start which may return a 2nd page
638 . . when doing duplex scans, or load the next page from the ADF)
639 . .
640 . . - sane_cancel() : cancel operation
641 . - sane_close() : close opened scanner device
642 - sane_exit() : terminate use of backend
643
644 */
645
646 /*
647 * @@ Section 1 - Boilerplate
648 */
649
650 #include "../include/sane/config.h"
651
652 #include <string.h> /*memcpy...*/
653 #include <ctype.h> /*isspace*/
654 #include <math.h> /*tan*/
655 #include <unistd.h> /*usleep*/
656
657 #include "../include/sane/sanei_backend.h"
658 #include "../include/sane/sanei_scsi.h"
659 #include "../include/sane/sanei_usb.h"
660 #include "../include/sane/saneopts.h"
661 #include "../include/sane/sanei_config.h"
662 #include "../include/sane/sanei_magic.h"
663
664 #include "fujitsu-scsi.h"
665 #include "fujitsu.h"
666
667 #define DEBUG 1
668 #define BUILD 139
669
670 /* values for SANE_DEBUG_FUJITSU env var:
671 - errors 5
672 - function trace 10
673 - function detail 15
674 - get/setopt cmds 20
675 - scsi/usb trace 25
676 - scsi/usb writes 30
677 - scsi/usb reads 31
678 - useless noise 35
679 */
680
681 /* ------------------------------------------------------------------------- */
682 /* if JPEG support is not enabled in sane.h, we setup our own defines */
683 #ifndef SANE_FRAME_JPEG
684 #define SANE_FRAME_JPEG 0x0B
685 #define SANE_JPEG_DISABLED 1
686 #endif
687 /* ------------------------------------------------------------------------- */
688 #define STRING_FLATBED SANE_I18N("Flatbed")
689 #define STRING_ADFFRONT SANE_I18N("ADF Front")
690 #define STRING_ADFBACK SANE_I18N("ADF Back")
691 #define STRING_ADFDUPLEX SANE_I18N("ADF Duplex")
692 #define STRING_CARDFRONT SANE_I18N("Card Front")
693 #define STRING_CARDBACK SANE_I18N("Card Back")
694 #define STRING_CARDDUPLEX SANE_I18N("Card Duplex")
695
696 #define STRING_LINEART SANE_VALUE_SCAN_MODE_LINEART
697 #define STRING_HALFTONE SANE_VALUE_SCAN_MODE_HALFTONE
698 #define STRING_GRAYSCALE SANE_VALUE_SCAN_MODE_GRAY
699 #define STRING_COLOR SANE_VALUE_SCAN_MODE_COLOR
700
701 #define STRING_DEFAULT SANE_I18N("Default")
702 #define STRING_ON SANE_I18N("On")
703 #define STRING_OFF SANE_I18N("Off")
704
705 #define STRING_DTC SANE_I18N("DTC")
706 #define STRING_SDTC SANE_I18N("SDTC")
707
708 #define STRING_DITHER SANE_I18N("Dither")
709 #define STRING_DIFFUSION SANE_I18N("Diffusion")
710
711 #define STRING_RED SANE_I18N("Red")
712 #define STRING_GREEN SANE_I18N("Green")
713 #define STRING_BLUE SANE_I18N("Blue")
714 #define STRING_WHITE SANE_I18N("White")
715 #define STRING_BLACK SANE_I18N("Black")
716
717 #define STRING_NONE SANE_I18N("None")
718 #define STRING_JPEG SANE_I18N("JPEG")
719
720 #define STRING_CONTINUE SANE_I18N("Continue")
721 #define STRING_STOP SANE_I18N("Stop")
722
723 #define STRING_10MM SANE_I18N("10mm")
724 #define STRING_15MM SANE_I18N("15mm")
725 #define STRING_20MM SANE_I18N("20mm")
726
727 #define STRING_HORIZONTAL SANE_I18N("Horizontal")
728 #define STRING_HORIZONTALBOLD SANE_I18N("Horizontal bold")
729 #define STRING_HORIZONTALNARROW SANE_I18N("Horizontal narrow")
730 #define STRING_VERTICAL SANE_I18N("Vertical")
731 #define STRING_VERTICALBOLD SANE_I18N("Vertical bold")
732
733 #define STRING_TOPTOBOTTOM SANE_I18N("Top to bottom")
734 #define STRING_BOTTOMTOTOP SANE_I18N("Bottom to top")
735
736 #define STRING_FRONT SANE_I18N("Front")
737 #define STRING_BACK SANE_I18N("Back")
738
739 #define max(a,b) (((a)>(b))?(a):(b))
740
741 /* Also set via config file. */
742 static int global_buffer_size = 64 * 1024;
743
744 /*
745 * used by attach* and sane_get_devices
746 * a ptr to a null term array of ptrs to SANE_Device structs
747 * a ptr to a single-linked list of fujitsu structs
748 */
749 static const SANE_Device **sane_devArray = NULL;
750 static struct fujitsu *fujitsu_devList = NULL;
751
752 /*
753 * @@ Section 2 - SANE & scanner init code
754 */
755
756 /*
757 * Called by SANE initially.
758 *
759 * From the SANE spec:
760 * This function must be called before any other SANE function can be
761 * called. The behavior of a SANE backend is undefined if this
762 * function is not called first. The version code of the backend is
763 * returned in the value pointed to by version_code. If that pointer
764 * is NULL, no version code is returned. Argument authorize is either
765 * a pointer to a function that is invoked when the backend requires
766 * authentication for a specific resource or NULL if the frontend does
767 * not support authentication.
768 */
769 SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)770 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
771 {
772 (void) authorize; /* get rid of compiler warning */
773
774 DBG_INIT ();
775 DBG (10, "sane_init: start\n");
776
777 if (version_code)
778 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
779
780 DBG (5, "sane_init: fujitsu backend %d.%d.%d, from %s\n",
781 SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING);
782
783 sanei_magic_init();
784
785 DBG (10, "sane_init: finish\n");
786
787 return SANE_STATUS_GOOD;
788 }
789
790 /*
791 * Called by SANE to find out about supported devices.
792 *
793 * From the SANE spec:
794 * This function can be used to query the list of devices that are
795 * available. If the function executes successfully, it stores a
796 * pointer to a NULL terminated array of pointers to SANE_Device
797 * structures in *device_list. The returned list is guaranteed to
798 * remain unchanged and valid until (a) another call to this function
799 * is performed or (b) a call to sane_exit() is performed. This
800 * function can be called repeatedly to detect when new devices become
801 * available. If argument local_only is true, only local devices are
802 * returned (devices directly attached to the machine that SANE is
803 * running on). If it is false, the device list includes all remote
804 * devices that are accessible to the SANE library.
805 *
806 * SANE does not require that this function is called before a
807 * sane_open() call is performed. A device name may be specified
808 * explicitly by a user which would make it unnecessary and
809 * undesirable to call this function first.
810 */
811 /*
812 * Read the config file, find scanners with help from sanei_*
813 * and store in global device structs
814 */
815 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)816 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
817 {
818 SANE_Status ret = SANE_STATUS_GOOD;
819 struct fujitsu * s;
820 struct fujitsu * prev = NULL;
821 char line[PATH_MAX];
822 const char *lp;
823 FILE *fp;
824 int num_devices=0;
825 int i=0;
826
827 (void) local_only; /* get rid of compiler warning */
828
829 DBG (10, "sane_get_devices: start\n");
830
831 /* mark all existing scanners as missing, attach_one will remove mark */
832 for (s = fujitsu_devList; s; s = s->next) {
833 s->missing = 1;
834 }
835
836 sanei_usb_init();
837
838 /* set this to 64K before reading the file */
839 global_buffer_size = 64 * 1024;
840
841 fp = sanei_config_open (FUJITSU_CONFIG_FILE);
842
843 if (fp) {
844
845 DBG (15, "sane_get_devices: reading config file %s\n",
846 FUJITSU_CONFIG_FILE);
847
848 while (sanei_config_read (line, PATH_MAX, fp)) {
849
850 lp = line;
851
852 /* ignore comments */
853 if (*lp == '#')
854 continue;
855
856 /* skip empty lines */
857 if (*lp == 0)
858 continue;
859
860 if ((strncmp ("option", lp, 6) == 0) && isspace (lp[6])) {
861
862 lp += 6;
863 lp = sanei_config_skip_whitespace (lp);
864
865 /* we allow setting buffersize too big */
866 if ((strncmp (lp, "buffer-size", 11) == 0) && isspace (lp[11])) {
867
868 int buf;
869 lp += 11;
870 lp = sanei_config_skip_whitespace (lp);
871 buf = atoi (lp);
872
873 if (buf < 4096) {
874 DBG (5, "sane_get_devices: config option \"buffer-size\" (%d) is < 4096, ignoring!\n", buf);
875 continue;
876 }
877
878 if (buf > 64*1024) {
879 DBG (5, "sane_get_devices: config option \"buffer-size\" (%d) is > %d, warning!\n", buf, 64*1024);
880 }
881
882 DBG (15, "sane_get_devices: setting \"buffer-size\" to %d\n", buf);
883 global_buffer_size = buf;
884 }
885 else {
886 DBG (5, "sane_get_devices: config option \"%s\" unrecognized - ignored.\n", lp);
887 }
888 }
889 else if ((strncmp ("usb", lp, 3) == 0) && isspace (lp[3])) {
890 DBG (15, "sane_get_devices: looking for '%s'\n", lp);
891 sanei_usb_attach_matching_devices(lp, attach_one_usb);
892 }
893 else if ((strncmp ("scsi", lp, 4) == 0) && isspace (lp[4])) {
894 DBG (15, "sane_get_devices: looking for '%s'\n", lp);
895 sanei_config_attach_matching_devices (lp, attach_one_scsi);
896 }
897 else{
898 DBG (5, "sane_get_devices: config line \"%s\" unrecognized - ignored.\n", lp);
899 }
900 }
901 fclose (fp);
902 }
903
904 else {
905 DBG (5, "sane_get_devices: missing required config file '%s'!\n",
906 FUJITSU_CONFIG_FILE);
907 }
908
909 /*delete missing scanners from list*/
910 for (s = fujitsu_devList; s;) {
911 if(s->missing){
912 DBG (5, "sane_get_devices: missing scanner %s\n",s->device_name);
913
914 /*splice s out of list by changing pointer in prev to next*/
915 if(prev){
916 prev->next = s->next;
917 free(s);
918 s=prev->next;
919 }
920 /*remove s from head of list, using prev to cache it*/
921 else{
922 prev = s;
923 s = s->next;
924 free(prev);
925 prev=NULL;
926
927 /*reset head to next s*/
928 fujitsu_devList = s;
929 }
930 }
931 else{
932 prev = s;
933 s=prev->next;
934 }
935 }
936
937 for (s = fujitsu_devList; s; s=s->next) {
938 DBG (15, "sane_get_devices: found scanner %s\n",s->device_name);
939 num_devices++;
940 }
941
942 DBG (15, "sane_get_devices: found %d scanner(s)\n",num_devices);
943
944 if (sane_devArray)
945 free (sane_devArray);
946
947 sane_devArray = calloc (num_devices + 1, sizeof (SANE_Device*));
948 if (!sane_devArray)
949 return SANE_STATUS_NO_MEM;
950
951 for (s = fujitsu_devList; s; s=s->next) {
952 sane_devArray[i++] = (SANE_Device *)&s->sane;
953 }
954 sane_devArray[i] = 0;
955
956 if(device_list){
957 *device_list = sane_devArray;
958 }
959
960 DBG (10, "sane_get_devices: finish\n");
961
962 return ret;
963 }
964
965 /* callbacks used by sane_get_devices */
966 static SANE_Status
attach_one_scsi(const char *device_name)967 attach_one_scsi (const char *device_name)
968 {
969 return attach_one(device_name,CONNECTION_SCSI);
970 }
971
972 static SANE_Status
attach_one_usb(const char *device_name)973 attach_one_usb (const char *device_name)
974 {
975 return attach_one(device_name,CONNECTION_USB);
976 }
977
978 /* build the scanner struct and link to global list
979 * unless struct is already loaded, then pretend
980 */
981 static SANE_Status
attach_one(const char *device_name, int connType)982 attach_one (const char *device_name, int connType)
983 {
984 struct fujitsu *s;
985 int ret;
986
987 DBG (10, "attach_one: start\n");
988 DBG (15, "attach_one: looking for '%s'\n", device_name);
989
990 for (s = fujitsu_devList; s; s = s->next) {
991 if (strcmp (s->device_name, device_name) == 0){
992 DBG (10, "attach_one: already attached!\n");
993 s->missing = 0;
994 return SANE_STATUS_GOOD;
995 }
996 }
997
998 /* build a fujitsu struct to hold it */
999 if ((s = calloc (sizeof (*s), 1)) == NULL)
1000 return SANE_STATUS_NO_MEM;
1001
1002 /* scsi command/data buffer */
1003 s->buffer_size = global_buffer_size;
1004
1005 /* copy the device name */
1006 strcpy (s->device_name, device_name);
1007
1008 /* connect the fd */
1009 s->connection = connType;
1010 s->fd = -1;
1011 ret = connect_fd(s);
1012 if(ret != SANE_STATUS_GOOD){
1013 free (s);
1014 return ret;
1015 }
1016
1017 /* Now query the device to load its vendor/model/version */
1018 ret = init_inquire (s);
1019 if (ret != SANE_STATUS_GOOD) {
1020 disconnect_fd(s);
1021 free (s);
1022 DBG (5, "attach_one: inquiry failed\n");
1023 return ret;
1024 }
1025
1026 /* load detailed specs/capabilities from the device */
1027 ret = init_vpd (s);
1028 if (ret != SANE_STATUS_GOOD) {
1029 disconnect_fd(s);
1030 free (s);
1031 DBG (5, "attach_one: vpd failed\n");
1032 return ret;
1033 }
1034
1035 /* clean up the scanner struct based on model */
1036 /* this is the only piece of model specific code */
1037 ret = init_model (s);
1038 if (ret != SANE_STATUS_GOOD) {
1039 disconnect_fd(s);
1040 free (s);
1041 DBG (5, "attach_one: model failed\n");
1042 return ret;
1043 }
1044
1045 /* see what mode pages device supports */
1046 ret = init_ms (s);
1047 if (ret != SANE_STATUS_GOOD) {
1048 disconnect_fd(s);
1049 free (s);
1050 DBG (5, "attach_one: ms failed\n");
1051 return ret;
1052 }
1053
1054 /* sets SANE option 'values' to good defaults */
1055 ret = init_user (s);
1056 if (ret != SANE_STATUS_GOOD) {
1057 disconnect_fd(s);
1058 free (s);
1059 DBG (5, "attach_one: user failed\n");
1060 return ret;
1061 }
1062
1063 ret = init_options (s);
1064 if (ret != SANE_STATUS_GOOD) {
1065 disconnect_fd(s);
1066 free (s);
1067 DBG (5, "attach_one: options failed\n");
1068 return ret;
1069 }
1070
1071 ret = init_interlace (s);
1072 if (ret != SANE_STATUS_GOOD) {
1073 disconnect_fd(s);
1074 free (s);
1075 DBG (5, "attach_one: interlace failed\n");
1076 return ret;
1077 }
1078
1079 /* load strings into sane_device struct */
1080 s->sane.name = s->device_name;
1081 s->sane.vendor = s->vendor_name;
1082 s->sane.model = s->model_name;
1083 s->sane.type = "scanner";
1084
1085 /* change name in sane_device struct if scanner has serial number */
1086 ret = init_serial (s);
1087 if (ret == SANE_STATUS_GOOD) {
1088 s->sane.name = s->serial_name;
1089 }
1090 else{
1091 DBG (5, "attach_one: serial number unsupported?\n");
1092 }
1093
1094 /* we close the connection, so that another backend can talk to scanner */
1095 disconnect_fd(s);
1096
1097 /* store this scanner in global vars */
1098 s->next = fujitsu_devList;
1099 fujitsu_devList = s;
1100
1101 DBG (10, "attach_one: finish\n");
1102
1103 return SANE_STATUS_GOOD;
1104 }
1105
1106 /*
1107 * connect the fd in the scanner struct
1108 */
1109 static SANE_Status
connect_fd(struct fujitsu *s)1110 connect_fd (struct fujitsu *s)
1111 {
1112 SANE_Status ret;
1113 int buffer_size = s->buffer_size;
1114
1115 DBG (10, "connect_fd: start\n");
1116
1117 if(s->fd > -1){
1118 DBG (5, "connect_fd: already open\n");
1119 ret = SANE_STATUS_GOOD;
1120 }
1121 else if (s->connection == CONNECTION_USB) {
1122 DBG (15, "connect_fd: opening USB device\n");
1123 ret = sanei_usb_open (s->device_name, &(s->fd));
1124 }
1125 else {
1126 DBG (15, "connect_fd: opening SCSI device\n");
1127 ret = sanei_scsi_open_extended (s->device_name, &(s->fd), sense_handler, s,
1128 &s->buffer_size);
1129 if(!ret && buffer_size != s->buffer_size){
1130 DBG (5, "connect_fd: cannot get requested buffer size (%d/%d)\n",
1131 buffer_size, s->buffer_size);
1132 }
1133 }
1134
1135 if(ret == SANE_STATUS_GOOD){
1136
1137 /* first generation usb scanners can get flaky if not closed
1138 * properly after last use. very first commands sent to device
1139 * must be prepared to correct this- see wait_scanner() */
1140 ret = wait_scanner(s);
1141 if (ret != SANE_STATUS_GOOD) {
1142 DBG (5, "connect_fd: could not wait_scanner\n");
1143 disconnect_fd(s);
1144 }
1145
1146 }
1147 else{
1148 DBG (5, "connect_fd: could not open device: %d\n", ret);
1149 }
1150
1151 DBG (10, "connect_fd: finish\n");
1152
1153 return ret;
1154 }
1155
1156 /*
1157 * This routine will check if a certain device is a Fujitsu scanner
1158 * It also copies interesting data from INQUIRY into the handle structure
1159 */
1160 static SANE_Status
init_inquire(struct fujitsu *s)1161 init_inquire (struct fujitsu *s)
1162 {
1163 int i;
1164 SANE_Status ret;
1165
1166 unsigned char cmd[INQUIRY_len];
1167 size_t cmdLen = INQUIRY_len;
1168
1169 unsigned char in[INQUIRY_std_len];
1170 size_t inLen = INQUIRY_std_len;
1171
1172 DBG (10, "init_inquire: start\n");
1173
1174 memset(cmd,0,cmdLen);
1175 set_SCSI_opcode(cmd, INQUIRY_code);
1176 set_IN_return_size (cmd, inLen);
1177 set_IN_evpd (cmd, 0);
1178 set_IN_page_code (cmd, 0);
1179
1180 ret = do_cmd (
1181 s, 1, 0,
1182 cmd, cmdLen,
1183 NULL, 0,
1184 in, &inLen
1185 );
1186
1187 if (ret != SANE_STATUS_GOOD){
1188 return ret;
1189 }
1190
1191 if (get_IN_periph_devtype (in) != IN_periph_devtype_scanner){
1192 DBG (5, "The device at '%s' is not a scanner.\n", s->device_name);
1193 return SANE_STATUS_INVAL;
1194 }
1195
1196 get_IN_vendor (in, s->vendor_name);
1197 get_IN_product (in, s->model_name);
1198 get_IN_version (in, s->version_name);
1199
1200 s->vendor_name[8] = 0;
1201 s->model_name[16] = 0;
1202 s->version_name[4] = 0;
1203
1204 /* gobble trailing spaces */
1205 for (i = 7; s->vendor_name[i] == ' ' && i >= 0; i--)
1206 s->vendor_name[i] = 0;
1207 for (i = 15; s->model_name[i] == ' ' && i >= 0; i--)
1208 s->model_name[i] = 0;
1209 for (i = 3; s->version_name[i] == ' ' && i >= 0; i--)
1210 s->version_name[i] = 0;
1211
1212 if (strcmp ("FUJITSU", s->vendor_name)) {
1213 DBG (5, "The device at '%s' is reported to be made by '%s'\n", s->device_name, s->vendor_name);
1214 DBG (5, "This backend only supports Fujitsu products.\n");
1215 return SANE_STATUS_INVAL;
1216 }
1217
1218 DBG (15, "init_inquire: Found %s scanner %s version %s at %s\n",
1219 s->vendor_name, s->model_name, s->version_name, s->device_name);
1220
1221 /*some scanners list random data here*/
1222 DBG (15, "inquiry options\n");
1223
1224 s->color_raster_offset = get_IN_color_offset(in);
1225 DBG (15, " color offset: %d lines\n",s->color_raster_offset);
1226
1227 /* FIXME: we don't store all of these? */
1228 DBG (15, " long gray scan: %d\n",get_IN_long_gray(in));
1229 DBG (15, " long color scan: %d\n",get_IN_long_color(in));
1230
1231 DBG (15, " emulation mode: %d\n",get_IN_emulation(in));
1232 DBG (15, " CMP/CGA: %d\n",get_IN_cmp_cga(in));
1233 DBG (15, " background back: %d\n",get_IN_bg_back(in));
1234 DBG (15, " background front: %d\n",get_IN_bg_front(in));
1235 DBG (15, " background fb: %d\n",get_IN_bg_fb(in));
1236 DBG (15, " back only scan: %d\n",get_IN_has_back(in));
1237
1238 s->duplex_raster_offset = get_IN_duplex_offset(in);
1239 DBG (15, " duplex offset: %d lines\n",s->duplex_raster_offset);
1240
1241 DBG (10, "init_inquire: finish\n");
1242
1243 return SANE_STATUS_GOOD;
1244 }
1245
1246 /*
1247 * Use INQUIRY VPD to setup more detail about the scanner
1248 */
1249 static SANE_Status
init_vpd(struct fujitsu *s)1250 init_vpd (struct fujitsu *s)
1251 {
1252 SANE_Status ret;
1253
1254 unsigned char cmd[INQUIRY_len];
1255 size_t cmdLen = INQUIRY_len;
1256
1257 unsigned char in[INQUIRY_vpd_len];
1258 size_t inLen = INQUIRY_vpd_len;
1259
1260 int payload_len, payload_off;
1261
1262 DBG (10, "init_vpd: start\n");
1263
1264 /* get EVPD */
1265 memset(cmd,0,cmdLen);
1266 set_SCSI_opcode(cmd, INQUIRY_code);
1267 set_IN_return_size (cmd, inLen);
1268 set_IN_evpd (cmd, 1);
1269 set_IN_page_code (cmd, 0xf0);
1270
1271 ret = do_cmd (
1272 s, 1, 0,
1273 cmd, cmdLen,
1274 NULL, 0,
1275 in, &inLen
1276 );
1277
1278 /*FIXME no vpd, set some defaults? */
1279 if (ret != SANE_STATUS_GOOD && ret != SANE_STATUS_EOF) {
1280 DBG (5, "init_vpd: Your scanner does not support VPD?\n");
1281 DBG (5, "init_vpd: Please contact kitno455 at gmail dot com\n");
1282 DBG (5, "init_vpd: with details of your scanner model.\n");
1283 return ret;
1284 }
1285
1286 /* In byte 4, the scanner sends the length of the remainder of
1287 * the payload. But, this value is often bogus. */
1288 payload_len = get_IN_page_length(in);
1289
1290 DBG (15, "init_vpd: length=%0x\n", payload_len);
1291
1292 /* M3099 gives all data, but wrong length */
1293 if (strstr (s->model_name, "M3099") && payload_len == 0x19){
1294 DBG (5, "init_vpd: M3099 repair\n");
1295 payload_len = 0x5f;
1296 }
1297
1298 /* M3097G has short vpd, fill in missing part */
1299 else if (strstr (s->model_name, "M3097G") && payload_len == 0x19){
1300 unsigned char vpd3097g[] = {
1301 0, 0,
1302 0xc2, 0x08, 0, 0, 0, 0, 0, 0, 0xed, 0xbf, 0, 0, 0, 0, 0, 0,
1303 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1304 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1305 0, 0, 0xff, 0xff, 0xff, 0, 0x45, 0x35, 0, 0xe0, 0, 0, 0, 0, 0, 0,
1306 0, 0, 0, 0
1307 };
1308
1309 DBG (5, "init_vpd: M3097G repair\n");
1310 payload_len = 0x5f;
1311 memcpy(in+0x1e,vpd3097g,sizeof(vpd3097g));
1312
1313 /*IPC*/
1314 if(strstr (s->model_name, "i")){
1315 DBG (5, "init_vpd: M3097G IPC repair\n");
1316
1317 /*subwin cmd*/
1318 in[0x2b] = 1;
1319
1320 /*rif/dtc/sdtc/outline/emph/sep/mirr/wlf*/
1321 in[0x58] = 0xff;
1322
1323 /*subwin/diffusion*/
1324 in[0x59] = 0xc0;
1325 }
1326
1327 /*CMP*/
1328 if(strstr (s->model_name, "m")){
1329 DBG (5, "init_vpd: M3097G CMP repair\n");
1330
1331 /*4megs*/
1332 in[0x23] = 0x40;
1333
1334 /*mh/mr/mmr*/
1335 in[0x5a] = 0xe0;
1336 }
1337 }
1338
1339 /* all other known scanners have at least 0x5f,
1340 * less would require software changes like above */
1341 else if (payload_len < 0x5f) {
1342 DBG (5, "init_vpd: Your scanner supports only partial VPD?\n");
1343 DBG (5, "init_vpd: Please contact kitno455 at gmail dot com\n");
1344 DBG (5, "init_vpd: with details of your scanner model.\n");
1345 return SANE_STATUS_INVAL;
1346 }
1347
1348 /* Special case- some scanners will under-report the amount of
1349 * valid vpd that they send, and return the default length.
1350 * Adding 4 more bytes allows us to include the overscan info.
1351 * Scanners that don't support overscan seem to have all zeros
1352 * in these bytes, so no harm is done.
1353 * This may be an 'off-by-four' error in the firmware. */
1354 else if (payload_len == 0x5f){
1355 payload_len += 4;
1356 }
1357
1358 /* Having an offset from the beginning of the payload
1359 * is more useful than from byte 4, as that matches the
1360 * documentation more closely. */
1361 payload_off = payload_len + 4;
1362
1363 /* everything that appears in bytes 0 to 0x1d */
1364 DBG (15, "standard options\n");
1365
1366 s->basic_x_res = get_IN_basic_x_res (in);
1367 DBG (15, " basic x res: %d dpi\n",s->basic_x_res);
1368
1369 s->basic_y_res = get_IN_basic_y_res (in);
1370 DBG (15, " basic y res: %d dpi\n",s->basic_y_res);
1371
1372 s->step_x_res[MODE_LINEART] = get_IN_step_x_res (in);
1373 DBG (15, " step x res: %d dpi\n", s->step_x_res[MODE_LINEART]);
1374
1375 s->step_y_res[MODE_LINEART] = get_IN_step_y_res (in);
1376 DBG (15, " step y res: %d dpi\n", s->step_y_res[MODE_LINEART]);
1377
1378 s->max_x_res = get_IN_max_x_res (in);
1379 DBG (15, " max x res: %d dpi\n", s->max_x_res);
1380
1381 s->max_y_res = get_IN_max_y_res (in);
1382 DBG (15, " max y res: %d dpi\n", s->max_y_res);
1383
1384 s->min_x_res = get_IN_min_x_res (in);
1385 DBG (15, " min x res: %d dpi\n", s->min_x_res);
1386
1387 s->min_y_res = get_IN_min_y_res (in);
1388 DBG (15, " min y res: %d dpi\n", s->min_y_res);
1389
1390 /* some scanners list B&W resolutions. */
1391 s->std_res[0] = get_IN_std_res_60 (in);
1392 DBG (15, " 60 dpi: %d\n", s->std_res[0]);
1393
1394 s->std_res[1] = get_IN_std_res_75 (in);
1395 DBG (15, " 75 dpi: %d\n", s->std_res[1]);
1396
1397 s->std_res[2] = get_IN_std_res_100 (in);
1398 DBG (15, " 100 dpi: %d\n", s->std_res[2]);
1399
1400 s->std_res[3] = get_IN_std_res_120 (in);
1401 DBG (15, " 120 dpi: %d\n", s->std_res[3]);
1402
1403 s->std_res[4] = get_IN_std_res_150 (in);
1404 DBG (15, " 150 dpi: %d\n", s->std_res[4]);
1405
1406 s->std_res[5] = get_IN_std_res_160 (in);
1407 DBG (15, " 160 dpi: %d\n", s->std_res[5]);
1408
1409 s->std_res[6] = get_IN_std_res_180 (in);
1410 DBG (15, " 180 dpi: %d\n", s->std_res[6]);
1411
1412 s->std_res[7] = get_IN_std_res_200 (in);
1413 DBG (15, " 200 dpi: %d\n", s->std_res[7]);
1414
1415 s->std_res[8] = get_IN_std_res_240 (in);
1416 DBG (15, " 240 dpi: %d\n", s->std_res[8]);
1417
1418 s->std_res[9] = get_IN_std_res_300 (in);
1419 DBG (15, " 300 dpi: %d\n", s->std_res[9]);
1420
1421 s->std_res[10] = get_IN_std_res_320 (in);
1422 DBG (15, " 320 dpi: %d\n", s->std_res[10]);
1423
1424 s->std_res[11] = get_IN_std_res_400 (in);
1425 DBG (15, " 400 dpi: %d\n", s->std_res[11]);
1426
1427 s->std_res[12] = get_IN_std_res_480 (in);
1428 DBG (15, " 480 dpi: %d\n", s->std_res[12]);
1429
1430 s->std_res[13] = get_IN_std_res_600 (in);
1431 DBG (15, " 600 dpi: %d\n", s->std_res[13]);
1432
1433 s->std_res[14] = get_IN_std_res_800 (in);
1434 DBG (15, " 800 dpi: %d\n", s->std_res[14]);
1435
1436 s->std_res[15] = get_IN_std_res_1200 (in);
1437 DBG (15, " 1200 dpi: %d\n", s->std_res[15]);
1438
1439 /* maximum window width and length are reported in basic units.*/
1440 s->max_x_basic = get_IN_window_width(in);
1441 DBG(15, " max width: %2.2f inches\n",(float)s->max_x_basic/s->basic_x_res);
1442
1443 s->max_y_basic = get_IN_window_length(in);
1444 DBG(15, " max length: %2.2f inches\n",(float)s->max_y_basic/s->basic_y_res);
1445
1446 /* known modes */
1447 s->can_overflow = get_IN_overflow(in);
1448 DBG (15, " overflow: %d\n", s->can_overflow);
1449
1450 s->can_mode[MODE_LINEART] = get_IN_monochrome (in);
1451 DBG (15, " monochrome: %d\n", s->can_mode[MODE_LINEART]);
1452
1453 s->can_mode[MODE_HALFTONE] = get_IN_half_tone (in);
1454 DBG (15, " halftone: %d\n", s->can_mode[MODE_HALFTONE]);
1455
1456 s->can_mode[MODE_GRAYSCALE] = get_IN_multilevel (in);
1457 DBG (15, " grayscale: %d\n", s->can_mode[MODE_GRAYSCALE]);
1458
1459 DBG (15, " color_monochrome: %d\n", get_IN_monochrome_rgb(in));
1460 DBG (15, " color_halftone: %d\n", get_IN_half_tone_rgb(in));
1461
1462 s->can_mode[MODE_COLOR] = get_IN_multilevel_rgb (in);
1463 DBG (15, " color_grayscale: %d\n", s->can_mode[MODE_COLOR]);
1464
1465 /* now we look at vendor specific data in bytes 0x1e onward */
1466 DBG (15, "vendor options\n");
1467
1468 s->has_adf = get_IN_adf(in);
1469 DBG (15, " adf: %d\n", s->has_adf);
1470
1471 s->has_flatbed = get_IN_flatbed(in);
1472 DBG (15, " flatbed: %d\n", s->has_flatbed);
1473
1474 s->has_transparency = get_IN_transparency(in);
1475 DBG (15, " transparency: %d\n", s->has_transparency);
1476
1477 s->has_duplex = get_IN_duplex(in);
1478 s->has_back = s->has_duplex;
1479 DBG (15, " duplex: %d\n", s->has_duplex);
1480
1481 s->has_endorser_b = get_IN_endorser_b(in);
1482 DBG (15, " back endorser: %d\n", s->has_endorser_b);
1483
1484 s->has_barcode = get_IN_barcode(in);
1485 DBG (15, " barcode: %d\n", s->has_barcode);
1486
1487 s->has_operator_panel = get_IN_operator_panel(in);
1488 DBG (15, " operator panel: %d\n", s->has_operator_panel);
1489
1490 s->has_endorser_f = get_IN_endorser_f(in);
1491 DBG (15, " front endorser: %d\n", s->has_endorser_f);
1492
1493 DBG (15, " multi-purpose stacker: %d\n", get_IN_mp_stacker(in));
1494
1495 DBG (15, " prepick: %d\n", get_IN_prepick(in));
1496 DBG (15, " mf detect: %d\n", get_IN_mf_detect(in));
1497
1498 s->has_paper_protect = get_IN_paperprot(in);
1499 DBG (15, " paper protection: %d\n", s->has_paper_protect);
1500
1501 s->adbits = get_IN_adbits(in);
1502 DBG (15, " A/D bits: %d\n",s->adbits);
1503
1504 s->buffer_bytes = get_IN_buffer_bytes(in);
1505 DBG (15, " buffer bytes: %d\n",s->buffer_bytes);
1506
1507 DBG (15, "Standard commands\n");
1508
1509 /* std scsi command support byte 26*/
1510 s->has_cmd_msen10 = get_IN_has_cmd_msen10(in);
1511 DBG (15, " mode_sense_10 cmd: %d\n", s->has_cmd_msen10);
1512
1513 s->has_cmd_msel10 = get_IN_has_cmd_msel10(in);
1514 DBG (15, " mode_select_10 cmd: %d\n", s->has_cmd_msel10);
1515
1516 /* std scsi command support byte 27*/
1517 s->has_cmd_lsen = get_IN_has_cmd_lsen(in);
1518 DBG (15, " log_sense cmd: %d\n", s->has_cmd_lsen);
1519
1520 s->has_cmd_lsel = get_IN_has_cmd_lsel(in);
1521 DBG (15, " log_select cmd: %d\n", s->has_cmd_lsel);
1522
1523 s->has_cmd_change = get_IN_has_cmd_change(in);
1524 DBG (15, " change cmd: %d\n", s->has_cmd_change);
1525
1526 s->has_cmd_rbuff = get_IN_has_cmd_rbuff(in);
1527 DBG (15, " read_buffer cmd: %d\n", s->has_cmd_rbuff);
1528
1529 s->has_cmd_wbuff = get_IN_has_cmd_wbuff(in);
1530 DBG (15, " write_buffer cmd: %d\n", s->has_cmd_wbuff);
1531
1532 s->has_cmd_cav = get_IN_has_cmd_cav(in);
1533 DBG (15, " copy_and_verify cmd: %d\n", s->has_cmd_cav);
1534
1535 s->has_cmd_comp = get_IN_has_cmd_comp(in);
1536 DBG (15, " compare cmd: %d\n", s->has_cmd_comp);
1537
1538 s->has_cmd_gdbs = get_IN_has_cmd_gdbs(in);
1539 DBG (15, " get_d_b_status cmd: %d\n", s->has_cmd_gdbs);
1540
1541 /* std scsi command support byte 28*/
1542 s->has_cmd_op = get_IN_has_cmd_op(in);
1543 DBG (15, " object_pos cmd: %d\n", s->has_cmd_op);
1544
1545 s->has_cmd_send = get_IN_has_cmd_send(in);
1546 DBG (15, " send cmd: %d\n", s->has_cmd_send);
1547
1548 s->has_cmd_read = get_IN_has_cmd_read(in);
1549 DBG (15, " read cmd: %d\n", s->has_cmd_read);
1550
1551 s->has_cmd_gwin = get_IN_has_cmd_gwin(in);
1552 DBG (15, " get_window cmd: %d\n", s->has_cmd_gwin);
1553
1554 s->has_cmd_swin = get_IN_has_cmd_swin(in);
1555 DBG (15, " set_window cmd: %d\n", s->has_cmd_swin);
1556
1557 s->has_cmd_sdiag = get_IN_has_cmd_sdiag(in);
1558 DBG (15, " send_diag cmd: %d\n", s->has_cmd_sdiag);
1559
1560 s->has_cmd_rdiag = get_IN_has_cmd_rdiag(in);
1561 DBG (15, " read_diag cmd: %d\n", s->has_cmd_rdiag);
1562
1563 s->has_cmd_scan = get_IN_has_cmd_scan(in);
1564 DBG (15, " scan cmd: %d\n", s->has_cmd_scan);
1565
1566 /* std scsi command support byte 29*/
1567 s->has_cmd_msen6 = get_IN_has_cmd_msen6(in);
1568 DBG (15, " mode_sense_6 cmd: %d\n", s->has_cmd_msen6);
1569
1570 s->has_cmd_copy = get_IN_has_cmd_copy(in);
1571 DBG (15, " copy cmd: %d\n", s->has_cmd_copy);
1572
1573 s->has_cmd_rel = get_IN_has_cmd_rel(in);
1574 DBG (15, " release cmd: %d\n", s->has_cmd_rel);
1575
1576 s->has_cmd_runit = get_IN_has_cmd_runit(in);
1577 DBG (15, " reserve_unit cmd: %d\n", s->has_cmd_runit);
1578
1579 s->has_cmd_msel6 = get_IN_has_cmd_msel6(in);
1580 DBG (15, " mode_select_6 cmd: %d\n", s->has_cmd_msel6);
1581
1582 s->has_cmd_inq = get_IN_has_cmd_inq(in);
1583 DBG (15, " inquiry cmd: %d\n", s->has_cmd_inq);
1584
1585 s->has_cmd_rs = get_IN_has_cmd_rs(in);
1586 DBG (15, " request_sense cmd: %d\n", s->has_cmd_rs);
1587
1588 s->has_cmd_tur = get_IN_has_cmd_tur(in);
1589 DBG (15, " test_unit_ready cmd: %d\n", s->has_cmd_tur);
1590
1591 /* vendor added scsi command support */
1592 /* FIXME: there are more of these... */
1593 DBG (15, "Vendor commands\n");
1594
1595 s->has_cmd_subwindow = get_IN_has_cmd_subwindow(in);
1596 DBG (15, " subwindow cmd: %d\n", s->has_cmd_subwindow);
1597
1598 s->has_cmd_endorser = get_IN_has_cmd_endorser(in);
1599 DBG (15, " endorser cmd: %d\n", s->has_cmd_endorser);
1600
1601 s->has_cmd_hw_status = get_IN_has_cmd_hw_status (in);
1602 DBG (15, " hardware status cmd: %d\n", s->has_cmd_hw_status);
1603
1604 s->has_cmd_hw_status_2 = get_IN_has_cmd_hw_status_2 (in);
1605 DBG (15, " hardware status 2 cmd: %d\n", s->has_cmd_hw_status_2);
1606
1607 s->has_cmd_hw_status_3 = get_IN_has_cmd_hw_status_3 (in);
1608 DBG (15, " hardware status 3 cmd: %d\n", s->has_cmd_hw_status_3);
1609
1610 s->has_cmd_scanner_ctl = get_IN_has_cmd_scanner_ctl(in);
1611 DBG (15, " scanner control cmd: %d\n", s->has_cmd_scanner_ctl);
1612
1613 s->has_cmd_device_restart = get_IN_has_cmd_device_restart(in);
1614 DBG (15, " device restart cmd: %d\n", s->has_cmd_device_restart);
1615
1616 /* get threshold, brightness and contrast ranges. */
1617 s->brightness_steps = get_IN_brightness_steps(in);
1618 DBG (15, " brightness steps: %d\n", s->brightness_steps);
1619
1620 s->threshold_steps = get_IN_threshold_steps(in);
1621 DBG (15, " threshold steps: %d\n", s->threshold_steps);
1622
1623 s->contrast_steps = get_IN_contrast_steps(in);
1624 DBG (15, " contrast steps: %d\n", s->contrast_steps);
1625
1626 /* dither/gamma patterns */
1627 s->num_internal_gamma = get_IN_num_gamma_internal (in);
1628 DBG (15, " built in gamma patterns: %d\n", s->num_internal_gamma);
1629
1630 s->num_download_gamma = get_IN_num_gamma_download (in);
1631 DBG (15, " download gamma patterns: %d\n", s->num_download_gamma);
1632
1633 s->num_internal_dither = get_IN_num_dither_internal (in);
1634 DBG (15, " built in dither patterns: %d\n", s->num_internal_dither);
1635
1636 s->num_download_dither = get_IN_num_dither_download (in);
1637 DBG (15, " download dither patterns: %d\n", s->num_download_dither);
1638
1639 /* ipc functions */
1640 s->has_rif = get_IN_ipc_bw_rif (in);
1641 DBG (15, " RIF: %d\n", s->has_rif);
1642
1643 s->has_dtc = get_IN_ipc_dtc(in);
1644 DBG (15, " DTC (AutoI): %d\n", s->has_dtc);
1645
1646 s->has_sdtc = get_IN_ipc_sdtc(in);
1647 DBG (15, " SDTC (AutoII): %d\n", s->has_sdtc);
1648
1649 s->has_outline = get_IN_ipc_outline_extraction (in);
1650 DBG (15, " outline extraction: %d\n", s->has_outline);
1651
1652 s->has_emphasis = get_IN_ipc_image_emphasis (in);
1653 DBG (15, " image emphasis: %d\n", s->has_emphasis);
1654
1655 s->has_autosep = get_IN_ipc_auto_separation (in);
1656 DBG (15, " automatic separation: %d\n", s->has_autosep);
1657
1658 s->has_mirroring = get_IN_ipc_mirroring (in);
1659 DBG (15, " mirror image: %d\n", s->has_mirroring);
1660
1661 s->has_wl_follow = get_IN_ipc_wl_follow (in);
1662 DBG (15, " white level follower: %d\n", s->has_wl_follow);
1663
1664 /* byte 58 */
1665 s->has_subwindow = get_IN_ipc_subwindow (in);
1666 DBG (15, " subwindow: %d\n", s->has_subwindow);
1667
1668 s->has_diffusion = get_IN_ipc_diffusion (in);
1669 DBG (15, " diffusion: %d\n", s->has_diffusion);
1670
1671 s->has_ipc3 = get_IN_ipc_ipc3 (in);
1672 DBG (15, " ipc3: %d\n", s->has_ipc3);
1673
1674 s->has_rotation = get_IN_ipc_rotation (in);
1675 DBG (15, " rotation: %d\n", s->has_rotation);
1676
1677 s->has_hybrid_crop_deskew = get_IN_ipc_hybrid_crop_deskew(in);
1678 DBG (15, " hybrid crop deskew: %d\n", s->has_hybrid_crop_deskew);
1679
1680 /* this one is weird, overrides the payload length from scanner */
1681 DBG (15, " vpd extends to byte 6f: %d\n", get_IN_vpd_thru_byte_6f(in));
1682 if(get_IN_vpd_thru_byte_6f(in) && payload_off < 0x6f){
1683 payload_off = 0x6f;
1684 }
1685
1686 /* compression modes */
1687 s->has_comp_MH = get_IN_compression_MH (in);
1688 DBG (15, " compression MH: %d\n", s->has_comp_MH);
1689
1690 s->has_comp_MR = get_IN_compression_MR (in);
1691 DBG (15, " compression MR: %d\n", s->has_comp_MR);
1692
1693 s->has_comp_MMR = get_IN_compression_MMR (in);
1694 DBG (15, " compression MMR: %d\n", s->has_comp_MMR);
1695
1696 s->has_comp_JBIG = get_IN_compression_JBIG (in);
1697 DBG (15, " compression JBIG: %d\n", s->has_comp_JBIG);
1698
1699 s->has_comp_JPG1 = get_IN_compression_JPG_BASE (in);
1700 DBG (15, " compression JPG1: %d\n", s->has_comp_JPG1);
1701 #ifdef SANE_JPEG_DISABLED
1702 DBG (15, " (Disabled)\n");
1703 #endif
1704
1705 s->has_comp_JPG2 = get_IN_compression_JPG_EXT (in);
1706 DBG (15, " compression JPG2: %d\n", s->has_comp_JPG2);
1707
1708 s->has_comp_JPG3 = get_IN_compression_JPG_INDEP (in);
1709 DBG (15, " compression JPG3: %d\n", s->has_comp_JPG3);
1710
1711 /* FIXME: we don't store these? */
1712 DBG (15, " back endorser mech: %d\n", get_IN_endorser_b_mech(in));
1713 DBG (15, " back endorser stamp: %d\n", get_IN_endorser_b_stamp(in));
1714 DBG (15, " back endorser elec: %d\n", get_IN_endorser_b_elec(in));
1715 DBG (15, " endorser max id: %d\n", get_IN_endorser_max_id(in));
1716
1717 DBG (15, " front endorser mech: %d\n", get_IN_endorser_f_mech(in));
1718 DBG (15, " front endorser stamp: %d\n", get_IN_endorser_f_stamp(in));
1719 DBG (15, " front endorser elec: %d\n", get_IN_endorser_f_elec(in));
1720
1721 s->endorser_type_b = get_IN_endorser_b_type(in);
1722 DBG (15, " back endorser type: %d\n", s->endorser_type_b);
1723
1724 s->endorser_type_f = get_IN_endorser_f_type(in);
1725 DBG (15, " back endorser type: %d\n", s->endorser_type_f);
1726
1727 DBG (15, " connection type: %d\n", get_IN_connection(in));
1728
1729 DBG (15, " endorser ext: %d\n", get_IN_endorser_type_ext(in));
1730 DBG (15, " endorser pr_b: %d\n", get_IN_endorser_pre_back(in));
1731 DBG (15, " endorser pr_f: %d\n", get_IN_endorser_pre_front(in));
1732 DBG (15, " endorser po_b: %d\n", get_IN_endorser_post_back(in));
1733 DBG (15, " endorser po_f: %d\n", get_IN_endorser_post_front(in));
1734
1735 s->os_x_basic = get_IN_x_overscan_size(in);
1736 DBG (15, " horizontal overscan: %d\n", s->os_x_basic);
1737
1738 s->os_y_basic = get_IN_y_overscan_size(in);
1739 DBG (15, " vertical overscan: %d\n", s->os_y_basic);
1740
1741 /* not all scanners go this far */
1742 if (payload_off >= 0x68) {
1743 DBG (15, " default bg adf b: %d\n", get_IN_default_bg_adf_b(in));
1744 DBG (15, " default bg adf f: %d\n", get_IN_default_bg_adf_f(in));
1745 DBG (15, " default bg fb: %d\n", get_IN_default_bg_fb(in));
1746 }
1747
1748 if (payload_off >= 0x69) {
1749 DBG (15, " auto color: %d\n", get_IN_auto_color(in));
1750 DBG (15, " blank skip: %d\n", get_IN_blank_skip(in));
1751 DBG (15, " multi image: %d\n", get_IN_multi_image(in));
1752 DBG (15, " f b type indep: %d\n", get_IN_f_b_type_indep(in));
1753 DBG (15, " f b res indep: %d\n", get_IN_f_b_res_indep(in));
1754 }
1755
1756 if (payload_off >= 0x6a) {
1757 DBG (15, " dropout spec: %d\n", get_IN_dropout_spec(in));
1758 DBG (15, " dropout non: %d\n", get_IN_dropout_non(in));
1759 DBG (15, " dropout white: %d\n", get_IN_dropout_white(in));
1760 }
1761
1762 if (payload_off >= 0x6d) {
1763 DBG (15, " skew check: %d\n", get_IN_skew_check(in));
1764 DBG (15, " new feed roller: %d\n", get_IN_new_fd_roll(in));
1765 s->has_adv_paper_prot = get_IN_paper_prot_2(in);
1766 DBG (15, " paper protection: %d\n", s->has_adv_paper_prot);
1767 }
1768
1769 /* this one is weird, overrides the payload length from scanner,
1770 * but the enlarged area is just null bytes, so we ignore this */
1771 if (payload_off >= 0x6f) {
1772 DBG (15, " extra evpd length: %d\n", get_IN_evpd_len(in));
1773 }
1774
1775 if (payload_off >= 0x70) {
1776 DBG (15, " paper count: %d\n", get_IN_paper_count(in));
1777 DBG (15, " paper number: %d\n", get_IN_paper_number(in));
1778 DBG (15, " ext send to: %d\n", get_IN_ext_send_to(in));
1779
1780 s->has_staple_detect = get_IN_staple_det(in);
1781 DBG (15, " staple det: %d\n", s->has_staple_detect);
1782
1783 DBG (15, " pause host: %d\n", get_IN_pause_host(in));
1784 DBG (15, " pause panel: %d\n", get_IN_pause_panel(in));
1785 DBG (15, " pause conf: %d\n", get_IN_pause_conf(in));
1786 DBG (15, " hq print: %d\n", get_IN_hq_print(in));
1787 }
1788
1789 if (payload_off >= 0x71) {
1790 DBG (15, " ext GHS len: %d\n", get_IN_ext_GHS_len(in));
1791 }
1792
1793 if (payload_off >= 0x72) {
1794 DBG (15, " smbc func: %d\n", get_IN_smbc_func(in));
1795 DBG (15, " imprint chk b: %d\n", get_IN_imprint_chk_b(in));
1796 DBG (15, " imprint chk f: %d\n", get_IN_imprint_chk_f(in));
1797 DBG (15, " force w bg: %d\n", get_IN_force_w_bg(in));
1798
1799 s->has_df_recovery = get_IN_mf_recover_lvl(in);
1800 DBG (15, " mf recover lvl: %d\n", s->has_df_recovery);
1801 }
1802
1803 if (payload_off >= 0x73) {
1804 DBG (15, " first read time: %d\n", get_IN_first_read_time(in));
1805 DBG (15, " div scanning: %d\n", get_IN_div_scanning(in));
1806 DBG (15, " start job: %d\n", get_IN_start_job(in));
1807 DBG (15, " lifetime log: %d\n", get_IN_lifetime_log(in));
1808 DBG (15, " imff save rest: %d\n", get_IN_imff_save_rest(in));
1809 DBG (15, " wide scsi type: %d\n", get_IN_wide_scsi_type(in));
1810 }
1811
1812 if (payload_off >= 0x74) {
1813 DBG (15, " lut hybrid crop: %d\n", get_IN_lut_hybrid_crop(in));
1814 DBG (15, " over under amt: %d\n", get_IN_over_under_amt(in));
1815 DBG (15, " rgb lut: %d\n", get_IN_rgb_lut(in));
1816 DBG (15, " num lut dl: %d\n", get_IN_num_lut_dl(in));
1817 }
1818
1819 /* Various items below are poorly documented or missing */
1820
1821 if (payload_off >= 0x76) {
1822 s->has_off_mode = get_IN_erp_lot6_supp(in);
1823 DBG (15, " ErP Lot6 (power off timer): %d\n", s->has_off_mode);
1824 DBG (15, " sync next feed: %d\n", get_IN_sync_next_feed(in));
1825 }
1826
1827 if (payload_off >= 0x79) {
1828 DBG (15, " battery: %d\n", get_IN_battery(in));
1829 DBG (15, " battery save: %d\n", get_IN_battery_save(in));
1830 DBG (15, " object position reverse: %d\n", get_IN_op_reverse(in));
1831 }
1832
1833 if (payload_off >= 0x7a) {
1834 s->has_op_halt = get_IN_op_halt(in);
1835 DBG (15, " object position halt: %d\n", s->has_op_halt);
1836 }
1837
1838 if (payload_off >= 0x7c) {
1839 s->has_return_path = get_IN_return_path(in);
1840 DBG (15, " return path (card) scanning: %d\n", s->has_return_path);
1841 DBG (15, " energy star 3: %d\n", get_IN_energy_star3(in));
1842 }
1843
1844 DBG (10, "init_vpd: finish\n");
1845
1846 return SANE_STATUS_GOOD;
1847 }
1848
1849 static SANE_Status
init_ms(struct fujitsu *s)1850 init_ms(struct fujitsu *s)
1851 {
1852 int ret;
1853 int oldDbg=0;
1854
1855 unsigned char cmd[MODE_SENSE_len];
1856 size_t cmdLen = MODE_SENSE_len;
1857
1858 unsigned char in[MODE_SENSE_data_len];
1859 size_t inLen = MODE_SENSE_data_len;
1860
1861 DBG (10, "init_ms: start\n");
1862
1863 if(!s->has_cmd_msen6){
1864 DBG (10, "init_ms: unsupported\n");
1865 return SANE_STATUS_GOOD;
1866 }
1867
1868 /* some of the following probes will produce errors */
1869 /* so we reduce the dbg level to reduce the noise */
1870 /* however, if user builds with NDEBUG, we can't do that */
1871 /* so we protect the code with the following macro */
1872 IF_DBG( oldDbg=DBG_LEVEL; )
1873 IF_DBG( if(DBG_LEVEL < 35){ DBG_LEVEL = 0; } )
1874
1875 memset(cmd,0,cmdLen);
1876 set_SCSI_opcode(cmd, MODE_SENSE_code);
1877 set_MSEN_xfer_length (cmd, inLen);
1878
1879 if(s->has_MS_autocolor){
1880 DBG (35, "init_ms: autocolor\n");
1881 set_MSEN_pc(cmd, MS_pc_autocolor);
1882 ret = do_cmd (
1883 s, 1, 0,
1884 cmd, cmdLen,
1885 NULL, 0,
1886 in, &inLen
1887 );
1888 if(ret != SANE_STATUS_GOOD){
1889 s->has_MS_autocolor=0;
1890 }
1891 }
1892
1893 if(s->has_MS_prepick){
1894 DBG (35, "init_ms: prepick\n");
1895 set_MSEN_pc(cmd, MS_pc_prepick);
1896 inLen = MODE_SENSE_data_len;
1897 ret = do_cmd (
1898 s, 1, 0,
1899 cmd, cmdLen,
1900 NULL, 0,
1901 in, &inLen
1902 );
1903 if(ret != SANE_STATUS_GOOD){
1904 s->has_MS_prepick=0;
1905 }
1906 }
1907
1908 if(s->has_MS_sleep){
1909 DBG (35, "init_ms: sleep\n");
1910 set_MSEN_pc(cmd, MS_pc_sleep);
1911 inLen = MODE_SENSE_data_len;
1912 ret = do_cmd (
1913 s, 1, 0,
1914 cmd, cmdLen,
1915 NULL, 0,
1916 in, &inLen
1917 );
1918 if(ret != SANE_STATUS_GOOD){
1919 s->has_MS_sleep=0;
1920 }
1921 }
1922
1923 if(s->has_MS_duplex){
1924 DBG (35, "init_ms: duplex\n");
1925 set_MSEN_pc(cmd, MS_pc_duplex);
1926 inLen = MODE_SENSE_data_len;
1927 ret = do_cmd (
1928 s, 1, 0,
1929 cmd, cmdLen,
1930 NULL, 0,
1931 in, &inLen
1932 );
1933 if(ret != SANE_STATUS_GOOD){
1934 s->has_MS_duplex=0;
1935 }
1936 }
1937
1938 if(s->has_MS_rand){
1939 DBG (35, "init_ms: rand\n");
1940 set_MSEN_pc(cmd, MS_pc_rand);
1941 inLen = MODE_SENSE_data_len;
1942 ret = do_cmd (
1943 s, 1, 0,
1944 cmd, cmdLen,
1945 NULL, 0,
1946 in, &inLen
1947 );
1948 if(ret != SANE_STATUS_GOOD){
1949 s->has_MS_rand=0;
1950 }
1951 }
1952
1953 if(s->has_MS_bg){
1954 DBG (35, "init_ms: bg\n");
1955 set_MSEN_pc(cmd, MS_pc_bg);
1956 inLen = MODE_SENSE_data_len;
1957 ret = do_cmd (
1958 s, 1, 0,
1959 cmd, cmdLen,
1960 NULL, 0,
1961 in, &inLen
1962 );
1963 if(ret != SANE_STATUS_GOOD){
1964 s->has_MS_bg=0;
1965 }
1966 }
1967
1968 if(s->has_MS_df){
1969 DBG (35, "init_ms: df\n");
1970 set_MSEN_pc(cmd, MS_pc_df);
1971 inLen = MODE_SENSE_data_len;
1972 ret = do_cmd (
1973 s, 1, 0,
1974 cmd, cmdLen,
1975 NULL, 0,
1976 in, &inLen
1977 );
1978 if(ret != SANE_STATUS_GOOD){
1979 s->has_MS_df=0;
1980 }
1981 }
1982
1983 if(s->has_MS_dropout){
1984 DBG (35, "init_ms: dropout\n");
1985 set_MSEN_pc(cmd, MS_pc_dropout);
1986 inLen = MODE_SENSE_data_len;
1987 ret = do_cmd (
1988 s, 1, 0,
1989 cmd, cmdLen,
1990 NULL, 0,
1991 in, &inLen
1992 );
1993 if(ret != SANE_STATUS_GOOD){
1994 s->has_MS_dropout=0;
1995 }
1996 }
1997
1998 if(s->has_MS_buff){
1999 DBG (35, "init_ms: buffer\n");
2000 set_MSEN_pc(cmd, MS_pc_buff);
2001 inLen = MODE_SENSE_data_len;
2002 ret = do_cmd (
2003 s, 1, 0,
2004 cmd, cmdLen,
2005 NULL, 0,
2006 in, &inLen
2007 );
2008 if(ret != SANE_STATUS_GOOD){
2009 s->has_MS_buff=0;
2010 }
2011 }
2012
2013 if(s->has_MS_auto){
2014 DBG (35, "init_ms: auto\n");
2015 set_MSEN_pc(cmd, MS_pc_auto);
2016 inLen = MODE_SENSE_data_len;
2017 ret = do_cmd (
2018 s, 1, 0,
2019 cmd, cmdLen,
2020 NULL, 0,
2021 in, &inLen
2022 );
2023 if(ret != SANE_STATUS_GOOD){
2024 s->has_MS_auto=0;
2025 }
2026 }
2027
2028 if(s->has_MS_lamp){
2029 DBG (35, "init_ms: lamp\n");
2030 set_MSEN_pc(cmd, MS_pc_lamp);
2031 inLen = MODE_SENSE_data_len;
2032 ret = do_cmd (
2033 s, 1, 0,
2034 cmd, cmdLen,
2035 NULL, 0,
2036 in, &inLen
2037 );
2038 if(ret != SANE_STATUS_GOOD){
2039 s->has_MS_lamp=0;
2040 }
2041 }
2042
2043 if(s->has_MS_jobsep){
2044 DBG (35, "init_ms: jobsep\n");
2045 set_MSEN_pc(cmd, MS_pc_jobsep);
2046 inLen = MODE_SENSE_data_len;
2047 ret = do_cmd (
2048 s, 1, 0,
2049 cmd, cmdLen,
2050 NULL, 0,
2051 in, &inLen
2052 );
2053 if(ret != SANE_STATUS_GOOD){
2054 s->has_MS_jobsep=0;
2055 }
2056 }
2057
2058 IF_DBG (DBG_LEVEL = oldDbg;)
2059
2060 DBG (15, " autocolor: %d\n", s->has_MS_autocolor);
2061 DBG (15, " prepick: %d\n", s->has_MS_prepick);
2062 DBG (15, " sleep: %d\n", s->has_MS_sleep);
2063 DBG (15, " duplex: %d\n", s->has_MS_duplex);
2064 DBG (15, " rand: %d\n", s->has_MS_rand);
2065 DBG (15, " bg: %d\n", s->has_MS_bg);
2066 DBG (15, " df: %d\n", s->has_MS_df);
2067 DBG (15, " dropout: %d\n", s->has_MS_dropout);
2068 DBG (15, " buff: %d\n", s->has_MS_buff);
2069 DBG (15, " auto: %d\n", s->has_MS_auto);
2070 DBG (15, " lamp: %d\n", s->has_MS_lamp);
2071 DBG (15, " jobsep: %d\n", s->has_MS_jobsep);
2072
2073 DBG (10, "init_ms: finish\n");
2074
2075 return SANE_STATUS_GOOD;
2076 }
2077
2078 /*
2079 * get model specific info that is not in vpd, and correct
2080 * errors in vpd data. struct is already initialized to 0.
2081 */
2082 static SANE_Status
init_model(struct fujitsu *s)2083 init_model (struct fujitsu *s)
2084 {
2085 int i;
2086
2087 DBG (10, "init_model: start\n");
2088
2089 /* for most scanners these are good defaults */
2090 if(s->can_mode[MODE_LINEART]
2091 || s->can_mode[MODE_HALFTONE]
2092 || s->can_mode[MODE_GRAYSCALE]
2093 ){
2094 s->has_vuid_mono = 1;
2095 }
2096 if(s->can_mode[MODE_COLOR]){
2097 s->has_vuid_color = 1;
2098 }
2099
2100 for(i=MODE_HALFTONE;i<=MODE_COLOR;i++){
2101 s->step_x_res[i] = s->step_x_res[MODE_LINEART];
2102 s->step_y_res[i] = s->step_y_res[MODE_LINEART];
2103 }
2104
2105 s->reverse_by_mode[MODE_LINEART] = 0;
2106 s->reverse_by_mode[MODE_HALFTONE] = 0;
2107 s->reverse_by_mode[MODE_GRAYSCALE] = 1;
2108 s->reverse_by_mode[MODE_COLOR] = 1;
2109
2110 s->ppl_mod_by_mode[MODE_LINEART] = 8;
2111 s->ppl_mod_by_mode[MODE_HALFTONE] = 8;
2112 s->ppl_mod_by_mode[MODE_GRAYSCALE] = 1;
2113 s->ppl_mod_by_mode[MODE_COLOR] = 1;
2114
2115 /* endorser type tells string length (among other things) */
2116 if(s->has_endorser_b){
2117 /*old-style is 40 bytes*/
2118 if(s->endorser_type_b == ET_OLD){
2119 s->endorser_string_len = 40;
2120 }
2121 /*short new style is 60 bytes*/
2122 else if(s->endorser_type_b == ET_30){
2123 s->endorser_string_len = 60;
2124 }
2125 /*long new style is 80 bytes*/
2126 else if(s->endorser_type_b == ET_40){
2127 s->endorser_string_len = 80;
2128 }
2129 }
2130 else if(s->has_endorser_f){
2131 /*old-style is 40 bytes*/
2132 if(s->endorser_type_f == ET_OLD){
2133 s->endorser_string_len = 40;
2134 }
2135 /*short new style is 60 bytes*/
2136 else if(s->endorser_type_f == ET_30){
2137 s->endorser_string_len = 60;
2138 }
2139 /*long new style is 80 bytes*/
2140 else if(s->endorser_type_f == ET_40){
2141 s->endorser_string_len = 80;
2142 }
2143 }
2144
2145 /* convert to 1200dpi units */
2146 s->max_x = s->max_x_basic * 1200 / s->basic_x_res;
2147 s->max_y = s->max_y_basic * 1200 / s->basic_y_res;
2148
2149 /* setup the list with a single choice, in 1200dpi units, at max res */
2150 s->max_y_by_res[0].res = s->max_y_res;
2151 s->max_y_by_res[0].len = s->max_y;
2152
2153 /* assume these are same as adf, override below */
2154 s->max_x_fb = s->max_x;
2155 s->max_y_fb = s->max_y;
2156
2157 /* assume we can do these. we will disable
2158 * them at runtime if they cannot */
2159 s->has_pixelsize = 1;
2160 s->has_MS_autocolor = 1;
2161 s->has_MS_prepick = 1;
2162 s->has_MS_sleep = 1;
2163 s->has_MS_duplex = 1;
2164 s->has_MS_rand = 1;
2165 s->has_MS_bg = 1;
2166 s->has_MS_df = 1;
2167 s->has_MS_dropout = 1;
2168 s->has_MS_buff = 1;
2169 s->has_MS_auto = 1;
2170 s->has_MS_lamp = 1;
2171 s->has_MS_jobsep = 1;
2172
2173 /* these two scanners lie about their capabilities,
2174 * and/or differ significantly from most other models */
2175 if (strstr (s->model_name, "M3091")
2176 || strstr (s->model_name, "M3092")) {
2177
2178 /* lies */
2179 s->has_rif = 1;
2180 s->has_back = 0;
2181 s->adbits = 8;
2182 if (strstr (s->model_name, "M3092"))
2183 s->has_flatbed = 1;
2184
2185 /*actually does have res range in non-color modes */
2186 for(i=MODE_LINEART;i<MODE_COLOR;i++){
2187 s->step_x_res[i] = 1;
2188 s->step_y_res[i] = 1;
2189 }
2190
2191 /*but the color mode y list is very limited, only 75, 150, 300 (and 600)*/
2192 for(i=0;i<16;i++){
2193 s->std_res[i] = 0;
2194 }
2195 s->std_res[1] = 1;
2196 s->std_res[4] = 1;
2197 s->std_res[9] = 1;
2198
2199 /* weirdness */
2200 s->has_vuid_3091 = 1;
2201 s->has_vuid_color = 0;
2202 s->has_vuid_mono = 0;
2203 s->has_short_pixelsize = 1;
2204
2205 s->color_interlace = COLOR_INTERLACE_3091;
2206 s->duplex_interlace = DUPLEX_INTERLACE_3091;
2207 s->ghs_in_rs = 1;
2208
2209 /* might be inaccurate */
2210 s->num_internal_gamma = 1;
2211 s->num_download_gamma = 0;
2212
2213 s->reverse_by_mode[MODE_LINEART] = 1;
2214 s->reverse_by_mode[MODE_HALFTONE] = 1;
2215 s->reverse_by_mode[MODE_GRAYSCALE] = 0;
2216 s->reverse_by_mode[MODE_COLOR] = 0;
2217 }
2218
2219 else if (strstr (s->model_name, "M3093")){
2220
2221 /* lies */
2222 s->has_back = 0;
2223 s->adbits = 8;
2224
2225 /* weirdness */
2226 s->duplex_interlace = DUPLEX_INTERLACE_NONE;
2227 }
2228
2229 else if ( strstr (s->model_name, "M309")
2230 || strstr (s->model_name, "M409")){
2231
2232 /* weirdness */
2233 s->broken_diag_serial = 1;
2234
2235 /* lies */
2236 s->adbits = 8;
2237 }
2238
2239 else if (strstr (s->model_name, "fi-4120C2")
2240 || strstr (s->model_name, "fi-4220C2") ) {
2241
2242 /* missing from vpd */
2243 s->os_x_basic = 118;
2244 s->os_y_basic = 118;
2245 s->max_y_fb = 14032;
2246 }
2247
2248 else if (strstr (s->model_name, "fi-4220C")){
2249
2250 /* missing from vpd */
2251 s->max_y_fb = 14032;
2252 }
2253
2254 else if (strstr (s->model_name,"fi-4340")
2255 || strstr (s->model_name, "fi-4750") ) {
2256 /* weirdness */
2257 s->broken_diag_serial = 1;
2258 }
2259
2260 /* some firmware versions use capital f? */
2261 else if (strstr (s->model_name, "Fi-4860")
2262 || strstr (s->model_name, "fi-4860") ) {
2263
2264 /* weirdness */
2265 s->broken_diag_serial = 1;
2266
2267 s->ppl_mod_by_mode[MODE_LINEART] = 32;
2268 s->ppl_mod_by_mode[MODE_HALFTONE] = 32;
2269 s->ppl_mod_by_mode[MODE_GRAYSCALE] = 4;
2270 s->ppl_mod_by_mode[MODE_COLOR] = 4;
2271 }
2272
2273 /* some firmware versions use capital f? */
2274 else if (strstr (s->model_name, "Fi-4990")
2275 || strstr (s->model_name, "fi-4990") ) {
2276
2277 /* weirdness */
2278 s->duplex_interlace = DUPLEX_INTERLACE_NONE;
2279 s->color_interlace = COLOR_INTERLACE_RRGGBB;
2280
2281 s->ppl_mod_by_mode[MODE_LINEART] = 32;
2282 s->ppl_mod_by_mode[MODE_HALFTONE] = 32;
2283 s->ppl_mod_by_mode[MODE_GRAYSCALE] = 4;
2284 s->ppl_mod_by_mode[MODE_COLOR] = 4;
2285 }
2286
2287 else if (strstr (s->model_name,"fi-5110C")){
2288
2289 /* missing from vpd */
2290 s->os_x_basic = 147;
2291 s->os_y_basic = 147;
2292 }
2293
2294 else if (strstr (s->model_name,"fi-5110EOX")){
2295
2296 /* weirdness */
2297 s->cropping_mode = CROP_ABSOLUTE;
2298 }
2299
2300 else if (strstr (s->model_name,"fi-5220C")){
2301
2302 /* missing from vpd */
2303 s->max_x_fb = 10764;
2304 s->max_y_fb = 14032;
2305 }
2306
2307 else if (strstr (s->model_name,"fi-5530")
2308 || strstr (s->model_name,"fi-5650")
2309 || strstr (s->model_name,"fi-5750")){
2310
2311 /* lies - usb only */
2312 if(s->connection == CONNECTION_USB)
2313 s->adbits = 8;
2314 }
2315
2316 else if (strstr (s->model_name,"S1500")){
2317
2318 /*lies*/
2319 s->has_MS_bg=0;
2320 s->has_MS_prepick=0;
2321 }
2322
2323 /* also includes the 'Z' models */
2324 else if (strstr (s->model_name,"fi-6130")
2325 || strstr (s->model_name,"fi-6140")){
2326
2327 /* weirdness */
2328 /* these machines have longer max paper at lower res */
2329 s->max_y_by_res[1].res = 200;
2330 s->max_y_by_res[1].len = 151512;
2331 }
2332
2333 /* also includes the 'Z' models */
2334 else if (strstr (s->model_name,"fi-6230")
2335 || strstr (s->model_name,"fi-6240")){
2336
2337 /* weirdness */
2338 /* these machines have longer max paper at lower res */
2339 s->max_y_by_res[1].res = 200;
2340 s->max_y_by_res[1].len = 151512;
2341
2342 /* missing from vpd */
2343 s->max_x_fb = 10764; /* was previously 10488 */
2344 s->max_y_fb = 14032; /* some scanners can be slightly more? */
2345 }
2346
2347 else if (strstr (s->model_name,"fi-6110")){
2348
2349 /* weirdness */
2350 /* these machines have longer max paper at lower res */
2351 s->max_y_by_res[1].res = 200;
2352 s->max_y_by_res[1].len = 151512;
2353
2354 /*lies*/
2355 s->has_MS_bg=0;
2356 s->has_MS_prepick=0;
2357 }
2358
2359 else if (strstr (s->model_name,"fi-6800")
2360 || strstr (s->model_name,"fi-5900")){
2361 /* do not need overrides */
2362 }
2363
2364 else if (strstr (s->model_name,"iX500")){
2365 /* locks up scanner if we try to auto detect */
2366 s->has_MS_lamp = 0;
2367
2368 /* weirdness */
2369 s->need_q_table = 1;
2370 s->need_diag_preread = 1;
2371 s->ppl_mod_by_mode[MODE_COLOR] = 2;
2372 s->hopper_before_op = 1;
2373 s->no_wait_after_op = 1;
2374
2375 /* lies */
2376 s->adbits = 8;
2377
2378 /* we have to simulate these in software*/
2379 s->can_mode[MODE_LINEART] = 2;
2380 s->can_mode[MODE_GRAYSCALE] = 2;
2381
2382 /* don't bother with this one */
2383 s->can_mode[MODE_HALFTONE] = 0;
2384 }
2385
2386 /*mostly copied from iX500*/
2387 else if (strstr (s->model_name,"iX100")){
2388 /* locks up scanner if we try to auto detect */
2389 s->has_MS_lamp = 0;
2390
2391 /* weirdness */
2392 s->need_q_table = 1;
2393 s->need_diag_preread = 1;
2394 s->ppl_mod_by_mode[MODE_COLOR] = 2;
2395 s->hopper_before_op = 1;
2396 s->no_wait_after_op = 1;
2397
2398 /* lies */
2399 s->adbits = 8;
2400
2401 /* don't bother with this one */
2402 s->can_mode[MODE_HALFTONE] = 0;
2403 }
2404
2405 else if (strstr (s->model_name,"fi-7180")
2406 || strstr (s->model_name,"fi-7160")){
2407 /* locks up scanner if we try to auto detect */
2408 s->has_MS_lamp = 0;
2409
2410 /* weirdness */
2411 /* these machines have longer max paper at lower res */
2412 s->max_y_by_res[1].res = 400;
2413 s->max_y_by_res[1].len = 194268;
2414 s->max_y_by_res[2].res = 300;
2415 s->max_y_by_res[2].len = 260268;
2416 s->max_y_by_res[3].res = 200;
2417 s->max_y_by_res[3].len = 266268;
2418 }
2419
2420 else if (strstr (s->model_name,"fi-7280")
2421 || strstr (s->model_name,"fi-7260")){
2422 /* locks up scanner if we try to auto detect */
2423 s->has_MS_lamp = 0;
2424
2425 /* weirdness */
2426 /* these machines have longer max paper at lower res */
2427 s->max_y_by_res[1].res = 400;
2428 s->max_y_by_res[1].len = 194268;
2429 s->max_y_by_res[2].res = 300;
2430 s->max_y_by_res[2].len = 260268;
2431 s->max_y_by_res[3].res = 200;
2432 s->max_y_by_res[3].len = 266268;
2433
2434 /* missing from vpd */
2435 s->max_x_fb = 10764;
2436 s->max_y_fb = 14032; /* some scanners can be slightly more? */
2437 }
2438
2439 else if (strstr (s->model_name,"fi-7480")
2440 || strstr (s->model_name,"fi-7460")){
2441
2442 /* weirdness */
2443 /* these machines have longer max paper at lower res */
2444 s->max_y_by_res[1].res = 400;
2445 s->max_y_by_res[1].len = 194268;
2446 s->max_y_by_res[2].res = 300;
2447 s->max_y_by_res[2].len = 260268;
2448 s->max_y_by_res[3].res = 200;
2449 s->max_y_by_res[3].len = 266268;
2450 }
2451
2452 else if (strstr (s->model_name,"fi-7030")){
2453
2454 /* weirdness */
2455 /* these machines have longer max paper at lower res */
2456 s->max_y_by_res[1].res = 400;
2457 s->max_y_by_res[1].len = 192000;
2458 s->max_y_by_res[2].res = 300;
2459 s->max_y_by_res[2].len = 258000;
2460 s->max_y_by_res[3].res = 200;
2461 s->max_y_by_res[3].len = 264000;
2462 }
2463
2464 else if (strstr (s->model_name,"fi-7700")
2465 || strstr (s->model_name,"fi-7600")){
2466
2467 /* weirdness */
2468 /* these machines have longer max paper at lower res */
2469 s->max_y_by_res[1].res = 400;
2470 s->max_y_by_res[1].len = 192000;
2471 s->max_y_by_res[2].res = 300;
2472 s->max_y_by_res[2].len = 258000;
2473 s->max_y_by_res[3].res = 200;
2474 s->max_y_by_res[3].len = 264000;
2475 }
2476
2477 DBG (10, "init_model: finish\n");
2478
2479 return SANE_STATUS_GOOD;
2480 }
2481
2482 static SANE_Status
set_mode(struct fujitsu *s, int mode)2483 set_mode (struct fujitsu *s, int mode)
2484 {
2485 int i;
2486 /* give the user what they asked for */
2487 s->u_mode = mode;
2488
2489 /* give the scanner the closest mode */
2490 for(i=MODE_COLOR;i>=mode;i--){
2491 if(s->can_mode[i] == 1){
2492 s->s_mode = i;
2493 }
2494 }
2495
2496 return SANE_STATUS_GOOD;
2497 }
2498
2499 /*
2500 * set good default user values.
2501 * struct is already initialized to 0.
2502 */
2503 static SANE_Status
init_user(struct fujitsu *s)2504 init_user (struct fujitsu *s)
2505 {
2506
2507 DBG (10, "init_user: start\n");
2508
2509 /* source */
2510 if(s->has_flatbed)
2511 s->source = SOURCE_FLATBED;
2512 else if(s->has_adf)
2513 s->source = SOURCE_ADF_FRONT;
2514 else if(s->has_return_path)
2515 s->source = SOURCE_CARD_FRONT;
2516
2517 /* scan mode */
2518 if(s->can_mode[MODE_LINEART])
2519 set_mode(s,MODE_LINEART);
2520 else if(s->can_mode[MODE_HALFTONE])
2521 set_mode(s,MODE_HALFTONE);
2522 else if(s->can_mode[MODE_GRAYSCALE])
2523 set_mode(s,MODE_GRAYSCALE);
2524 else if(s->can_mode[MODE_COLOR])
2525 set_mode(s,MODE_COLOR);
2526
2527 /*x res*/
2528 s->resolution_x = s->basic_x_res;
2529
2530 /*y res*/
2531 s->resolution_y = s->basic_y_res;
2532 if(s->resolution_y > s->resolution_x){
2533 s->resolution_y = s->resolution_x;
2534 }
2535
2536 /* page width US-Letter */
2537 s->page_width = 8.5 * 1200;
2538 if(s->page_width > s->max_x){
2539 s->page_width = s->max_x;
2540 }
2541
2542 /* page height US-Letter */
2543 s->page_height = 11 * 1200;
2544 set_max_y(s);
2545 if(s->page_height > s->max_y){
2546 s->page_height = s->max_y;
2547 }
2548
2549 /* bottom-right x */
2550 s->br_x = s->page_width;
2551
2552 /* bottom-right y */
2553 s->br_y = s->page_height;
2554
2555 /* gamma ramp exponent */
2556 s->gamma = 1;
2557
2558 /* safe endorser settings */
2559 s->u_endorser_bits=16;
2560 s->u_endorser_step=1;
2561 s->u_endorser_side=ED_back;
2562 if(s->has_endorser_f){
2563 s->u_endorser_side=ED_front;
2564 }
2565 s->u_endorser_dir=DIR_TTB;
2566 strcpy((char *)s->u_endorser_string,"%05ud");
2567
2568 /* more recent machines default to this being 'on', *
2569 * which causes the scanner to ingest multiple pages *
2570 * even when the user only wants one */
2571 s->buff_mode = MSEL_OFF;
2572
2573 /* useful features of newer scanners which we turn on,
2574 * even though the scanner defaults to off */
2575 if(s->has_paper_protect){
2576 s->paper_protect = MSEL_ON;
2577 }
2578 if(s->has_staple_detect){
2579 s->staple_detect = MSEL_ON;
2580 }
2581 if(s->has_df_recovery){
2582 s->df_recovery = MSEL_ON;
2583 }
2584 if(s->has_adv_paper_prot){
2585 s->adv_paper_prot = MSEL_ON;
2586 }
2587
2588 s->off_time = 240;
2589
2590 DBG (10, "init_user: finish\n");
2591
2592 return SANE_STATUS_GOOD;
2593 }
2594
2595 /*
2596 * This function presets the "option" array to blank
2597 */
2598 static SANE_Status
init_options(struct fujitsu *s)2599 init_options (struct fujitsu *s)
2600 {
2601 int i;
2602
2603 DBG (10, "init_options: start\n");
2604
2605 memset (s->opt, 0, sizeof (s->opt));
2606 for (i = 0; i < NUM_OPTIONS; ++i) {
2607 s->opt[i].name = "filler";
2608 s->opt[i].size = sizeof (SANE_Word);
2609 s->opt[i].cap = SANE_CAP_INACTIVE;
2610 }
2611
2612 /* go ahead and setup the first opt, because
2613 * frontend may call control_option on it
2614 * before calling get_option_descriptor
2615 */
2616 s->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS;
2617 s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
2618 s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
2619 s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
2620 s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
2621
2622 DBG (10, "init_options: finish\n");
2623
2624 return SANE_STATUS_GOOD;
2625 }
2626
2627 /*
2628 * send set window repeatedly to color scanners,
2629 * searching for valid color interlacing mode
2630 */
2631 static SANE_Status
init_interlace(struct fujitsu *s)2632 init_interlace (struct fujitsu *s)
2633 {
2634 SANE_Status ret = SANE_STATUS_GOOD;
2635 int curr_mode = s->u_mode;
2636 int oldDbg=0;
2637
2638 DBG (10, "init_interlace: start\n");
2639
2640 if(s->color_interlace != COLOR_INTERLACE_UNK){
2641 DBG (10, "init_interlace: already loaded\n");
2642 return SANE_STATUS_GOOD;
2643 }
2644
2645 if(!s->has_vuid_color){
2646 DBG (10, "init_interlace: color unsupported\n");
2647 return SANE_STATUS_GOOD;
2648 }
2649
2650 /* set to color mode first */
2651 set_mode(s,MODE_COLOR);
2652
2653 /* load our own private copy of scan params */
2654 ret = update_params(s);
2655 if (ret != SANE_STATUS_GOOD) {
2656 DBG (5, "init_interlace: ERROR: cannot update params\n");
2657 return ret;
2658 }
2659
2660 /*loop thru all the formats we support*/
2661 for(s->color_interlace = COLOR_INTERLACE_RGB;
2662 s->color_interlace <= COLOR_INTERLACE_RRGGBB;
2663 s->color_interlace++){
2664
2665 /* some of the following probes will produce errors */
2666 /* so we reduce the dbg level to reduce the noise */
2667 /* however, if user builds with NDEBUG, we can't do that */
2668 /* so we protect the code with the following macro */
2669 IF_DBG( oldDbg=DBG_LEVEL; )
2670 IF_DBG( if(DBG_LEVEL < 35){ DBG_LEVEL = 0; } )
2671
2672 ret = set_window(s);
2673
2674 IF_DBG (DBG_LEVEL = oldDbg;)
2675
2676 if (ret == SANE_STATUS_GOOD){
2677 break;
2678 }
2679 else{
2680 DBG (15, "init_interlace: not %d\n", s->color_interlace);
2681 }
2682 }
2683
2684 if (ret != SANE_STATUS_GOOD){
2685 DBG (5, "init_interlace: no valid interlacings\n");
2686 return SANE_STATUS_INVAL;
2687 }
2688
2689 DBG (15, "init_interlace: color_interlace: %d\n",s->color_interlace);
2690
2691 /* restore mode */
2692 set_mode(s,curr_mode);
2693
2694 DBG (10, "init_interlace: finish\n");
2695
2696 return SANE_STATUS_GOOD;
2697 }
2698
2699 /*
2700 * send diag query for serial number, and read result back
2701 * use it to build a unique name for scanner in s->serial_name
2702 */
2703 static SANE_Status
init_serial(struct fujitsu *s)2704 init_serial (struct fujitsu *s)
2705 {
2706 SANE_Status ret = SANE_STATUS_GOOD;
2707 unsigned int sn = 0;
2708
2709 unsigned char cmd[SEND_DIAGNOSTIC_len]; /*also big enough for READ_DIAG*/
2710 size_t cmdLen = SEND_DIAGNOSTIC_len;
2711
2712 unsigned char out[SD_gdi_len];
2713 size_t outLen = SD_gdi_len;
2714
2715 unsigned char in[RD_gdi_len];
2716 size_t inLen = RD_gdi_len;
2717
2718 DBG (10, "init_serial: start\n");
2719
2720 if (!s->has_cmd_sdiag || !s->has_cmd_rdiag || s->broken_diag_serial){
2721 DBG (5, "init_serial: send/read diag not supported, returning\n");
2722 return SANE_STATUS_INVAL;
2723 }
2724
2725 memset(cmd,0,cmdLen);
2726 set_SCSI_opcode(cmd, SEND_DIAGNOSTIC_code);
2727 set_SD_slftst(cmd, 0);
2728 set_SD_xferlen(cmd, outLen);
2729
2730 memcpy(out,SD_gdi_string,outLen);
2731
2732 ret = do_cmd (
2733 s, 1, 0,
2734 cmd, cmdLen,
2735 out, outLen,
2736 NULL, NULL
2737 );
2738
2739 if (ret != SANE_STATUS_GOOD){
2740 DBG (5, "init_serial: send diag error: %d\n", ret);
2741 return ret;
2742 }
2743
2744 memset(cmd,0,cmdLen);
2745 set_SCSI_opcode(cmd, READ_DIAGNOSTIC_code);
2746 set_RD_xferlen(cmd, inLen);
2747
2748 ret = do_cmd (
2749 s, 1, 0,
2750 cmd, cmdLen,
2751 NULL, 0,
2752 in, &inLen
2753 );
2754
2755 if (ret != SANE_STATUS_GOOD){
2756 DBG (5, "init_serial: read diag error: %d\n", ret);
2757 return ret;
2758 }
2759
2760 sn = get_RD_id_serial(in);
2761
2762 DBG (15, "init_serial: found sn %d\n",sn);
2763
2764 sprintf(s->serial_name, "%s:%d", s->model_name, sn);
2765
2766 DBG (15, "init_serial: serial_name: %s\n",s->serial_name);
2767
2768 DBG (10, "init_serial: finish\n");
2769
2770 return SANE_STATUS_GOOD;
2771 }
2772
2773 /*
2774 * From the SANE spec:
2775 * This function is used to establish a connection to a particular
2776 * device. The name of the device to be opened is passed in argument
2777 * name. If the call completes successfully, a handle for the device
2778 * is returned in *h. As a special case, specifying a zero-length
2779 * string as the device requests opening the first available device
2780 * (if there is such a device).
2781 */
2782 SANE_Status
sane_open(SANE_String_Const name, SANE_Handle * handle)2783 sane_open (SANE_String_Const name, SANE_Handle * handle)
2784 {
2785 struct fujitsu *dev = NULL;
2786 struct fujitsu *s = NULL;
2787 SANE_Status ret;
2788
2789 DBG (10, "sane_open: start\n");
2790
2791 if(fujitsu_devList){
2792 DBG (15, "sane_open: searching currently attached scanners\n");
2793 }
2794 else{
2795 DBG (15, "sane_open: no scanners currently attached, attaching\n");
2796
2797 ret = sane_get_devices(NULL,0);
2798 if(ret != SANE_STATUS_GOOD){
2799 return ret;
2800 }
2801 }
2802
2803 if(!name || !name[0]){
2804 DBG (15, "sane_open: no device requested, using default\n");
2805 s = fujitsu_devList;
2806 }
2807 else{
2808 DBG (15, "sane_open: device %s requested\n", name);
2809
2810 for (dev = fujitsu_devList; dev; dev = dev->next) {
2811 if (strcmp (dev->sane.name, name) == 0
2812 || strcmp (dev->device_name, name) == 0) { /*always allow sanei devname*/
2813 s = dev;
2814 break;
2815 }
2816 }
2817 }
2818
2819 if (!s) {
2820 DBG (5, "sane_open: no device found\n");
2821 return SANE_STATUS_INVAL;
2822 }
2823
2824 DBG (15, "sane_open: device %s found\n", s->sane.name);
2825
2826 *handle = s;
2827
2828 /* connect the fd so we can talk to scanner */
2829 ret = connect_fd(s);
2830 if(ret != SANE_STATUS_GOOD){
2831 return ret;
2832 }
2833
2834 DBG (10, "sane_open: finish\n");
2835
2836 return SANE_STATUS_GOOD;
2837 }
2838
2839 /*
2840 * @@ Section 3 - SANE Options functions
2841 */
2842
2843 /*
2844 * Returns the options we know.
2845 *
2846 * From the SANE spec:
2847 * This function is used to access option descriptors. The function
2848 * returns the option descriptor for option number n of the device
2849 * represented by handle h. Option number 0 is guaranteed to be a
2850 * valid option. Its value is an integer that specifies the number of
2851 * options that are available for device handle h (the count includes
2852 * option 0). If n is not a valid option index, the function returns
2853 * NULL. The returned option descriptor is guaranteed to remain valid
2854 * (and at the returned address) until the device is closed.
2855 */
2856 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)2857 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
2858 {
2859 struct fujitsu *s = handle;
2860 int i,j;
2861 SANE_Option_Descriptor *opt = &s->opt[option];
2862
2863 DBG (20, "sane_get_option_descriptor: %d\n", option);
2864
2865 if ((unsigned) option >= NUM_OPTIONS)
2866 return NULL;
2867
2868 /* "Mode" group -------------------------------------------------------- */
2869 if(option==OPT_STANDARD_GROUP){
2870 opt->name = SANE_NAME_STANDARD;
2871 opt->title = SANE_TITLE_STANDARD;
2872 opt->desc = SANE_DESC_STANDARD;
2873 opt->type = SANE_TYPE_GROUP;
2874 opt->constraint_type = SANE_CONSTRAINT_NONE;
2875 }
2876
2877 /* source */
2878 if(option==OPT_SOURCE){
2879 i=0;
2880 if(s->has_flatbed){
2881 s->source_list[i++]=STRING_FLATBED;
2882 }
2883 if(s->has_adf){
2884 s->source_list[i++]=STRING_ADFFRONT;
2885
2886 if(s->has_back){
2887 s->source_list[i++]=STRING_ADFBACK;
2888 }
2889 if(s->has_duplex){
2890 s->source_list[i++]=STRING_ADFDUPLEX;
2891 }
2892 }
2893 if(s->has_return_path){
2894 s->source_list[i++]=STRING_CARDFRONT;
2895
2896 if(s->has_back){
2897 s->source_list[i++]=STRING_CARDBACK;
2898 }
2899 if(s->has_duplex){
2900 s->source_list[i++]=STRING_CARDDUPLEX;
2901 }
2902 }
2903 s->source_list[i]=NULL;
2904
2905 opt->name = SANE_NAME_SCAN_SOURCE;
2906 opt->title = SANE_TITLE_SCAN_SOURCE;
2907 opt->desc = SANE_DESC_SCAN_SOURCE;
2908 opt->type = SANE_TYPE_STRING;
2909 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
2910 opt->constraint.string_list = s->source_list;
2911 opt->size = maxStringSize (opt->constraint.string_list);
2912 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2913 }
2914
2915 /* scan mode */
2916 if(option==OPT_MODE){
2917 i=0;
2918 if(s->can_mode[MODE_LINEART]){
2919 s->mode_list[i++]=STRING_LINEART;
2920 }
2921 if(s->can_mode[MODE_HALFTONE]){
2922 s->mode_list[i++]=STRING_HALFTONE;
2923 }
2924 if(s->can_mode[MODE_GRAYSCALE]){
2925 s->mode_list[i++]=STRING_GRAYSCALE;
2926 }
2927 if(s->can_mode[MODE_COLOR]){
2928 s->mode_list[i++]=STRING_COLOR;
2929 }
2930 s->mode_list[i]=NULL;
2931
2932 opt->name = SANE_NAME_SCAN_MODE;
2933 opt->title = SANE_TITLE_SCAN_MODE;
2934 opt->desc = SANE_DESC_SCAN_MODE;
2935 opt->type = SANE_TYPE_STRING;
2936 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
2937 opt->constraint.string_list = s->mode_list;
2938 opt->size = maxStringSize (opt->constraint.string_list);
2939 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2940 }
2941
2942 /* resolution */
2943 /* some scanners only support fixed res
2944 * build a list of possible choices */
2945 if(option==OPT_RES){
2946 opt->name = SANE_NAME_SCAN_RESOLUTION;
2947 opt->title = SANE_TITLE_SCAN_RESOLUTION;
2948 opt->desc = SANE_DESC_SCAN_RESOLUTION;
2949 opt->type = SANE_TYPE_INT;
2950 opt->unit = SANE_UNIT_DPI;
2951 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2952
2953 if(s->step_x_res[s->s_mode] && s->step_y_res[s->s_mode]){
2954 s->res_range.min = s->min_x_res;
2955 s->res_range.max = s->max_x_res;
2956 s->res_range.quant = s->step_x_res[s->s_mode];
2957 opt->constraint_type = SANE_CONSTRAINT_RANGE;
2958 opt->constraint.range = &s->res_range;
2959 }
2960 else{
2961 int reses[]
2962 = {60,75,100,120,150,160,180,200,240,300,320,400,480,600,800,1200};
2963
2964 i=0;
2965 for(j=0;j<16;j++){
2966 if(s->std_res[j]
2967 && s->max_x_res >= reses[j] && s->min_x_res <= reses[j]
2968 && s->max_y_res >= reses[j] && s->min_y_res <= reses[j]
2969 ){
2970 s->res_list[++i] = reses[j];
2971 }
2972 }
2973 s->res_list[0] = i;
2974
2975 opt->constraint_type = SANE_CONSTRAINT_WORD_LIST;
2976 opt->constraint.word_list = s->res_list;
2977 }
2978 }
2979
2980 /* "Geometry" group ---------------------------------------------------- */
2981 if(option==OPT_GEOMETRY_GROUP){
2982 opt->name = SANE_NAME_GEOMETRY;
2983 opt->title = SANE_TITLE_GEOMETRY;
2984 opt->desc = SANE_DESC_GEOMETRY;
2985 opt->type = SANE_TYPE_GROUP;
2986 opt->constraint_type = SANE_CONSTRAINT_NONE;
2987 }
2988
2989 /* top-left x */
2990 if(option==OPT_TL_X){
2991 /* values stored in 1200 dpi units */
2992 /* must be converted to MM for sane */
2993 s->tl_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x);
2994 s->tl_x_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_width(s));
2995 s->tl_x_range.quant = MM_PER_UNIT_FIX;
2996
2997 opt->name = SANE_NAME_SCAN_TL_X;
2998 opt->title = SANE_TITLE_SCAN_TL_X;
2999 opt->desc = SANE_DESC_SCAN_TL_X;
3000 opt->type = SANE_TYPE_FIXED;
3001 opt->unit = SANE_UNIT_MM;
3002 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3003 opt->constraint.range = &(s->tl_x_range);
3004 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3005 }
3006
3007 /* top-left y */
3008 if(option==OPT_TL_Y){
3009 /* values stored in 1200 dpi units */
3010 /* must be converted to MM for sane */
3011 s->tl_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y);
3012 s->tl_y_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_height(s));
3013 s->tl_y_range.quant = MM_PER_UNIT_FIX;
3014
3015 opt->name = SANE_NAME_SCAN_TL_Y;
3016 opt->title = SANE_TITLE_SCAN_TL_Y;
3017 opt->desc = SANE_DESC_SCAN_TL_Y;
3018 opt->type = SANE_TYPE_FIXED;
3019 opt->unit = SANE_UNIT_MM;
3020 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3021 opt->constraint.range = &(s->tl_y_range);
3022 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3023 }
3024
3025 /* bottom-right x */
3026 if(option==OPT_BR_X){
3027 /* values stored in 1200 dpi units */
3028 /* must be converted to MM for sane */
3029 s->br_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x);
3030 s->br_x_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_width(s));
3031 s->br_x_range.quant = MM_PER_UNIT_FIX;
3032
3033 opt->name = SANE_NAME_SCAN_BR_X;
3034 opt->title = SANE_TITLE_SCAN_BR_X;
3035 opt->desc = SANE_DESC_SCAN_BR_X;
3036 opt->type = SANE_TYPE_FIXED;
3037 opt->unit = SANE_UNIT_MM;
3038 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3039 opt->constraint.range = &(s->br_x_range);
3040 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3041 }
3042
3043 /* bottom-right y */
3044 if(option==OPT_BR_Y){
3045 /* values stored in 1200 dpi units */
3046 /* must be converted to MM for sane */
3047 s->br_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y);
3048 s->br_y_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_height(s));
3049 s->br_y_range.quant = MM_PER_UNIT_FIX;
3050
3051 opt->name = SANE_NAME_SCAN_BR_Y;
3052 opt->title = SANE_TITLE_SCAN_BR_Y;
3053 opt->desc = SANE_DESC_SCAN_BR_Y;
3054 opt->type = SANE_TYPE_FIXED;
3055 opt->unit = SANE_UNIT_MM;
3056 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3057 opt->constraint.range = &(s->br_y_range);
3058 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3059 }
3060
3061 /* page width */
3062 if(option==OPT_PAGE_WIDTH){
3063 /* values stored in 1200 dpi units */
3064 /* must be converted to MM for sane */
3065 s->paper_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x);
3066 s->paper_x_range.max = SCANNER_UNIT_TO_FIXED_MM(s->max_x);
3067 s->paper_x_range.quant = MM_PER_UNIT_FIX;
3068
3069 opt->name = SANE_NAME_PAGE_WIDTH;
3070 opt->title = SANE_TITLE_PAGE_WIDTH;
3071 opt->desc = SANE_DESC_PAGE_WIDTH;
3072 opt->type = SANE_TYPE_FIXED;
3073 opt->unit = SANE_UNIT_MM;
3074 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3075 opt->constraint.range = &s->paper_x_range;
3076
3077 if(s->has_adf || s->has_return_path){
3078 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3079 if(s->source == SOURCE_FLATBED){
3080 opt->cap |= SANE_CAP_INACTIVE;
3081 }
3082 }
3083 else{
3084 opt->cap = SANE_CAP_INACTIVE;
3085 }
3086 }
3087
3088 /* page height */
3089 if(option==OPT_PAGE_HEIGHT){
3090 /* values stored in 1200 dpi units */
3091 /* must be converted to MM for sane */
3092 s->paper_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y);
3093 s->paper_y_range.max = SCANNER_UNIT_TO_FIXED_MM(s->max_y);
3094 s->paper_y_range.quant = MM_PER_UNIT_FIX;
3095
3096 opt->name = SANE_NAME_PAGE_HEIGHT;
3097 opt->title = SANE_TITLE_PAGE_HEIGHT;
3098 opt->desc = SANE_DESC_PAGE_HEIGHT;
3099 opt->type = SANE_TYPE_FIXED;
3100 opt->unit = SANE_UNIT_MM;
3101 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3102 opt->constraint.range = &s->paper_y_range;
3103
3104 if(s->has_adf || s->has_return_path){
3105 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3106 if(s->source == SOURCE_FLATBED){
3107 opt->cap |= SANE_CAP_INACTIVE;
3108 }
3109 }
3110 else{
3111 opt->cap = SANE_CAP_INACTIVE;
3112 }
3113 }
3114
3115 /* "Enhancement" group ------------------------------------------------- */
3116 if(option==OPT_ENHANCEMENT_GROUP){
3117 opt->name = SANE_NAME_ENHANCEMENT;
3118 opt->title = SANE_TITLE_ENHANCEMENT;
3119 opt->desc = SANE_DESC_ENHANCEMENT;
3120 opt->type = SANE_TYPE_GROUP;
3121 opt->constraint_type = SANE_CONSTRAINT_NONE;
3122 }
3123
3124 /* brightness */
3125 if(option==OPT_BRIGHTNESS){
3126 opt->name = SANE_NAME_BRIGHTNESS;
3127 opt->title = SANE_TITLE_BRIGHTNESS;
3128 opt->desc = SANE_DESC_BRIGHTNESS;
3129 opt->type = SANE_TYPE_INT;
3130 opt->unit = SANE_UNIT_NONE;
3131 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3132 opt->constraint.range = &s->brightness_range;
3133 s->brightness_range.quant=1;
3134
3135 /* some have hardware brightness (always 0 to 255?) */
3136 /* some use LUT or GT (-127 to +127)*/
3137 if (s->brightness_steps || s->num_download_gamma){
3138 s->brightness_range.min=-127;
3139 s->brightness_range.max=127;
3140 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3141 }
3142 else{
3143 opt->cap = SANE_CAP_INACTIVE;
3144 }
3145 }
3146
3147 /* contrast */
3148 if(option==OPT_CONTRAST){
3149 opt->name = SANE_NAME_CONTRAST;
3150 opt->title = SANE_TITLE_CONTRAST;
3151 opt->desc = SANE_DESC_CONTRAST;
3152 opt->type = SANE_TYPE_INT;
3153 opt->unit = SANE_UNIT_NONE;
3154 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3155 opt->constraint.range = &s->contrast_range;
3156 s->contrast_range.quant=1;
3157
3158 /* some have hardware contrast (always 0 to 255?) */
3159 /* some use LUT or GT (-127 to +127)*/
3160 if (s->contrast_steps || s->num_download_gamma){
3161 s->contrast_range.min=-127;
3162 s->contrast_range.max=127;
3163 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3164 }
3165 else {
3166 opt->cap = SANE_CAP_INACTIVE;
3167 }
3168 }
3169
3170 /* gamma */
3171 if(option==OPT_GAMMA){
3172 opt->name = "gamma";
3173 opt->title = SANE_I18N ("Gamma function exponent");
3174 opt->desc = SANE_I18N ("Changes intensity of midtones");
3175 opt->type = SANE_TYPE_FIXED;
3176 opt->unit = SANE_UNIT_NONE;
3177 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3178 opt->constraint.range = &s->gamma_range;
3179
3180 /* value ranges from .3 to 5, should be log scale? */
3181 s->gamma_range.quant=SANE_FIX(0.01);
3182 s->gamma_range.min=SANE_FIX(0.3);
3183 s->gamma_range.max=SANE_FIX(5);
3184
3185 /* scanner has gamma via LUT or GT */
3186 /*if (s->num_download_gamma){
3187 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3188 }
3189 else {
3190 opt->cap = SANE_CAP_INACTIVE;
3191 }*/
3192
3193 opt->cap = SANE_CAP_INACTIVE;
3194 }
3195
3196 /*threshold*/
3197 if(option==OPT_THRESHOLD){
3198 opt->name = SANE_NAME_THRESHOLD;
3199 opt->title = SANE_TITLE_THRESHOLD;
3200 opt->desc = SANE_DESC_THRESHOLD;
3201 opt->type = SANE_TYPE_INT;
3202 opt->unit = SANE_UNIT_NONE;
3203 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3204 opt->constraint.range = &s->threshold_range;
3205 s->threshold_range.min=0;
3206 s->threshold_range.max=s->threshold_steps;
3207 s->threshold_range.quant=1;
3208
3209 if (s->threshold_steps){
3210 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3211 if(s->u_mode != MODE_LINEART){
3212 opt->cap |= SANE_CAP_INACTIVE;
3213 }
3214 }
3215 else {
3216 opt->cap = SANE_CAP_INACTIVE;
3217 }
3218 }
3219
3220 /* =============== common ipc params ================================ */
3221 if(option==OPT_RIF){
3222 opt->name = "rif";
3223 opt->title = SANE_I18N ("RIF");
3224 opt->desc = SANE_I18N ("Reverse image format");
3225 opt->type = SANE_TYPE_BOOL;
3226 opt->unit = SANE_UNIT_NONE;
3227 if (s->has_rif)
3228 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3229 else
3230 opt->cap = SANE_CAP_INACTIVE;
3231 }
3232
3233 if(option==OPT_HT_TYPE){
3234 i=0;
3235 s->ht_type_list[i++]=STRING_DEFAULT;
3236 s->ht_type_list[i++]=STRING_DITHER;
3237 s->ht_type_list[i++]=STRING_DIFFUSION;
3238 s->ht_type_list[i]=NULL;
3239
3240 opt->name = "ht-type";
3241 opt->title = SANE_I18N ("Halftone type");
3242 opt->desc = SANE_I18N ("Control type of halftone filter");
3243 opt->type = SANE_TYPE_STRING;
3244 opt->unit = SANE_UNIT_NONE;
3245
3246 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3247 opt->constraint.string_list = s->ht_type_list;
3248 opt->size = maxStringSize (opt->constraint.string_list);
3249
3250 if(s->has_diffusion){
3251 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3252 if(s->s_mode != MODE_HALFTONE){
3253 opt->cap |= SANE_CAP_INACTIVE;
3254 }
3255 }
3256 else
3257 opt->cap = SANE_CAP_INACTIVE;
3258 }
3259
3260 if(option==OPT_HT_PATTERN){
3261 opt->name = "ht-pattern";
3262 opt->title = SANE_I18N ("Halftone pattern");
3263 opt->desc = SANE_I18N ("Control pattern of halftone filter");
3264 opt->type = SANE_TYPE_INT;
3265 opt->unit = SANE_UNIT_NONE;
3266
3267 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3268 opt->constraint.range = &s->ht_pattern_range;
3269 s->ht_pattern_range.min=0;
3270 s->ht_pattern_range.max=s->num_internal_dither - 1;
3271 s->ht_pattern_range.quant=1;
3272
3273 if (s->num_internal_dither){
3274 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3275 if(s->s_mode != MODE_HALFTONE){
3276 opt->cap |= SANE_CAP_INACTIVE;
3277 }
3278 }
3279 else
3280 opt->cap = SANE_CAP_INACTIVE;
3281 }
3282
3283 if(option==OPT_OUTLINE){
3284 opt->name = "outline";
3285 opt->title = SANE_I18N ("Outline");
3286 opt->desc = SANE_I18N ("Perform outline extraction");
3287 opt->type = SANE_TYPE_BOOL;
3288 opt->unit = SANE_UNIT_NONE;
3289 if (s->has_outline)
3290 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3291 else
3292 opt->cap = SANE_CAP_INACTIVE;
3293 }
3294
3295 if(option==OPT_EMPHASIS){
3296 opt->name = "emphasis";
3297 opt->title = SANE_I18N ("Emphasis");
3298 opt->desc = SANE_I18N ("Negative to smooth or positive to sharpen image");
3299 opt->type = SANE_TYPE_INT;
3300 opt->unit = SANE_UNIT_NONE;
3301
3302 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3303 opt->constraint.range = &s->emphasis_range;
3304 s->emphasis_range.min=-128;
3305 s->emphasis_range.max=127;
3306 s->emphasis_range.quant=1;
3307
3308 if (s->has_emphasis)
3309 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3310 else
3311 opt->cap = SANE_CAP_INACTIVE;
3312 }
3313
3314 if(option==OPT_SEPARATION){
3315 opt->name = "separation";
3316 opt->title = SANE_I18N ("Separation");
3317 opt->desc = SANE_I18N ("Enable automatic separation of image and text");
3318 opt->type = SANE_TYPE_BOOL;
3319 opt->unit = SANE_UNIT_NONE;
3320 if (s->has_autosep)
3321 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3322 else
3323 opt->cap = SANE_CAP_INACTIVE;
3324 }
3325
3326 if(option==OPT_MIRRORING){
3327 opt->name = "mirroring";
3328 opt->title = SANE_I18N ("Mirroring");
3329 opt->desc = SANE_I18N ("Reflect output image horizontally");
3330 opt->type = SANE_TYPE_BOOL;
3331 opt->unit = SANE_UNIT_NONE;
3332 if (s->has_mirroring)
3333 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3334 else
3335 opt->cap = SANE_CAP_INACTIVE;
3336 }
3337
3338 if(option==OPT_WL_FOLLOW){
3339 i=0;
3340 s->wl_follow_list[i++]=STRING_DEFAULT;
3341 s->wl_follow_list[i++]=STRING_ON;
3342 s->wl_follow_list[i++]=STRING_OFF;
3343 s->wl_follow_list[i]=NULL;
3344
3345 opt->name = "wl-follow";
3346 opt->title = SANE_I18N ("White level follower");
3347 opt->desc = SANE_I18N ("Control white level follower");
3348 opt->type = SANE_TYPE_STRING;
3349 opt->unit = SANE_UNIT_NONE;
3350
3351 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3352 opt->constraint.string_list = s->wl_follow_list;
3353 opt->size = maxStringSize (opt->constraint.string_list);
3354
3355 if (s->has_wl_follow)
3356 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3357 else
3358 opt->cap = SANE_CAP_INACTIVE;
3359 }
3360
3361 /* =============== DTC params ================================ */
3362 /* enabled when in dtc mode (manually or by default) */
3363 if(option==OPT_BP_FILTER){
3364 opt->name = "bp-filter";
3365 opt->title = SANE_I18N ("BP filter");
3366 opt->desc = SANE_I18N ("Improves quality of high resolution ball-point pen text");
3367 opt->type = SANE_TYPE_BOOL;
3368 opt->unit = SANE_UNIT_NONE;
3369
3370 if ( s->has_dtc ){
3371 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3372 if(get_ipc_mode(s) == WD_ipc_SDTC){
3373 opt->cap |= SANE_CAP_INACTIVE;
3374 }
3375 }
3376 else
3377 opt->cap = SANE_CAP_INACTIVE;
3378 }
3379
3380 if(option==OPT_SMOOTHING){
3381 opt->name = "smoothing";
3382 opt->title = SANE_I18N ("Smoothing");
3383 opt->desc = SANE_I18N ("Enable smoothing for improved OCR");
3384 opt->type = SANE_TYPE_BOOL;
3385 opt->unit = SANE_UNIT_NONE;
3386
3387 if ( s->has_dtc ){
3388 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3389 if(get_ipc_mode(s) == WD_ipc_SDTC){
3390 opt->cap |= SANE_CAP_INACTIVE;
3391 }
3392 }
3393 else
3394 opt->cap = SANE_CAP_INACTIVE;
3395 }
3396
3397 if(option==OPT_GAMMA_CURVE){
3398 opt->name = "gamma-curve";
3399 opt->title = SANE_I18N ("Gamma curve");
3400 opt->desc = SANE_I18N ("Gamma curve, from light to dark, but upper two may not work");
3401 opt->type = SANE_TYPE_INT;
3402 opt->unit = SANE_UNIT_NONE;
3403
3404 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3405 opt->constraint.range = &s->gamma_curve_range;
3406 s->gamma_curve_range.min=0;
3407 s->gamma_curve_range.max=3;
3408 s->gamma_curve_range.quant=1;
3409
3410 if ( s->has_dtc ){
3411 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3412 if(get_ipc_mode(s) == WD_ipc_SDTC){
3413 opt->cap |= SANE_CAP_INACTIVE;
3414 }
3415 }
3416 else
3417 opt->cap = SANE_CAP_INACTIVE;
3418 }
3419
3420 if(option==OPT_THRESHOLD_CURVE){
3421 opt->name = "threshold-curve";
3422 opt->title = SANE_I18N ("Threshold curve");
3423 opt->desc = SANE_I18N ("Threshold curve, from light to dark, but upper two may not be linear");
3424 opt->type = SANE_TYPE_INT;
3425 opt->unit = SANE_UNIT_NONE;
3426
3427 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3428 opt->constraint.range = &s->threshold_curve_range;
3429 s->threshold_curve_range.min=0;
3430 s->threshold_curve_range.max=7;
3431 s->threshold_curve_range.quant=1;
3432
3433 if ( s->has_dtc ){
3434 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3435 if(get_ipc_mode(s) == WD_ipc_SDTC){
3436 opt->cap |= SANE_CAP_INACTIVE;
3437 }
3438 }
3439 else
3440 opt->cap = SANE_CAP_INACTIVE;
3441 }
3442
3443 if(option==OPT_THRESHOLD_WHITE){
3444 opt->name = "threshold-white";
3445 opt->title = SANE_I18N ("Threshold white");
3446 opt->desc = SANE_I18N ("Set pixels equal to threshold to white instead of black");
3447 opt->type = SANE_TYPE_BOOL;
3448 opt->unit = SANE_UNIT_NONE;
3449
3450 if ( s->has_dtc ){
3451 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3452 if(get_ipc_mode(s) == WD_ipc_SDTC){
3453 opt->cap |= SANE_CAP_INACTIVE;
3454 }
3455 }
3456 else
3457 opt->cap = SANE_CAP_INACTIVE;
3458 }
3459
3460 if(option==OPT_NOISE_REMOVAL){
3461 opt->name = "noise-removal";
3462 opt->title = SANE_I18N ("Noise removal");
3463 opt->desc = SANE_I18N ("Noise removal");
3464 opt->type = SANE_TYPE_BOOL;
3465 opt->unit = SANE_UNIT_NONE;
3466
3467 if ( s->has_dtc ){
3468 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3469 if(get_ipc_mode(s) == WD_ipc_SDTC){
3470 opt->cap |= SANE_CAP_INACTIVE;
3471 }
3472 }
3473 else
3474 opt->cap = SANE_CAP_INACTIVE;
3475 }
3476
3477 if(option==OPT_MATRIX_5){
3478 opt->name = "matrix-5x5";
3479 opt->title = SANE_I18N ("Matrix 5x5");
3480 opt->desc = SANE_I18N ("Remove 5 pixel square noise");
3481 opt->type = SANE_TYPE_BOOL;
3482 opt->unit = SANE_UNIT_NONE;
3483
3484 if ( s->has_dtc ){
3485 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3486 if(!s->noise_removal){
3487 opt->cap |= SANE_CAP_INACTIVE;
3488 }
3489 }
3490 else
3491 opt->cap = SANE_CAP_INACTIVE;
3492 }
3493
3494 if(option==OPT_MATRIX_4){
3495 opt->name = "matrix-4x4";
3496 opt->title = SANE_I18N ("Matrix 4x4");
3497 opt->desc = SANE_I18N ("Remove 4 pixel square noise");
3498 opt->type = SANE_TYPE_BOOL;
3499 opt->unit = SANE_UNIT_NONE;
3500
3501 if ( s->has_dtc ){
3502 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3503 if(!s->noise_removal){
3504 opt->cap |= SANE_CAP_INACTIVE;
3505 }
3506 }
3507 else
3508 opt->cap = SANE_CAP_INACTIVE;
3509 }
3510
3511 if(option==OPT_MATRIX_3){
3512 opt->name = "matrix-3x3";
3513 opt->title = SANE_I18N ("Matrix 3x3");
3514 opt->desc = SANE_I18N ("Remove 3 pixel square noise");
3515 opt->type = SANE_TYPE_BOOL;
3516 opt->unit = SANE_UNIT_NONE;
3517
3518 if ( s->has_dtc ){
3519 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3520 if(!s->noise_removal){
3521 opt->cap |= SANE_CAP_INACTIVE;
3522 }
3523 }
3524 else
3525 opt->cap = SANE_CAP_INACTIVE;
3526 }
3527
3528 if(option==OPT_MATRIX_2){
3529 opt->name = "matrix-2x2";
3530 opt->title = SANE_I18N ("Matrix 2x2");
3531 opt->desc = SANE_I18N ("Remove 2 pixel square noise");
3532 opt->type = SANE_TYPE_BOOL;
3533 opt->unit = SANE_UNIT_NONE;
3534
3535 if ( s->has_dtc ){
3536 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3537 if(!s->noise_removal){
3538 opt->cap |= SANE_CAP_INACTIVE;
3539 }
3540 }
3541 else
3542 opt->cap = SANE_CAP_INACTIVE;
3543 }
3544
3545 /* =============== SDTC param ================================ */
3546 /* enabled when in sdtc mode (manually or by default) */
3547 /* called variance with ipc2, sensitivity with ipc3 */
3548 if(option==OPT_VARIANCE){
3549 opt->name = "variance";
3550 opt->title = SANE_I18N ("Variance");
3551 opt->desc = SANE_I18N ("Set SDTC variance rate (sensitivity), 0 equals 127");
3552 opt->type = SANE_TYPE_INT;
3553 opt->unit = SANE_UNIT_NONE;
3554
3555 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3556 opt->constraint.range = &s->variance_range;
3557 s->variance_range.min=0;
3558 s->variance_range.max=255;
3559 s->variance_range.quant=1;
3560
3561 if ( s->has_sdtc ){
3562 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3563 if(get_ipc_mode(s) == WD_ipc_DTC){
3564 opt->cap |= SANE_CAP_INACTIVE;
3565 }
3566 }
3567 else
3568 opt->cap = SANE_CAP_INACTIVE;
3569 }
3570
3571 /* "Advanced" group ------------------------------------------------------ */
3572 if(option==OPT_ADVANCED_GROUP){
3573 opt->name = SANE_NAME_ADVANCED;
3574 opt->title = SANE_TITLE_ADVANCED;
3575 opt->desc = SANE_DESC_ADVANCED;
3576 opt->type = SANE_TYPE_GROUP;
3577 opt->constraint_type = SANE_CONSTRAINT_NONE;
3578 }
3579
3580 /*automatic width detection */
3581 if(option==OPT_AWD){
3582
3583 opt->name = "awd";
3584 opt->title = SANE_I18N ("Auto width detection");
3585 opt->desc = SANE_I18N ("Scanner detects paper sides. May reduce scanning speed.");
3586 opt->type = SANE_TYPE_BOOL;
3587 opt->unit = SANE_UNIT_NONE;
3588 opt->constraint_type = SANE_CONSTRAINT_NONE;
3589
3590 /* this option is useless by itself? */
3591 if (0 && s->has_MS_auto && s->has_hybrid_crop_deskew){
3592 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3593 }
3594 else
3595 opt->cap = SANE_CAP_INACTIVE;
3596 }
3597
3598 /*automatic length detection */
3599 if(option==OPT_ALD){
3600
3601 opt->name = "ald";
3602 opt->title = SANE_I18N ("Auto length detection");
3603 opt->desc = SANE_I18N ("Scanner detects paper lower edge. May confuse some frontends.");
3604 opt->type = SANE_TYPE_BOOL;
3605 opt->unit = SANE_UNIT_NONE;
3606 opt->constraint_type = SANE_CONSTRAINT_NONE;
3607
3608 if (s->has_MS_auto){
3609 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3610 }
3611 else
3612 opt->cap = SANE_CAP_INACTIVE;
3613 }
3614
3615 /*image compression*/
3616 if(option==OPT_COMPRESS){
3617 i=0;
3618 s->compress_list[i++]=STRING_NONE;
3619
3620 if(s->has_comp_JPG1){
3621 #ifndef SANE_JPEG_DISABLED
3622 s->compress_list[i++]=STRING_JPEG;
3623 #endif
3624 }
3625
3626 s->compress_list[i]=NULL;
3627
3628 opt->name = "compression";
3629 opt->title = SANE_I18N ("Compression");
3630 opt->desc = SANE_I18N ("Enable compressed data. May crash your front-end program");
3631 opt->type = SANE_TYPE_STRING;
3632 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3633 opt->constraint.string_list = s->compress_list;
3634 opt->size = maxStringSize (opt->constraint.string_list);
3635
3636 if (i > 1){
3637 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3638 if ( must_downsample(s) || s->s_mode < MODE_GRAYSCALE ){
3639 opt->cap |= SANE_CAP_INACTIVE;
3640 }
3641 }
3642 else
3643 opt->cap = SANE_CAP_INACTIVE;
3644 }
3645
3646 /*image compression arg*/
3647 if(option==OPT_COMPRESS_ARG){
3648
3649 opt->name = "compression-arg";
3650 opt->title = SANE_I18N ("Compression argument");
3651 opt->desc = SANE_I18N ("Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) is same as 4");
3652 opt->type = SANE_TYPE_INT;
3653 opt->unit = SANE_UNIT_NONE;
3654 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3655 opt->constraint.range = &s->compress_arg_range;
3656 s->compress_arg_range.quant=1;
3657
3658 if(s->has_comp_JPG1){
3659 s->compress_arg_range.min=0;
3660 s->compress_arg_range.max=7;
3661 #ifndef SANE_JPEG_DISABLED
3662 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
3663 #endif
3664
3665 if(s->compress != COMP_JPEG){
3666 opt->cap |= SANE_CAP_INACTIVE;
3667 }
3668 }
3669 else
3670 opt->cap = SANE_CAP_INACTIVE;
3671 }
3672
3673 /*double feed detection*/
3674 if(option==OPT_DF_ACTION){
3675 s->df_action_list[0] = STRING_DEFAULT;
3676 s->df_action_list[1] = STRING_CONTINUE;
3677 s->df_action_list[2] = STRING_STOP;
3678 s->df_action_list[3] = NULL;
3679
3680 opt->name = "df-action";
3681 opt->title = SANE_I18N ("DF action");
3682 opt->desc = SANE_I18N ("Action following double feed error");
3683 opt->type = SANE_TYPE_STRING;
3684 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3685 opt->constraint.string_list = s->df_action_list;
3686 opt->size = maxStringSize (opt->constraint.string_list);
3687
3688 if (s->has_MS_df)
3689 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3690 else
3691 opt->cap = SANE_CAP_INACTIVE;
3692 }
3693
3694 /*double feed by skew*/
3695 if(option==OPT_DF_SKEW){
3696
3697 opt->name = "df-skew";
3698 opt->title = SANE_I18N ("DF skew");
3699 opt->desc = SANE_I18N ("Enable double feed error due to skew");
3700 opt->type = SANE_TYPE_BOOL;
3701 opt->unit = SANE_UNIT_NONE;
3702 opt->constraint_type = SANE_CONSTRAINT_NONE;
3703
3704 if (s->has_MS_df){
3705 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3706 if(!s->df_action)
3707 opt->cap |= SANE_CAP_INACTIVE;
3708 }
3709 else
3710 opt->cap = SANE_CAP_INACTIVE;
3711 }
3712
3713 /*double feed by thickness */
3714 if(option==OPT_DF_THICKNESS){
3715
3716 opt->name = "df-thickness";
3717 opt->title = SANE_I18N ("DF thickness");
3718 opt->desc = SANE_I18N ("Enable double feed error due to paper thickness");
3719 opt->type = SANE_TYPE_BOOL;
3720 opt->unit = SANE_UNIT_NONE;
3721 opt->constraint_type = SANE_CONSTRAINT_NONE;
3722
3723 if (s->has_MS_df){
3724 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3725 if(!s->df_action)
3726 opt->cap |= SANE_CAP_INACTIVE;
3727 }
3728 else
3729 opt->cap = SANE_CAP_INACTIVE;
3730 }
3731
3732 /*double feed by length*/
3733 if(option==OPT_DF_LENGTH){
3734
3735 opt->name = "df-length";
3736 opt->title = SANE_I18N ("DF length");
3737 opt->desc = SANE_I18N ("Enable double feed error due to paper length");
3738 opt->type = SANE_TYPE_BOOL;
3739 opt->unit = SANE_UNIT_NONE;
3740 opt->constraint_type = SANE_CONSTRAINT_NONE;
3741
3742 if (s->has_MS_df){
3743 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3744 if(!s->df_action)
3745 opt->cap |= SANE_CAP_INACTIVE;
3746 }
3747 else
3748 opt->cap = SANE_CAP_INACTIVE;
3749 }
3750
3751 /*double feed length difference*/
3752 if(option==OPT_DF_DIFF){
3753 s->df_diff_list[0] = STRING_DEFAULT;
3754 s->df_diff_list[1] = STRING_10MM;
3755 s->df_diff_list[2] = STRING_15MM;
3756 s->df_diff_list[3] = STRING_20MM;
3757 s->df_diff_list[4] = NULL;
3758
3759 opt->name = "df-diff";
3760 opt->title = SANE_I18N ("DF length difference");
3761 opt->desc = SANE_I18N ("Difference in page length to trigger double feed error");
3762 opt->type = SANE_TYPE_STRING;
3763 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3764 opt->constraint.string_list = s->df_diff_list;
3765 opt->size = maxStringSize (opt->constraint.string_list);
3766
3767 if (s->has_MS_df){
3768 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3769 if(!s->df_action || !s->df_diff)
3770 opt->cap |= SANE_CAP_INACTIVE;
3771 }
3772 else
3773 opt->cap = SANE_CAP_INACTIVE;
3774 }
3775
3776 /*df_recovery*/
3777 if(option==OPT_DF_RECOVERY){
3778 s->df_recovery_list[0] = STRING_DEFAULT;
3779 s->df_recovery_list[1] = STRING_OFF;
3780 s->df_recovery_list[2] = STRING_ON;
3781 s->df_recovery_list[3] = NULL;
3782
3783 opt->name = "df-recovery";
3784 opt->title = SANE_I18N ("DF recovery mode");
3785 opt->desc = SANE_I18N ("Request scanner to reverse feed on paper jam");
3786 opt->type = SANE_TYPE_STRING;
3787 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3788 opt->constraint.string_list = s->df_recovery_list;
3789 opt->size = maxStringSize (opt->constraint.string_list);
3790 if (s->has_MS_df && s->has_df_recovery)
3791 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3792 else
3793 opt->cap = SANE_CAP_INACTIVE;
3794 }
3795
3796 /*paper_protect*/
3797 if(option==OPT_PAPER_PROTECT){
3798 s->paper_protect_list[0] = STRING_DEFAULT;
3799 s->paper_protect_list[1] = STRING_OFF;
3800 s->paper_protect_list[2] = STRING_ON;
3801 s->paper_protect_list[3] = NULL;
3802
3803 opt->name = "paper-protect";
3804 opt->title = SANE_I18N ("Paper protection");
3805 opt->desc = SANE_I18N ("Request scanner to predict jams in the ADF");
3806 opt->type = SANE_TYPE_STRING;
3807 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3808 opt->constraint.string_list = s->paper_protect_list;
3809 opt->size = maxStringSize (opt->constraint.string_list);
3810 if (s->has_MS_df && s->has_paper_protect)
3811 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3812 else
3813 opt->cap = SANE_CAP_INACTIVE;
3814 }
3815
3816 /*adv_paper_prot*/
3817 if(option==OPT_ADV_PAPER_PROT){
3818 s->adv_paper_prot_list[0] = STRING_DEFAULT;
3819 s->adv_paper_prot_list[1] = STRING_OFF;
3820 s->adv_paper_prot_list[2] = STRING_ON;
3821 s->adv_paper_prot_list[3] = NULL;
3822
3823 opt->name = "adv-paper-protect";
3824 opt->title = SANE_I18N ("Advanced paper protection");
3825 opt->desc = SANE_I18N ("Request scanner to predict jams in the ADF using improved sensors");
3826 opt->type = SANE_TYPE_STRING;
3827 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3828 opt->constraint.string_list = s->adv_paper_prot_list;
3829 opt->size = maxStringSize (opt->constraint.string_list);
3830 if (s->has_MS_df && s->has_adv_paper_prot)
3831 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3832 else
3833 opt->cap = SANE_CAP_INACTIVE;
3834 }
3835
3836 /*staple detection*/
3837 if(option==OPT_STAPLE_DETECT){
3838 s->staple_detect_list[0] = STRING_DEFAULT;
3839 s->staple_detect_list[1] = STRING_OFF;
3840 s->staple_detect_list[2] = STRING_ON;
3841 s->staple_detect_list[3] = NULL;
3842
3843 opt->name = "staple-detect";
3844 opt->title = SANE_I18N ("Staple detection");
3845 opt->desc = SANE_I18N ("Request scanner to detect jams in the ADF caused by staples");
3846 opt->type = SANE_TYPE_STRING;
3847 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3848 opt->constraint.string_list = s->staple_detect_list;
3849 opt->size = maxStringSize (opt->constraint.string_list);
3850 if (s->has_MS_df && s->has_staple_detect)
3851 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3852 else
3853 opt->cap = SANE_CAP_INACTIVE;
3854 }
3855
3856 /*background color*/
3857 if(option==OPT_BG_COLOR){
3858 s->bg_color_list[0] = STRING_DEFAULT;
3859 s->bg_color_list[1] = STRING_WHITE;
3860 s->bg_color_list[2] = STRING_BLACK;
3861 s->bg_color_list[3] = NULL;
3862
3863 opt->name = "bgcolor";
3864 opt->title = SANE_I18N ("Background color");
3865 opt->desc = SANE_I18N ("Set color of background for scans. May conflict with overscan option");
3866 opt->type = SANE_TYPE_STRING;
3867 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3868 opt->constraint.string_list = s->bg_color_list;
3869 opt->size = maxStringSize (opt->constraint.string_list);
3870 if (s->has_MS_bg)
3871 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3872 else
3873 opt->cap = SANE_CAP_INACTIVE;
3874 }
3875
3876 /*dropout color*/
3877 if(option==OPT_DROPOUT_COLOR){
3878 s->do_color_list[0] = STRING_DEFAULT;
3879 s->do_color_list[1] = STRING_RED;
3880 s->do_color_list[2] = STRING_GREEN;
3881 s->do_color_list[3] = STRING_BLUE;
3882 s->do_color_list[4] = NULL;
3883
3884 opt->name = "dropoutcolor";
3885 opt->title = SANE_I18N ("Dropout color");
3886 opt->desc = SANE_I18N ("One-pass scanners use only one color during gray or binary scanning, useful for colored paper or ink");
3887 opt->type = SANE_TYPE_STRING;
3888 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3889 opt->constraint.string_list = s->do_color_list;
3890 opt->size = maxStringSize (opt->constraint.string_list);
3891
3892 if (s->has_MS_dropout || s->has_vuid_3091 || must_downsample(s)){
3893 opt->cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT|SANE_CAP_ADVANCED;
3894 if(s->u_mode == MODE_COLOR)
3895 opt->cap |= SANE_CAP_INACTIVE;
3896 }
3897 else
3898 opt->cap = SANE_CAP_INACTIVE;
3899 }
3900
3901 /*buffer mode*/
3902 if(option==OPT_BUFF_MODE){
3903 s->buff_mode_list[0] = STRING_DEFAULT;
3904 s->buff_mode_list[1] = STRING_OFF;
3905 s->buff_mode_list[2] = STRING_ON;
3906 s->buff_mode_list[3] = NULL;
3907
3908 opt->name = "buffermode";
3909 opt->title = SANE_I18N ("Buffer mode");
3910 opt->desc = SANE_I18N ("Request scanner to read pages quickly from ADF into internal memory");
3911 opt->type = SANE_TYPE_STRING;
3912 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3913 opt->constraint.string_list = s->buff_mode_list;
3914 opt->size = maxStringSize (opt->constraint.string_list);
3915 if (s->has_MS_buff)
3916 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3917 else
3918 opt->cap = SANE_CAP_INACTIVE;
3919 }
3920
3921 /*prepick*/
3922 if(option==OPT_PREPICK){
3923 s->prepick_list[0] = STRING_DEFAULT;
3924 s->prepick_list[1] = STRING_OFF;
3925 s->prepick_list[2] = STRING_ON;
3926 s->prepick_list[3] = NULL;
3927
3928 opt->name = "prepick";
3929 opt->title = SANE_I18N ("Prepick");
3930 opt->desc = SANE_I18N ("Request scanner to grab next page from ADF");
3931 opt->type = SANE_TYPE_STRING;
3932 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3933 opt->constraint.string_list = s->prepick_list;
3934 opt->size = maxStringSize (opt->constraint.string_list);
3935 if (s->has_MS_prepick)
3936 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3937 else
3938 opt->cap = SANE_CAP_INACTIVE;
3939 }
3940
3941 /*overscan*/
3942 if(option==OPT_OVERSCAN){
3943 s->overscan_list[0] = STRING_DEFAULT;
3944 s->overscan_list[1] = STRING_OFF;
3945 s->overscan_list[2] = STRING_ON;
3946 s->overscan_list[3] = NULL;
3947
3948 opt->name = "overscan";
3949 opt->title = SANE_I18N ("Overscan");
3950 opt->desc = SANE_I18N ("Collect a few mm of background on top side of scan, before paper enters ADF, and increase maximum scan area beyond paper size, to allow collection on remaining sides. May conflict with bgcolor option");
3951 opt->type = SANE_TYPE_STRING;
3952 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3953 opt->constraint.string_list = s->overscan_list;
3954 opt->size = maxStringSize (opt->constraint.string_list);
3955 if (s->has_MS_auto && (s->os_x_basic || s->os_y_basic))
3956 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3957 else
3958 opt->cap = SANE_CAP_INACTIVE;
3959 }
3960
3961 /*sleep_time*/
3962 if(option==OPT_SLEEP_TIME){
3963 s->sleep_time_range.min = 0;
3964 s->sleep_time_range.max = 60;
3965 s->sleep_time_range.quant = 1;
3966
3967 opt->name = "sleeptimer";
3968 opt->title = SANE_I18N ("Sleep timer");
3969 opt->desc = SANE_I18N ("Time in minutes until the internal power supply switches to sleep mode");
3970 opt->type = SANE_TYPE_INT;
3971 opt->unit = SANE_UNIT_NONE;
3972 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3973 opt->constraint.range=&s->sleep_time_range;
3974 if(s->has_MS_sleep)
3975 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3976 else
3977 opt->cap = SANE_CAP_INACTIVE;
3978 }
3979
3980 /*off_time*/
3981 if(option==OPT_OFF_TIME){
3982 s->off_time_range.min = 0;
3983 s->off_time_range.max = 960;
3984 s->off_time_range.quant = 1;
3985
3986 opt->name = "offtimer";
3987 opt->title = SANE_I18N ("Off timer");
3988 opt->desc = SANE_I18N ("Time in minutes until the internal power supply switches the scanner off. Will be rounded to nearest 15 minutes. Zero means never power off.");
3989 opt->type = SANE_TYPE_INT;
3990 opt->unit = SANE_UNIT_NONE;
3991 opt->constraint_type = SANE_CONSTRAINT_RANGE;
3992 opt->constraint.range=&s->off_time_range;
3993 if(s->has_off_mode)
3994 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3995 else
3996 opt->cap = SANE_CAP_INACTIVE;
3997 }
3998
3999 /*duplex offset*/
4000 if(option==OPT_DUPLEX_OFFSET){
4001 s->duplex_offset_range.min = -16;
4002 s->duplex_offset_range.max = 16;
4003 s->duplex_offset_range.quant = 1;
4004
4005 opt->name = "duplexoffset";
4006 opt->title = SANE_I18N ("Duplex offset");
4007 opt->desc = SANE_I18N ("Adjust front/back offset");
4008 opt->type = SANE_TYPE_INT;
4009 opt->unit = SANE_UNIT_NONE;
4010 opt->constraint_type = SANE_CONSTRAINT_RANGE;
4011 opt->constraint.range = &s->duplex_offset_range;
4012 if(s->duplex_interlace == DUPLEX_INTERLACE_3091)
4013 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4014 else
4015 opt->cap = SANE_CAP_INACTIVE;
4016 }
4017
4018 if(option==OPT_GREEN_OFFSET){
4019 s->green_offset_range.min = -16;
4020 s->green_offset_range.max = 16;
4021 s->green_offset_range.quant = 1;
4022
4023 opt->name = "greenoffset";
4024 opt->title = SANE_I18N ("Green offset");
4025 opt->desc = SANE_I18N ("Adjust green/red offset");
4026 opt->type = SANE_TYPE_INT;
4027 opt->unit = SANE_UNIT_NONE;
4028 opt->constraint_type = SANE_CONSTRAINT_RANGE;
4029 opt->constraint.range = &s->green_offset_range;
4030 if(s->color_interlace == COLOR_INTERLACE_3091)
4031 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4032 else
4033 opt->cap = SANE_CAP_INACTIVE;
4034 }
4035
4036 if(option==OPT_BLUE_OFFSET){
4037 s->blue_offset_range.min = -16;
4038 s->blue_offset_range.max = 16;
4039 s->blue_offset_range.quant = 1;
4040
4041 opt->name = "blueoffset";
4042 opt->title = SANE_I18N ("Blue offset");
4043 opt->desc = SANE_I18N ("Adjust blue/red offset");
4044 opt->type = SANE_TYPE_INT;
4045 opt->unit = SANE_UNIT_NONE;
4046 opt->constraint_type = SANE_CONSTRAINT_RANGE;
4047 opt->constraint.range = &s->blue_offset_range;
4048 if(s->color_interlace == COLOR_INTERLACE_3091)
4049 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4050 else
4051 opt->cap = SANE_CAP_INACTIVE;
4052 }
4053
4054 if(option==OPT_LOW_MEM){
4055 opt->name = "lowmemory";
4056 opt->title = SANE_I18N ("Low Memory");
4057 opt->desc = SANE_I18N ("Limit driver memory usage for use in embedded systems. Causes some duplex transfers to alternate sides on each call to sane_read. Value of option 'side' can be used to determine correct image. This option should only be used with custom front-end software.");
4058 opt->type = SANE_TYPE_BOOL;
4059 opt->unit = SANE_UNIT_NONE;
4060 opt->size = sizeof(SANE_Word);
4061
4062 if (1)
4063 opt->cap= SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4064 else
4065 opt->cap = SANE_CAP_INACTIVE;
4066
4067 opt->constraint_type = SANE_CONSTRAINT_NONE;
4068 }
4069
4070 if(option==OPT_SIDE){
4071 opt->name = "side";
4072 opt->title = SANE_I18N ("Duplex side");
4073 opt->desc = SANE_I18N ("Tells which side (0=front, 1=back) of a duplex scan the next call to sane_read will return.");
4074 opt->type = SANE_TYPE_BOOL;
4075 opt->unit = SANE_UNIT_NONE;
4076 opt->size = sizeof(SANE_Word);
4077 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4078 opt->constraint_type = SANE_CONSTRAINT_NONE;
4079 }
4080
4081 /*deskew and crop by hardware*/
4082 if(option==OPT_HWDESKEWCROP){
4083 opt->name = "hwdeskewcrop";
4084 opt->title = SANE_I18N ("Hardware deskew and crop");
4085 opt->desc = SANE_I18N ("Request scanner to rotate and crop pages digitally.");
4086 opt->type = SANE_TYPE_BOOL;
4087 if (s->has_hybrid_crop_deskew)
4088 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4089 else
4090 opt->cap = SANE_CAP_INACTIVE;
4091 }
4092
4093 /*deskew by software*/
4094 if(option==OPT_SWDESKEW){
4095 opt->name = "swdeskew";
4096 opt->title = SANE_I18N ("Software deskew");
4097 opt->desc = SANE_I18N ("Request driver to rotate skewed pages digitally.");
4098 opt->type = SANE_TYPE_BOOL;
4099 if (1)
4100 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4101 else
4102 opt->cap = SANE_CAP_INACTIVE;
4103 }
4104
4105 /*software despeckle radius*/
4106 if(option==OPT_SWDESPECK){
4107
4108 opt->name = "swdespeck";
4109 opt->title = SANE_I18N ("Software despeckle diameter");
4110 opt->desc = SANE_I18N ("Maximum diameter of lone dots to remove from scan.");
4111 opt->type = SANE_TYPE_INT;
4112 opt->unit = SANE_UNIT_NONE;
4113 opt->constraint_type = SANE_CONSTRAINT_RANGE;
4114 opt->constraint.range = &s->swdespeck_range;
4115 s->swdespeck_range.quant=1;
4116
4117 if(1){
4118 s->swdespeck_range.min=0;
4119 s->swdespeck_range.max=9;
4120 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
4121 }
4122 else
4123 opt->cap = SANE_CAP_INACTIVE;
4124 }
4125
4126 /*crop by software*/
4127 if(option==OPT_SWCROP){
4128 opt->name = "swcrop";
4129 opt->title = SANE_I18N ("Software crop");
4130 opt->desc = SANE_I18N ("Request driver to remove border from pages digitally.");
4131 opt->type = SANE_TYPE_BOOL;
4132 if (1)
4133 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4134 else
4135 opt->cap = SANE_CAP_INACTIVE;
4136 }
4137
4138 /* Software blank page skip */
4139 if(option==OPT_SWSKIP){
4140
4141 opt->name = "swskip";
4142 opt->title = SANE_I18N ("Software blank skip percentage");
4143 opt->desc = SANE_I18N("Request driver to discard pages with low percentage of dark pixels");
4144 opt->type = SANE_TYPE_FIXED;
4145 opt->unit = SANE_UNIT_PERCENT;
4146 opt->constraint_type = SANE_CONSTRAINT_RANGE;
4147 opt->constraint.range = &s->swskip_range;
4148
4149 s->swskip_range.quant=SANE_FIX(0.10001);
4150 s->swskip_range.min=SANE_FIX(0);
4151 s->swskip_range.max=SANE_FIX(100);
4152
4153 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
4154 }
4155
4156 /*halt scanner feeder when cancelling*/
4157 if(option==OPT_HALT_ON_CANCEL){
4158 opt->name = "halt-on-cancel";
4159 opt->title = SANE_I18N ("Halt on Cancel");
4160 opt->desc = SANE_I18N ("Request driver to halt the paper feed instead of eject during a cancel.");
4161 opt->type = SANE_TYPE_BOOL;
4162 if (s->has_op_halt)
4163 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4164 else
4165 opt->cap = SANE_CAP_INACTIVE;
4166 }
4167
4168 /* "Endorser" group ------------------------------------------------------ */
4169 if(option==OPT_ENDORSER_GROUP){
4170 opt->name = "endorser-options";
4171 opt->title = SANE_I18N ("Endorser Options");
4172 opt->desc = SANE_I18N ("Controls for endorser unit");
4173 opt->type = SANE_TYPE_GROUP;
4174 opt->constraint_type = SANE_CONSTRAINT_NONE;
4175
4176 /*flaming hack to get scanimage to hide group*/
4177 if ( !(s->has_endorser_f || s->has_endorser_b) )
4178 opt->type = SANE_TYPE_BOOL;
4179 }
4180
4181 if(option==OPT_ENDORSER){
4182 opt->name = "endorser";
4183 opt->title = SANE_I18N ("Endorser");
4184 opt->desc = SANE_I18N ("Enable endorser unit");
4185 opt->type = SANE_TYPE_BOOL;
4186 opt->unit = SANE_UNIT_NONE;
4187 opt->size = sizeof(SANE_Word);
4188
4189 if (s->has_endorser_f || s->has_endorser_b)
4190 opt->cap= SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4191 else
4192 opt->cap = SANE_CAP_INACTIVE;
4193
4194 opt->constraint_type = SANE_CONSTRAINT_NONE;
4195 }
4196
4197 if(option==OPT_ENDORSER_BITS){
4198 opt->name = "endorser-bits";
4199 opt->title = SANE_I18N ("Endorser bits");
4200 opt->desc = SANE_I18N ("Determines maximum endorser counter value.");
4201 opt->type = SANE_TYPE_INT;
4202 opt->unit = SANE_UNIT_NONE;
4203 opt->size = sizeof(SANE_Word);
4204
4205 /*old type can't do this?*/
4206 if ((s->has_endorser_f && s->endorser_type_f != ET_OLD)
4207 || (s->has_endorser_b && s->endorser_type_b != ET_OLD)){
4208 opt->cap=SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4209 if(!s->u_endorser)
4210 opt->cap |= SANE_CAP_INACTIVE;
4211 }
4212 else
4213 opt->cap = SANE_CAP_INACTIVE;
4214
4215 opt->constraint_type = SANE_CONSTRAINT_RANGE;
4216 opt->constraint.range = &s->endorser_bits_range;
4217
4218 s->endorser_bits_range.min = 16;
4219 s->endorser_bits_range.max = 24;
4220 s->endorser_bits_range.quant = 8;
4221 }
4222
4223 if(option==OPT_ENDORSER_VAL){
4224 opt->name = "endorser-val";
4225 opt->title = SANE_I18N ("Endorser value");
4226 opt->desc = SANE_I18N ("Initial endorser counter value.");
4227 opt->type = SANE_TYPE_INT;
4228 opt->unit = SANE_UNIT_NONE;
4229 opt->size = sizeof(SANE_Word);
4230
4231 if (s->has_endorser_f || s->has_endorser_b){
4232 opt->cap=SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4233 if(!s->u_endorser)
4234 opt->cap |= SANE_CAP_INACTIVE;
4235 }
4236 else
4237 opt->cap = SANE_CAP_INACTIVE;
4238
4239 opt->constraint_type = SANE_CONSTRAINT_RANGE;
4240 opt->constraint.range = &s->endorser_val_range;
4241
4242 s->endorser_val_range.min = 0;
4243 s->endorser_val_range.max = (1 << s->u_endorser_bits)-1;
4244 s->endorser_val_range.quant = 1;
4245 }
4246
4247 if(option==OPT_ENDORSER_STEP){
4248 opt->name = "endorser-step";
4249 opt->title = SANE_I18N ("Endorser step");
4250 opt->desc = SANE_I18N ("Change endorser counter value by this much for each page.");
4251 opt->type = SANE_TYPE_INT;
4252 opt->unit = SANE_UNIT_NONE;
4253 opt->size = sizeof(SANE_Word);
4254
4255 if (s->has_endorser_f || s->has_endorser_b){
4256 opt->cap=SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4257 if(!s->u_endorser)
4258 opt->cap |= SANE_CAP_INACTIVE;
4259 }
4260 else
4261 opt->cap = SANE_CAP_INACTIVE;
4262
4263 opt->constraint_type = SANE_CONSTRAINT_RANGE;
4264 opt->constraint.range = &s->endorser_step_range;
4265
4266 s->endorser_step_range.min = -2;
4267 s->endorser_step_range.max = 2;
4268 s->endorser_step_range.quant = 1;
4269 }
4270
4271 if(option==OPT_ENDORSER_Y){
4272 opt->name = "endorser-y";
4273 opt->title = SANE_I18N ("Endorser Y");
4274 opt->desc = SANE_I18N ("Endorser print offset from top of paper.");
4275 opt->type = SANE_TYPE_FIXED;
4276 opt->unit = SANE_UNIT_MM;
4277 opt->size = sizeof(SANE_Word);
4278
4279 if (s->has_endorser_f || s->has_endorser_b){
4280 opt->cap=SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4281 if(!s->u_endorser)
4282 opt->cap |= SANE_CAP_INACTIVE;
4283 }
4284 else
4285 opt->cap = SANE_CAP_INACTIVE;
4286
4287 opt->constraint_type = SANE_CONSTRAINT_RANGE;
4288 opt->constraint.range = &(s->endorser_y_range);
4289
4290 /* values stored in 1200 dpi units */
4291 /* must be converted to MM for sane */
4292 s->endorser_y_range.min = SCANNER_UNIT_TO_FIXED_MM(0);
4293 s->endorser_y_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_height(s));
4294 s->endorser_y_range.quant = MM_PER_UNIT_FIX;
4295 }
4296
4297 if(option==OPT_ENDORSER_FONT){
4298 opt->name = "endorser-font";
4299 opt->title = SANE_I18N ("Endorser font");
4300 opt->desc = SANE_I18N ("Endorser printing font.");
4301 opt->type = SANE_TYPE_STRING;
4302 opt->unit = SANE_UNIT_NONE;
4303
4304 /*only newest can do this?*/
4305 if ((s->has_endorser_f && s->endorser_type_f == ET_40)
4306 || (s->has_endorser_b && s->endorser_type_b == ET_40)){
4307 opt->cap=SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4308 if(!s->u_endorser)
4309 opt->cap |= SANE_CAP_INACTIVE;
4310 }
4311 else
4312 opt->cap = SANE_CAP_INACTIVE;
4313
4314 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
4315 opt->constraint.string_list = s->endorser_font_list;
4316
4317 s->endorser_font_list[0] = STRING_HORIZONTAL;
4318 s->endorser_font_list[1] = STRING_HORIZONTALBOLD;
4319 s->endorser_font_list[2] = STRING_HORIZONTALNARROW;
4320 s->endorser_font_list[3] = STRING_VERTICAL;
4321 s->endorser_font_list[4] = STRING_VERTICALBOLD;
4322 s->endorser_font_list[5] = NULL;
4323
4324 opt->size = maxStringSize (opt->constraint.string_list);
4325 }
4326
4327 if(option==OPT_ENDORSER_DIR){
4328 opt->name = "endorser-dir";
4329 opt->title = SANE_I18N ("Endorser direction");
4330 opt->desc = SANE_I18N ("Endorser printing direction.");
4331 opt->type = SANE_TYPE_STRING;
4332 opt->unit = SANE_UNIT_NONE;
4333
4334 if (s->has_endorser_f || s->has_endorser_b){
4335 opt->cap=SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4336 if(!s->u_endorser)
4337 opt->cap |= SANE_CAP_INACTIVE;
4338 }
4339 else
4340 opt->cap = SANE_CAP_INACTIVE;
4341
4342 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
4343 opt->constraint.string_list = s->endorser_dir_list;
4344
4345 s->endorser_dir_list[0] = STRING_TOPTOBOTTOM;
4346 s->endorser_dir_list[1] = STRING_BOTTOMTOTOP;
4347 s->endorser_dir_list[2] = NULL;
4348
4349 opt->size = maxStringSize (opt->constraint.string_list);
4350 }
4351
4352 if(option==OPT_ENDORSER_SIDE){
4353 opt->name = "endorser-side";
4354 opt->title = SANE_I18N ("Endorser side");
4355 opt->desc = SANE_I18N ("Endorser printing side, requires hardware support to change");
4356 opt->type = SANE_TYPE_STRING;
4357 opt->unit = SANE_UNIT_NONE;
4358
4359 /* only show if both endorsers are installed */
4360 if (s->has_endorser_f && s->has_endorser_b){
4361 opt->cap=SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4362 if(!s->u_endorser)
4363 opt->cap |= SANE_CAP_INACTIVE;
4364 }
4365 else
4366 opt->cap = SANE_CAP_INACTIVE;
4367
4368 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
4369 opt->constraint.string_list = s->endorser_side_list;
4370
4371 s->endorser_side_list[0] = STRING_FRONT;
4372 s->endorser_side_list[1] = STRING_BACK;
4373 s->endorser_side_list[2] = NULL;
4374
4375 opt->size = maxStringSize (opt->constraint.string_list);
4376 }
4377
4378 if(option==OPT_ENDORSER_STRING){
4379 opt->name = "endorser-string";
4380 opt->title = SANE_I18N ("Endorser string");
4381 opt->desc = SANE_I18N ("Endorser alphanumeric print format. %05ud or %08ud at the end will be replaced by counter value.");
4382 opt->type = SANE_TYPE_STRING;
4383 opt->unit = SANE_UNIT_NONE;
4384 opt->size = s->endorser_string_len + 1;
4385
4386 if (s->has_endorser_f || s->has_endorser_b){
4387 opt->cap=SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
4388 if(!s->u_endorser)
4389 opt->cap |= SANE_CAP_INACTIVE;
4390 }
4391 else
4392 opt->cap = SANE_CAP_INACTIVE;
4393
4394 opt->constraint_type = SANE_CONSTRAINT_NONE;
4395 }
4396
4397 /* "Sensor" group ------------------------------------------------------ */
4398 if(option==OPT_SENSOR_GROUP){
4399 opt->name = SANE_NAME_SENSORS;
4400 opt->title = SANE_TITLE_SENSORS;
4401 opt->desc = SANE_DESC_SENSORS;
4402 opt->type = SANE_TYPE_GROUP;
4403 opt->constraint_type = SANE_CONSTRAINT_NONE;
4404 }
4405
4406 if(option==OPT_TOP){
4407 opt->name = "top-edge";
4408 opt->title = SANE_I18N ("Top edge");
4409 opt->desc = SANE_I18N ("Paper is pulled partly into ADF");
4410 opt->type = SANE_TYPE_BOOL;
4411 opt->unit = SANE_UNIT_NONE;
4412 if (s->has_cmd_hw_status || s->ghs_in_rs)
4413 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4414 else
4415 opt->cap = SANE_CAP_INACTIVE;
4416 }
4417
4418 if(option==OPT_A3){
4419 opt->name = "a3-paper";
4420 opt->title = SANE_I18N ("A3 paper");
4421 opt->desc = SANE_I18N ("A3 paper detected");
4422 opt->type = SANE_TYPE_BOOL;
4423 opt->unit = SANE_UNIT_NONE;
4424 if (s->has_cmd_hw_status)
4425 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4426 else
4427 opt->cap = SANE_CAP_INACTIVE;
4428 }
4429
4430 if(option==OPT_B4){
4431 opt->name = "b4-paper";
4432 opt->title = SANE_I18N ("B4 paper");
4433 opt->desc = SANE_I18N ("B4 paper detected");
4434 opt->type = SANE_TYPE_BOOL;
4435 opt->unit = SANE_UNIT_NONE;
4436 if (s->has_cmd_hw_status)
4437 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4438 else
4439 opt->cap = SANE_CAP_INACTIVE;
4440 }
4441
4442 if(option==OPT_A4){
4443 opt->name = "a4-paper";
4444 opt->title = SANE_I18N ("A4 paper");
4445 opt->desc = SANE_I18N ("A4 paper detected");
4446 opt->type = SANE_TYPE_BOOL;
4447 opt->unit = SANE_UNIT_NONE;
4448 if (s->has_cmd_hw_status)
4449 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4450 else
4451 opt->cap = SANE_CAP_INACTIVE;
4452 }
4453
4454 if(option==OPT_B5){
4455 opt->name = "b5-paper";
4456 opt->title = SANE_I18N ("B5 paper");
4457 opt->desc = SANE_I18N ("B5 paper detected");
4458 opt->type = SANE_TYPE_BOOL;
4459 opt->unit = SANE_UNIT_NONE;
4460 if (s->has_cmd_hw_status)
4461 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4462 else
4463 opt->cap = SANE_CAP_INACTIVE;
4464 }
4465
4466 if(option==OPT_HOPPER){
4467 opt->name = SANE_NAME_PAGE_LOADED;
4468 opt->title = SANE_TITLE_PAGE_LOADED;
4469 opt->desc = SANE_DESC_PAGE_LOADED;
4470 opt->type = SANE_TYPE_BOOL;
4471 opt->unit = SANE_UNIT_NONE;
4472 if (s->has_cmd_hw_status || s->ghs_in_rs)
4473 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4474 else
4475 opt->cap = SANE_CAP_INACTIVE;
4476 }
4477
4478 if(option==OPT_OMR){
4479 opt->name = "omr-df";
4480 opt->title = SANE_I18N ("OMR or DF");
4481 opt->desc = SANE_I18N ("OMR or double feed detected");
4482 opt->type = SANE_TYPE_BOOL;
4483 opt->unit = SANE_UNIT_NONE;
4484 if (s->has_cmd_hw_status)
4485 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4486 else
4487 opt->cap = SANE_CAP_INACTIVE;
4488 }
4489
4490 if(option==OPT_ADF_OPEN){
4491 opt->name = SANE_NAME_COVER_OPEN;
4492 opt->title = SANE_TITLE_COVER_OPEN;
4493 opt->desc = SANE_DESC_COVER_OPEN;
4494 opt->type = SANE_TYPE_BOOL;
4495 opt->unit = SANE_UNIT_NONE;
4496 if (s->has_cmd_hw_status || s->ghs_in_rs)
4497 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4498 else
4499 opt->cap = SANE_CAP_INACTIVE;
4500 }
4501
4502 if(option==OPT_CARD_LOADED){
4503 opt->name = "card-loaded";
4504 opt->title = SANE_I18N ("Card loaded");
4505 opt->desc = SANE_I18N ("Card slot contains paper");
4506 opt->type = SANE_TYPE_BOOL;
4507 opt->unit = SANE_UNIT_NONE;
4508 if (s->has_cmd_hw_status && s->has_return_path)
4509 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4510 else
4511 opt->cap = SANE_CAP_INACTIVE;
4512 }
4513
4514 if(option==OPT_SLEEP){
4515 opt->name = "power-save";
4516 opt->title = SANE_I18N ("Power saving");
4517 opt->desc = SANE_I18N ("Scanner in power saving mode");
4518 opt->type = SANE_TYPE_BOOL;
4519 opt->unit = SANE_UNIT_NONE;
4520 if (s->has_cmd_hw_status)
4521 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4522 else
4523 opt->cap = SANE_CAP_INACTIVE;
4524 }
4525
4526 if(option==OPT_SEND_SW){
4527 opt->name = SANE_NAME_EMAIL;
4528 opt->title = SANE_TITLE_EMAIL;
4529 opt->desc = SANE_DESC_EMAIL;
4530 opt->type = SANE_TYPE_BOOL;
4531 opt->unit = SANE_UNIT_NONE;
4532 if (s->has_cmd_hw_status || s->ghs_in_rs)
4533 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4534 else
4535 opt->cap = SANE_CAP_INACTIVE;
4536 }
4537
4538 if(option==OPT_MANUAL_FEED){
4539 opt->name = "manual-feed";
4540 opt->title = SANE_I18N ("Manual feed");
4541 opt->desc = SANE_I18N ("Manual feed selected");
4542 opt->type = SANE_TYPE_BOOL;
4543 opt->unit = SANE_UNIT_NONE;
4544 if (s->has_cmd_hw_status)
4545 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4546 else
4547 opt->cap = SANE_CAP_INACTIVE;
4548 }
4549
4550 if(option==OPT_SCAN_SW){
4551 opt->name = SANE_NAME_SCAN;
4552 opt->title = SANE_TITLE_SCAN;
4553 opt->desc = SANE_DESC_SCAN;
4554 opt->type = SANE_TYPE_BOOL;
4555 opt->unit = SANE_UNIT_NONE;
4556 if (s->has_cmd_hw_status || s->ghs_in_rs)
4557 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4558 else
4559 opt->cap = SANE_CAP_INACTIVE;
4560 }
4561
4562 if(option==OPT_FUNCTION){
4563 opt->name = "function";
4564 opt->title = SANE_I18N ("Function");
4565 opt->desc = SANE_I18N ("Function character on screen");
4566 opt->type = SANE_TYPE_INT;
4567 opt->unit = SANE_UNIT_NONE;
4568 if (s->has_cmd_hw_status || s->ghs_in_rs)
4569 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4570 else
4571 opt->cap = SANE_CAP_INACTIVE;
4572 }
4573
4574 if(option==OPT_INK_EMPTY){
4575 opt->name = "ink-low";
4576 opt->title = SANE_I18N ("Ink low");
4577 opt->desc = SANE_I18N ("Imprinter ink running low");
4578 opt->type = SANE_TYPE_BOOL;
4579 opt->unit = SANE_UNIT_NONE;
4580 if (s->has_cmd_hw_status && (s->has_endorser_f || s->has_endorser_b))
4581 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4582 else
4583 opt->cap = SANE_CAP_INACTIVE;
4584 }
4585
4586 if(option==OPT_DOUBLE_FEED){
4587 opt->name = "double-feed";
4588 opt->title = SANE_I18N ("Double feed");
4589 opt->desc = SANE_I18N ("Double feed detected");
4590 opt->type = SANE_TYPE_BOOL;
4591 opt->unit = SANE_UNIT_NONE;
4592 if (s->has_cmd_hw_status || s->ghs_in_rs)
4593 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4594 else
4595 opt->cap = SANE_CAP_INACTIVE;
4596 }
4597
4598 if(option==OPT_ERROR_CODE){
4599 opt->name = "error-code";
4600 opt->title = SANE_I18N ("Error code");
4601 opt->desc = SANE_I18N ("Hardware error code");
4602 opt->type = SANE_TYPE_INT;
4603 opt->unit = SANE_UNIT_NONE;
4604 if (s->has_cmd_hw_status)
4605 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4606 else
4607 opt->cap = SANE_CAP_INACTIVE;
4608 }
4609
4610 if(option==OPT_SKEW_ANGLE){
4611 opt->name = "skew-angle";
4612 opt->title = SANE_I18N ("Skew angle");
4613 opt->desc = SANE_I18N ("Requires black background for scanning");
4614 opt->type = SANE_TYPE_INT;
4615 opt->unit = SANE_UNIT_NONE;
4616 if (s->has_cmd_hw_status)
4617 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4618 else
4619 opt->cap = SANE_CAP_INACTIVE;
4620 }
4621
4622 if(option==OPT_INK_REMAIN){
4623 opt->name = "ink-remain";
4624 opt->title = SANE_I18N ("Ink remaining");
4625 opt->desc = SANE_I18N ("Imprinter ink level");
4626 opt->type = SANE_TYPE_INT;
4627 opt->unit = SANE_UNIT_NONE;
4628 if (s->has_cmd_hw_status && (s->has_endorser_f || s->has_endorser_b))
4629 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4630 else
4631 opt->cap = SANE_CAP_INACTIVE;
4632 }
4633
4634 if(option==OPT_DENSITY_SW){
4635 opt->name = "density";
4636 opt->title = SANE_I18N ("Density");
4637 opt->desc = SANE_I18N ("Density dial");
4638 opt->type = SANE_TYPE_INT;
4639 opt->unit = SANE_UNIT_NONE;
4640 if (s->ghs_in_rs)
4641 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4642 else
4643 opt->cap = SANE_CAP_INACTIVE;
4644 }
4645
4646 if(option==OPT_DUPLEX_SW){
4647 opt->name = "duplex";
4648 opt->title = SANE_I18N ("Duplex switch");
4649 opt->desc = SANE_I18N ("Duplex switch");
4650 opt->type = SANE_TYPE_BOOL;
4651 opt->unit = SANE_UNIT_NONE;
4652 if (s->ghs_in_rs)
4653 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
4654 else
4655 opt->cap = SANE_CAP_INACTIVE;
4656 }
4657
4658 return opt;
4659 }
4660
4661 /**
4662 * Gets or sets an option value.
4663 *
4664 * From the SANE spec:
4665 * This function is used to set or inquire the current value of option
4666 * number n of the device represented by handle h. The manner in which
4667 * the option is controlled is specified by parameter action. The
4668 * possible values of this parameter are described in more detail
4669 * below. The value of the option is passed through argument val. It
4670 * is a pointer to the memory that holds the option value. The memory
4671 * area pointed to by v must be big enough to hold the entire option
4672 * value (determined by member size in the corresponding option
4673 * descriptor).
4674 *
4675 * The only exception to this rule is that when setting the value of a
4676 * string option, the string pointed to by argument v may be shorter
4677 * since the backend will stop reading the option value upon
4678 * encountering the first NUL terminator in the string. If argument i
4679 * is not NULL, the value of *i will be set to provide details on how
4680 * well the request has been met.
4681 */
4682 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int * info)4683 sane_control_option (SANE_Handle handle, SANE_Int option,
4684 SANE_Action action, void *val, SANE_Int * info)
4685 {
4686 struct fujitsu *s = (struct fujitsu *) handle;
4687 SANE_Int dummy = 0;
4688 SANE_Status ret = SANE_STATUS_GOOD;
4689
4690 /* Make sure that all those statements involving *info cannot break (better
4691 * than having to do "if (info) ..." everywhere!)
4692 */
4693 if (info == 0)
4694 info = &dummy;
4695
4696 /*blast info in case frontend forgot*/
4697 *info = 0;
4698
4699 if (option >= NUM_OPTIONS) {
4700 DBG (5, "sane_control_option: %d too big\n", option);
4701 return SANE_STATUS_INVAL;
4702 }
4703
4704 if (!SANE_OPTION_IS_ACTIVE (s->opt[option].cap)) {
4705 DBG (5, "sane_control_option: %d inactive\n", option);
4706 return SANE_STATUS_INVAL;
4707 }
4708
4709 /*
4710 * SANE_ACTION_GET_VALUE: We have to find out the current setting and
4711 * return it in a human-readable form (often, text).
4712 */
4713 if (action == SANE_ACTION_GET_VALUE) {
4714 SANE_Word * val_p = (SANE_Word *) val;
4715
4716 DBG (20, "sane_control_option: get value for '%s' (%d)\n", s->opt[option].name,option);
4717
4718 switch (option) {
4719
4720 case OPT_NUM_OPTS:
4721 *val_p = NUM_OPTIONS;
4722 return SANE_STATUS_GOOD;
4723
4724 case OPT_SOURCE:
4725 if(s->source == SOURCE_FLATBED){
4726 strcpy (val, STRING_FLATBED);
4727 }
4728 else if(s->source == SOURCE_ADF_FRONT){
4729 strcpy (val, STRING_ADFFRONT);
4730 }
4731 else if(s->source == SOURCE_ADF_BACK){
4732 strcpy (val, STRING_ADFBACK);
4733 }
4734 else if(s->source == SOURCE_ADF_DUPLEX){
4735 strcpy (val, STRING_ADFDUPLEX);
4736 }
4737 else if(s->source == SOURCE_CARD_FRONT){
4738 strcpy (val, STRING_CARDFRONT);
4739 }
4740 else if(s->source == SOURCE_CARD_BACK){
4741 strcpy (val, STRING_CARDBACK);
4742 }
4743 else if(s->source == SOURCE_CARD_DUPLEX){
4744 strcpy (val, STRING_CARDDUPLEX);
4745 }
4746 return SANE_STATUS_GOOD;
4747
4748 case OPT_MODE:
4749 if(s->u_mode == MODE_LINEART){
4750 strcpy (val, STRING_LINEART);
4751 }
4752 else if(s->u_mode == MODE_HALFTONE){
4753 strcpy (val, STRING_HALFTONE);
4754 }
4755 else if(s->u_mode == MODE_GRAYSCALE){
4756 strcpy (val, STRING_GRAYSCALE);
4757 }
4758 else if(s->u_mode == MODE_COLOR){
4759 strcpy (val, STRING_COLOR);
4760 }
4761 return SANE_STATUS_GOOD;
4762
4763 case OPT_RES:
4764 *val_p = s->resolution_x;
4765 return SANE_STATUS_GOOD;
4766
4767 case OPT_TL_X:
4768 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->tl_x);
4769 return SANE_STATUS_GOOD;
4770
4771 case OPT_TL_Y:
4772 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->tl_y);
4773 return SANE_STATUS_GOOD;
4774
4775 case OPT_BR_X:
4776 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->br_x);
4777 return SANE_STATUS_GOOD;
4778
4779 case OPT_BR_Y:
4780 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->br_y);
4781 return SANE_STATUS_GOOD;
4782
4783 case OPT_PAGE_WIDTH:
4784 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->page_width);
4785 return SANE_STATUS_GOOD;
4786
4787 case OPT_PAGE_HEIGHT:
4788 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->page_height);
4789 return SANE_STATUS_GOOD;
4790
4791 case OPT_BRIGHTNESS:
4792 *val_p = s->brightness;
4793 return SANE_STATUS_GOOD;
4794
4795 case OPT_CONTRAST:
4796 *val_p = s->contrast;
4797 return SANE_STATUS_GOOD;
4798
4799 case OPT_GAMMA:
4800 *val_p = SANE_FIX(s->gamma);
4801 return SANE_STATUS_GOOD;
4802
4803 case OPT_THRESHOLD:
4804 *val_p = s->threshold;
4805 return SANE_STATUS_GOOD;
4806
4807 /* IPC */
4808 case OPT_RIF:
4809 *val_p = s->rif;
4810 return SANE_STATUS_GOOD;
4811
4812 case OPT_HT_TYPE:
4813 switch (s->ht_type) {
4814 case WD_ht_type_DEFAULT:
4815 strcpy (val, STRING_DEFAULT);
4816 break;
4817 case WD_ht_type_DITHER:
4818 strcpy (val, STRING_DITHER);
4819 break;
4820 case WD_ht_type_DIFFUSION:
4821 strcpy (val, STRING_DIFFUSION);
4822 break;
4823 }
4824 return SANE_STATUS_GOOD;
4825
4826 case OPT_HT_PATTERN:
4827 *val_p = s->ht_pattern;
4828 return SANE_STATUS_GOOD;
4829
4830 case OPT_OUTLINE:
4831 *val_p = s->outline;
4832 return SANE_STATUS_GOOD;
4833
4834 case OPT_EMPHASIS:
4835 *val_p = s->emphasis;
4836 return SANE_STATUS_GOOD;
4837
4838 case OPT_SEPARATION:
4839 *val_p = s->separation;
4840 return SANE_STATUS_GOOD;
4841
4842 case OPT_MIRRORING:
4843 *val_p = s->mirroring;
4844 return SANE_STATUS_GOOD;
4845
4846 case OPT_WL_FOLLOW:
4847 switch (s->wl_follow) {
4848 case WD_wl_follow_DEFAULT:
4849 strcpy (val, STRING_DEFAULT);
4850 break;
4851 case WD_wl_follow_ON:
4852 strcpy (val, STRING_ON);
4853 break;
4854 case WD_wl_follow_OFF:
4855 strcpy (val, STRING_OFF);
4856 break;
4857 }
4858 return SANE_STATUS_GOOD;
4859
4860 /* DTC params*/
4861 case OPT_BP_FILTER:
4862 *val_p = s->bp_filter;
4863 return SANE_STATUS_GOOD;
4864
4865 case OPT_SMOOTHING:
4866 *val_p = s->smoothing;
4867 return SANE_STATUS_GOOD;
4868
4869 case OPT_GAMMA_CURVE:
4870 *val_p = s->gamma_curve;
4871 return SANE_STATUS_GOOD;
4872
4873 case OPT_THRESHOLD_CURVE:
4874 *val_p = s->threshold_curve;
4875 return SANE_STATUS_GOOD;
4876
4877 case OPT_THRESHOLD_WHITE:
4878 *val_p = s->threshold_white;
4879 return SANE_STATUS_GOOD;
4880
4881 case OPT_NOISE_REMOVAL:
4882 *val_p = s->noise_removal;
4883 return SANE_STATUS_GOOD;
4884
4885 case OPT_MATRIX_5:
4886 *val_p = s->matrix_5;
4887 return SANE_STATUS_GOOD;
4888
4889 case OPT_MATRIX_4:
4890 *val_p = s->matrix_4;
4891 return SANE_STATUS_GOOD;
4892
4893 case OPT_MATRIX_3:
4894 *val_p = s->matrix_3;
4895 return SANE_STATUS_GOOD;
4896
4897 case OPT_MATRIX_2:
4898 *val_p = s->matrix_2;
4899 return SANE_STATUS_GOOD;
4900
4901 /* SDTC params*/
4902 case OPT_VARIANCE:
4903 *val_p = s->variance;
4904 return SANE_STATUS_GOOD;
4905
4906 /* Advanced Group */
4907 case OPT_AWD:
4908 *val_p = s->awd;
4909 return SANE_STATUS_GOOD;
4910
4911 case OPT_ALD:
4912 *val_p = s->ald;
4913 return SANE_STATUS_GOOD;
4914
4915 case OPT_COMPRESS:
4916 if(s->compress == COMP_JPEG){
4917 strcpy (val, STRING_JPEG);
4918 }
4919 else{
4920 strcpy (val, STRING_NONE);
4921 }
4922 return SANE_STATUS_GOOD;
4923
4924 case OPT_COMPRESS_ARG:
4925 *val_p = s->compress_arg;
4926 return SANE_STATUS_GOOD;
4927
4928 case OPT_DF_ACTION:
4929 switch (s->df_action) {
4930 case DF_DEFAULT:
4931 strcpy (val, STRING_DEFAULT);
4932 break;
4933 case DF_CONTINUE:
4934 strcpy (val, STRING_CONTINUE);
4935 break;
4936 case DF_STOP:
4937 strcpy (val, STRING_STOP);
4938 break;
4939 }
4940 return SANE_STATUS_GOOD;
4941
4942 case OPT_DF_SKEW:
4943 *val_p = s->df_skew;
4944 return SANE_STATUS_GOOD;
4945
4946 case OPT_DF_THICKNESS:
4947 *val_p = s->df_thickness;
4948 return SANE_STATUS_GOOD;
4949
4950 case OPT_DF_LENGTH:
4951 *val_p = s->df_length;
4952 return SANE_STATUS_GOOD;
4953
4954 case OPT_DF_DIFF:
4955 switch (s->df_diff) {
4956 case MSEL_df_diff_DEFAULT:
4957 strcpy (val, STRING_DEFAULT);
4958 break;
4959 case MSEL_df_diff_10MM:
4960 strcpy (val, STRING_10MM);
4961 break;
4962 case MSEL_df_diff_15MM:
4963 strcpy (val, STRING_15MM);
4964 break;
4965 case MSEL_df_diff_20MM:
4966 strcpy (val, STRING_20MM);
4967 break;
4968 }
4969 return SANE_STATUS_GOOD;
4970
4971 case OPT_DF_RECOVERY:
4972 switch (s->df_recovery) {
4973 case MSEL_DEFAULT:
4974 strcpy (val, STRING_DEFAULT);
4975 break;
4976 case MSEL_ON:
4977 strcpy (val, STRING_ON);
4978 break;
4979 case MSEL_OFF:
4980 strcpy (val, STRING_OFF);
4981 break;
4982 }
4983 return SANE_STATUS_GOOD;
4984
4985 case OPT_PAPER_PROTECT:
4986 switch (s->paper_protect) {
4987 case MSEL_DEFAULT:
4988 strcpy (val, STRING_DEFAULT);
4989 break;
4990 case MSEL_ON:
4991 strcpy (val, STRING_ON);
4992 break;
4993 case MSEL_OFF:
4994 strcpy (val, STRING_OFF);
4995 break;
4996 }
4997 return SANE_STATUS_GOOD;
4998
4999 case OPT_ADV_PAPER_PROT:
5000 switch (s->adv_paper_prot) {
5001 case MSEL_DEFAULT:
5002 strcpy (val, STRING_DEFAULT);
5003 break;
5004 case MSEL_ON:
5005 strcpy (val, STRING_ON);
5006 break;
5007 case MSEL_OFF:
5008 strcpy (val, STRING_OFF);
5009 break;
5010 }
5011 return SANE_STATUS_GOOD;
5012
5013 case OPT_STAPLE_DETECT:
5014 switch (s->staple_detect) {
5015 case MSEL_DEFAULT:
5016 strcpy (val, STRING_DEFAULT);
5017 break;
5018 case MSEL_ON:
5019 strcpy (val, STRING_ON);
5020 break;
5021 case MSEL_OFF:
5022 strcpy (val, STRING_OFF);
5023 break;
5024 }
5025 return SANE_STATUS_GOOD;
5026
5027 case OPT_BG_COLOR:
5028 switch (s->bg_color) {
5029 case COLOR_DEFAULT:
5030 strcpy (val, STRING_DEFAULT);
5031 break;
5032 case COLOR_WHITE:
5033 strcpy (val, STRING_WHITE);
5034 break;
5035 case COLOR_BLACK:
5036 strcpy (val, STRING_BLACK);
5037 break;
5038 }
5039 return SANE_STATUS_GOOD;
5040
5041 case OPT_DROPOUT_COLOR:
5042 switch (s->dropout_color) {
5043 case COLOR_DEFAULT:
5044 strcpy (val, STRING_DEFAULT);
5045 break;
5046 case COLOR_RED:
5047 strcpy (val, STRING_RED);
5048 break;
5049 case COLOR_GREEN:
5050 strcpy (val, STRING_GREEN);
5051 break;
5052 case COLOR_BLUE:
5053 strcpy (val, STRING_BLUE);
5054 break;
5055 }
5056 return SANE_STATUS_GOOD;
5057
5058 case OPT_BUFF_MODE:
5059 switch (s->buff_mode) {
5060 case MSEL_DEFAULT:
5061 strcpy (val, STRING_DEFAULT);
5062 break;
5063 case MSEL_ON:
5064 strcpy (val, STRING_ON);
5065 break;
5066 case MSEL_OFF:
5067 strcpy (val, STRING_OFF);
5068 break;
5069 }
5070 return SANE_STATUS_GOOD;
5071
5072 case OPT_PREPICK:
5073 switch (s->prepick) {
5074 case MSEL_DEFAULT:
5075 strcpy (val, STRING_DEFAULT);
5076 break;
5077 case MSEL_ON:
5078 strcpy (val, STRING_ON);
5079 break;
5080 case MSEL_OFF:
5081 strcpy (val, STRING_OFF);
5082 break;
5083 }
5084 return SANE_STATUS_GOOD;
5085
5086 case OPT_OVERSCAN:
5087 switch (s->overscan) {
5088 case MSEL_DEFAULT:
5089 strcpy (val, STRING_DEFAULT);
5090 break;
5091 case MSEL_ON:
5092 strcpy (val, STRING_ON);
5093 break;
5094 case MSEL_OFF:
5095 strcpy (val, STRING_OFF);
5096 break;
5097 }
5098 return SANE_STATUS_GOOD;
5099
5100 case OPT_SLEEP_TIME:
5101 *val_p = s->sleep_time;
5102 return SANE_STATUS_GOOD;
5103
5104 case OPT_OFF_TIME:
5105 *val_p = s->off_time;
5106 return SANE_STATUS_GOOD;
5107
5108 case OPT_DUPLEX_OFFSET:
5109 *val_p = s->duplex_offset;
5110 return SANE_STATUS_GOOD;
5111
5112 case OPT_GREEN_OFFSET:
5113 *val_p = s->green_offset;
5114 return SANE_STATUS_GOOD;
5115
5116 case OPT_BLUE_OFFSET:
5117 *val_p = s->blue_offset;
5118 return SANE_STATUS_GOOD;
5119
5120 case OPT_LOW_MEM:
5121 *val_p = s->low_mem;
5122 return SANE_STATUS_GOOD;
5123
5124 case OPT_SIDE:
5125 *val_p = s->side;
5126 return SANE_STATUS_GOOD;
5127
5128 case OPT_HWDESKEWCROP:
5129 *val_p = s->hwdeskewcrop;
5130 return SANE_STATUS_GOOD;
5131
5132 case OPT_SWDESKEW:
5133 *val_p = s->swdeskew;
5134 return SANE_STATUS_GOOD;
5135
5136 case OPT_SWDESPECK:
5137 *val_p = s->swdespeck;
5138 return SANE_STATUS_GOOD;
5139
5140 case OPT_SWCROP:
5141 *val_p = s->swcrop;
5142 return SANE_STATUS_GOOD;
5143
5144 case OPT_SWSKIP:
5145 *val_p = SANE_FIX(s->swskip);
5146 return SANE_STATUS_GOOD;
5147
5148 case OPT_HALT_ON_CANCEL:
5149 *val_p = s->halt_on_cancel;
5150 return SANE_STATUS_GOOD;
5151
5152 /* Endorser Group */
5153 case OPT_ENDORSER:
5154 *val_p = s->u_endorser;
5155 return SANE_STATUS_GOOD;
5156
5157 case OPT_ENDORSER_BITS:
5158 *val_p = s->u_endorser_bits;
5159 return SANE_STATUS_GOOD;
5160
5161 case OPT_ENDORSER_VAL:
5162 *val_p = s->u_endorser_val;
5163 return SANE_STATUS_GOOD;
5164
5165 case OPT_ENDORSER_STEP:
5166 *val_p = s->u_endorser_step;
5167 return SANE_STATUS_GOOD;
5168
5169 case OPT_ENDORSER_Y:
5170 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u_endorser_y);
5171 return SANE_STATUS_GOOD;
5172
5173 case OPT_ENDORSER_FONT:
5174 switch (s->u_endorser_font) {
5175 case FONT_H:
5176 strcpy (val, STRING_HORIZONTAL);
5177 break;
5178 case FONT_HB:
5179 strcpy (val, STRING_HORIZONTALBOLD);
5180 break;
5181 case FONT_HN:
5182 strcpy (val, STRING_HORIZONTALNARROW);
5183 break;
5184 case FONT_V:
5185 strcpy (val, STRING_VERTICAL);
5186 break;
5187 case FONT_VB:
5188 strcpy (val, STRING_VERTICALBOLD);
5189 break;
5190 }
5191 return SANE_STATUS_GOOD;
5192
5193 case OPT_ENDORSER_DIR:
5194 switch (s->u_endorser_dir) {
5195 case DIR_TTB:
5196 strcpy (val, STRING_TOPTOBOTTOM);
5197 break;
5198 case DIR_BTT:
5199 strcpy (val, STRING_BOTTOMTOTOP);
5200 break;
5201 }
5202 return SANE_STATUS_GOOD;
5203
5204 case OPT_ENDORSER_SIDE:
5205 switch (s->u_endorser_side) {
5206 case ED_front:
5207 strcpy (val, STRING_FRONT);
5208 break;
5209 case ED_back:
5210 strcpy (val, STRING_BACK);
5211 break;
5212 }
5213 return SANE_STATUS_GOOD;
5214
5215 case OPT_ENDORSER_STRING:
5216 strncpy(
5217 (SANE_String)val,
5218 (SANE_String)s->u_endorser_string,
5219 s->endorser_string_len+1
5220 );
5221 return SANE_STATUS_GOOD;
5222
5223 /* Sensor Group */
5224 case OPT_TOP:
5225 ret = get_hardware_status(s,option);
5226 *val_p = s->hw_top;
5227 return ret;
5228
5229 case OPT_A3:
5230 ret = get_hardware_status(s,option);
5231 *val_p = s->hw_A3;
5232 return ret;
5233
5234 case OPT_B4:
5235 ret = get_hardware_status(s,option);
5236 *val_p = s->hw_B4;
5237 return ret;
5238
5239 case OPT_A4:
5240 ret = get_hardware_status(s,option);
5241 *val_p = s->hw_A4;
5242 return ret;
5243
5244 case OPT_B5:
5245 ret = get_hardware_status(s,option);
5246 *val_p = s->hw_B5;
5247 return ret;
5248
5249 case OPT_HOPPER:
5250 ret = get_hardware_status(s,option);
5251 *val_p = s->hw_hopper;
5252 return ret;
5253
5254 case OPT_OMR:
5255 ret = get_hardware_status(s,option);
5256 *val_p = s->hw_omr;
5257 return ret;
5258
5259 case OPT_ADF_OPEN:
5260 ret = get_hardware_status(s,option);
5261 *val_p = s->hw_adf_open;
5262 return ret;
5263
5264 case OPT_CARD_LOADED:
5265 ret = get_hardware_status(s,option);
5266 *val_p = s->hw_card_loaded;
5267 return ret;
5268
5269 case OPT_SLEEP:
5270 ret = get_hardware_status(s,option);
5271 *val_p = s->hw_sleep;
5272 return ret;
5273
5274 case OPT_SEND_SW:
5275 ret = get_hardware_status(s,option);
5276 *val_p = s->hw_send_sw;
5277 return ret;
5278
5279 case OPT_MANUAL_FEED:
5280 ret = get_hardware_status(s,option);
5281 *val_p = s->hw_manual_feed;
5282 return ret;
5283
5284 case OPT_SCAN_SW:
5285 ret = get_hardware_status(s,option);
5286 *val_p = s->hw_scan_sw;
5287 return ret;
5288
5289 case OPT_FUNCTION:
5290 ret = get_hardware_status(s,option);
5291 *val_p = s->hw_function;
5292 return ret;
5293
5294 case OPT_INK_EMPTY:
5295 ret = get_hardware_status(s,option);
5296 *val_p = s->hw_ink_empty;
5297 return ret;
5298
5299 case OPT_DOUBLE_FEED:
5300 ret = get_hardware_status(s,option);
5301 *val_p = s->hw_double_feed;
5302 return ret;
5303
5304 case OPT_ERROR_CODE:
5305 ret = get_hardware_status(s,option);
5306 *val_p = s->hw_error_code;
5307 return ret;
5308
5309 case OPT_SKEW_ANGLE:
5310 ret = get_hardware_status(s,option);
5311 *val_p = s->hw_skew_angle;
5312 return ret;
5313
5314 case OPT_INK_REMAIN:
5315 ret = get_hardware_status(s,option);
5316 *val_p = s->hw_ink_remain;
5317 return ret;
5318
5319 case OPT_DENSITY_SW:
5320 ret = get_hardware_status(s,option);
5321 *val_p = s->hw_density_sw;
5322 return ret;
5323
5324 case OPT_DUPLEX_SW:
5325 ret = get_hardware_status(s,option);
5326 *val_p = s->hw_duplex_sw;
5327 return ret;
5328
5329 }
5330 }
5331 else if (action == SANE_ACTION_SET_VALUE) {
5332 int tmp;
5333 SANE_Word val_c;
5334 SANE_Status status;
5335
5336 DBG (20, "sane_control_option: set value for '%s' (%d)\n", s->opt[option].name,option);
5337
5338 if ( s->started ) {
5339 DBG (5, "sane_control_option: can't set, device busy\n");
5340 return SANE_STATUS_DEVICE_BUSY;
5341 }
5342
5343 if (!SANE_OPTION_IS_SETTABLE (s->opt[option].cap)) {
5344 DBG (5, "sane_control_option: not settable\n");
5345 return SANE_STATUS_INVAL;
5346 }
5347
5348 status = sanei_constrain_value (s->opt + option, val, info);
5349 if (status != SANE_STATUS_GOOD) {
5350 DBG (5, "sane_control_option: bad value\n");
5351 return status;
5352 }
5353
5354 /* may have been changed by constrain, so don't copy until now */
5355 val_c = *(SANE_Word *)val;
5356
5357 /*
5358 * Note - for those options which can assume one of a list of
5359 * valid values, we can safely assume that they will have
5360 * exactly one of those values because that's what
5361 * sanei_constrain_value does. Hence no "else: invalid" branches
5362 * below.
5363 */
5364 switch (option) {
5365
5366 /* Mode Group */
5367 case OPT_SOURCE:
5368 if (!strcmp (val, STRING_ADFFRONT)) {
5369 tmp = SOURCE_ADF_FRONT;
5370 }
5371 else if (!strcmp (val, STRING_ADFBACK)) {
5372 tmp = SOURCE_ADF_BACK;
5373 }
5374 else if (!strcmp (val, STRING_ADFDUPLEX)) {
5375 tmp = SOURCE_ADF_DUPLEX;
5376 }
5377 else if (!strcmp (val, STRING_CARDFRONT)) {
5378 tmp = SOURCE_CARD_FRONT;
5379 }
5380 else if (!strcmp (val, STRING_CARDBACK)) {
5381 tmp = SOURCE_CARD_BACK;
5382 }
5383 else if (!strcmp (val, STRING_CARDDUPLEX)) {
5384 tmp = SOURCE_CARD_DUPLEX;
5385 }
5386 else{
5387 tmp = SOURCE_FLATBED;
5388 }
5389
5390 if (s->source == tmp)
5391 return SANE_STATUS_GOOD;
5392
5393 s->source = tmp;
5394 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
5395 return SANE_STATUS_GOOD;
5396
5397 case OPT_MODE:
5398 if (!strcmp (val, STRING_LINEART)) {
5399 tmp = MODE_LINEART;
5400 }
5401 else if (!strcmp (val, STRING_HALFTONE)) {
5402 tmp = MODE_HALFTONE;
5403 }
5404 else if (!strcmp (val, STRING_GRAYSCALE)) {
5405 tmp = MODE_GRAYSCALE;
5406 }
5407 else{
5408 tmp = MODE_COLOR;
5409 }
5410
5411 if (tmp == s->u_mode)
5412 return SANE_STATUS_GOOD;
5413
5414 set_mode(s,tmp);
5415
5416 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
5417 return SANE_STATUS_GOOD;
5418
5419 case OPT_RES:
5420
5421 if (s->resolution_x == val_c)
5422 return SANE_STATUS_GOOD;
5423
5424 s->resolution_x = val_c;
5425 s->resolution_y = val_c;
5426 set_max_y(s);
5427
5428 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
5429 return SANE_STATUS_GOOD;
5430
5431 /* Geometry Group */
5432 case OPT_TL_X:
5433 if (s->tl_x == FIXED_MM_TO_SCANNER_UNIT(val_c))
5434 return SANE_STATUS_GOOD;
5435
5436 s->tl_x = FIXED_MM_TO_SCANNER_UNIT(val_c);
5437
5438 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
5439 return SANE_STATUS_GOOD;
5440
5441 case OPT_TL_Y:
5442 if (s->tl_y == FIXED_MM_TO_SCANNER_UNIT(val_c))
5443 return SANE_STATUS_GOOD;
5444
5445 s->tl_y = FIXED_MM_TO_SCANNER_UNIT(val_c);
5446
5447 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
5448 return SANE_STATUS_GOOD;
5449
5450 case OPT_BR_X:
5451 if (s->br_x == FIXED_MM_TO_SCANNER_UNIT(val_c))
5452 return SANE_STATUS_GOOD;
5453
5454 s->br_x = FIXED_MM_TO_SCANNER_UNIT(val_c);
5455
5456 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
5457 return SANE_STATUS_GOOD;
5458
5459 case OPT_BR_Y:
5460 if (s->br_y == FIXED_MM_TO_SCANNER_UNIT(val_c))
5461 return SANE_STATUS_GOOD;
5462
5463 s->br_y = FIXED_MM_TO_SCANNER_UNIT(val_c);
5464
5465 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
5466 return SANE_STATUS_GOOD;
5467
5468 case OPT_PAGE_WIDTH:
5469 if (s->page_width == FIXED_MM_TO_SCANNER_UNIT(val_c))
5470 return SANE_STATUS_GOOD;
5471
5472 /* if full width image, and paper size is changed,
5473 change the image size to match new paper */
5474 if (s->tl_x == 0 && s->br_x == s->page_width){
5475 DBG (20, "sane_control_option: br_x tracking page_width\n");
5476 s->br_x = FIXED_MM_TO_SCANNER_UNIT(val_c);
5477 *info |= SANE_INFO_RELOAD_PARAMS;
5478 }
5479
5480 s->page_width = FIXED_MM_TO_SCANNER_UNIT(val_c);
5481 *info |= SANE_INFO_RELOAD_OPTIONS;
5482 return SANE_STATUS_GOOD;
5483
5484 case OPT_PAGE_HEIGHT:
5485 if (s->page_height == FIXED_MM_TO_SCANNER_UNIT(val_c))
5486 return SANE_STATUS_GOOD;
5487
5488 /* if full height image, and paper size is changed,
5489 change the image size to match new paper */
5490 if (s->tl_y == 0 && s->br_y == s->page_height){
5491 DBG (20, "sane_control_option: br_y tracking page_height\n");
5492 s->br_y = FIXED_MM_TO_SCANNER_UNIT(val_c);
5493 *info |= SANE_INFO_RELOAD_PARAMS;
5494 }
5495
5496 s->page_height = FIXED_MM_TO_SCANNER_UNIT(val_c);
5497 *info |= SANE_INFO_RELOAD_OPTIONS;
5498 return SANE_STATUS_GOOD;
5499
5500 /* Enhancement Group */
5501 case OPT_BRIGHTNESS:
5502 s->brightness = val_c;
5503 return SANE_STATUS_GOOD;
5504
5505 case OPT_CONTRAST:
5506 s->contrast = val_c;
5507 return SANE_STATUS_GOOD;
5508
5509 case OPT_GAMMA:
5510 s->gamma = SANE_UNFIX(val_c);
5511 return SANE_STATUS_GOOD;
5512
5513 case OPT_THRESHOLD:
5514 s->threshold = val_c;
5515 return SANE_STATUS_GOOD;
5516
5517 /* IPC */
5518 case OPT_RIF:
5519 s->rif = val_c;
5520 return SANE_STATUS_GOOD;
5521
5522 case OPT_HT_TYPE:
5523 if (!strcmp(val, STRING_DEFAULT))
5524 s->ht_type = WD_ht_type_DEFAULT;
5525 else if (!strcmp(val, STRING_DITHER))
5526 s->ht_type = WD_ht_type_DITHER;
5527 else if (!strcmp(val, STRING_DIFFUSION))
5528 s->ht_type = WD_ht_type_DIFFUSION;
5529 return SANE_STATUS_GOOD;
5530
5531 case OPT_HT_PATTERN:
5532 s->ht_pattern = val_c;
5533 return SANE_STATUS_GOOD;
5534
5535 case OPT_OUTLINE:
5536 s->outline = val_c;
5537 return SANE_STATUS_GOOD;
5538
5539 case OPT_EMPHASIS:
5540 s->emphasis = val_c;
5541 return SANE_STATUS_GOOD;
5542
5543 case OPT_SEPARATION:
5544 s->separation = val_c;
5545 return SANE_STATUS_GOOD;
5546
5547 case OPT_MIRRORING:
5548 s->mirroring = val_c;
5549 return SANE_STATUS_GOOD;
5550
5551 case OPT_WL_FOLLOW:
5552 if (!strcmp(val, STRING_DEFAULT))
5553 s->wl_follow = WD_wl_follow_DEFAULT;
5554 else if (!strcmp(val, STRING_ON))
5555 s->wl_follow = WD_wl_follow_ON;
5556 else if (!strcmp(val, STRING_OFF))
5557 s->wl_follow = WD_wl_follow_OFF;
5558 return SANE_STATUS_GOOD;
5559
5560 /* DTC params*/
5561 case OPT_BP_FILTER:
5562 s->bp_filter = val_c;
5563 *info |= SANE_INFO_RELOAD_OPTIONS;
5564 return SANE_STATUS_GOOD;
5565
5566 case OPT_SMOOTHING:
5567 s->smoothing = val_c;
5568 *info |= SANE_INFO_RELOAD_OPTIONS;
5569 return SANE_STATUS_GOOD;
5570
5571 case OPT_GAMMA_CURVE:
5572 s->gamma_curve = val_c;
5573 *info |= SANE_INFO_RELOAD_OPTIONS;
5574 return SANE_STATUS_GOOD;
5575
5576 case OPT_THRESHOLD_CURVE:
5577 s->threshold_curve = val_c;
5578 *info |= SANE_INFO_RELOAD_OPTIONS;
5579 return SANE_STATUS_GOOD;
5580
5581 case OPT_THRESHOLD_WHITE:
5582 s->threshold_white = val_c;
5583 *info |= SANE_INFO_RELOAD_OPTIONS;
5584 return SANE_STATUS_GOOD;
5585
5586 case OPT_NOISE_REMOVAL:
5587 s->noise_removal = val_c;
5588 *info |= SANE_INFO_RELOAD_OPTIONS;
5589 return SANE_STATUS_GOOD;
5590
5591 case OPT_MATRIX_5:
5592 s->matrix_5 = val_c;
5593 return SANE_STATUS_GOOD;
5594
5595 case OPT_MATRIX_4:
5596 s->matrix_4 = val_c;
5597 return SANE_STATUS_GOOD;
5598
5599 case OPT_MATRIX_3:
5600 s->matrix_3 = val_c;
5601 return SANE_STATUS_GOOD;
5602
5603 case OPT_MATRIX_2:
5604 s->matrix_2 = val_c;
5605 return SANE_STATUS_GOOD;
5606
5607 /* SDTC params*/
5608 case OPT_VARIANCE:
5609 s->variance = val_c;
5610 *info |= SANE_INFO_RELOAD_OPTIONS;
5611 return SANE_STATUS_GOOD;
5612
5613 /* Advanced Group */
5614 case OPT_AWD:
5615 s->awd = val_c;
5616 *info |= SANE_INFO_RELOAD_OPTIONS;
5617 return SANE_STATUS_GOOD;
5618
5619 case OPT_ALD:
5620 s->ald = val_c;
5621 *info |= SANE_INFO_RELOAD_OPTIONS;
5622 return SANE_STATUS_GOOD;
5623
5624 case OPT_COMPRESS:
5625 if (!strcmp (val, STRING_JPEG)) {
5626 tmp = COMP_JPEG;
5627 }
5628 else{
5629 tmp = COMP_NONE;
5630 }
5631
5632 if (tmp == s->compress)
5633 return SANE_STATUS_GOOD;
5634
5635 s->compress = tmp;
5636 return SANE_STATUS_GOOD;
5637
5638 case OPT_COMPRESS_ARG:
5639 s->compress_arg = val_c;
5640 return SANE_STATUS_GOOD;
5641
5642 case OPT_DF_ACTION:
5643 if (!strcmp(val, STRING_DEFAULT))
5644 s->df_action = DF_DEFAULT;
5645 else if (!strcmp(val, STRING_CONTINUE))
5646 s->df_action = DF_CONTINUE;
5647 else if (!strcmp(val, STRING_STOP))
5648 s->df_action = DF_STOP;
5649 *info |= SANE_INFO_RELOAD_OPTIONS;
5650 return SANE_STATUS_GOOD;
5651
5652 case OPT_DF_SKEW:
5653 s->df_skew = val_c;
5654 return SANE_STATUS_GOOD;
5655
5656 case OPT_DF_THICKNESS:
5657 s->df_thickness = val_c;
5658 return SANE_STATUS_GOOD;
5659
5660 case OPT_DF_LENGTH:
5661 s->df_length = val_c;
5662 return SANE_STATUS_GOOD;
5663
5664 case OPT_DF_DIFF:
5665 if (!strcmp(val, STRING_DEFAULT))
5666 s->df_diff = MSEL_df_diff_DEFAULT;
5667 else if (!strcmp(val, STRING_10MM))
5668 s->df_diff = MSEL_df_diff_10MM;
5669 else if (!strcmp(val, STRING_15MM))
5670 s->df_diff = MSEL_df_diff_15MM;
5671 else if (!strcmp(val, STRING_20MM))
5672 s->df_diff = MSEL_df_diff_20MM;
5673 return SANE_STATUS_GOOD;
5674
5675 case OPT_DF_RECOVERY:
5676 if (!strcmp(val, STRING_DEFAULT))
5677 s->df_recovery = MSEL_DEFAULT;
5678 else if (!strcmp(val, STRING_ON))
5679 s->df_recovery = MSEL_ON;
5680 else if (!strcmp(val, STRING_OFF))
5681 s->df_recovery = MSEL_OFF;
5682 return SANE_STATUS_GOOD;
5683
5684 case OPT_PAPER_PROTECT:
5685 if (!strcmp(val, STRING_DEFAULT))
5686 s->paper_protect = MSEL_DEFAULT;
5687 else if (!strcmp(val, STRING_ON))
5688 s->paper_protect = MSEL_ON;
5689 else if (!strcmp(val, STRING_OFF))
5690 s->paper_protect = MSEL_OFF;
5691 return SANE_STATUS_GOOD;
5692
5693 case OPT_ADV_PAPER_PROT:
5694 if (!strcmp(val, STRING_DEFAULT))
5695 s->adv_paper_prot = MSEL_DEFAULT;
5696 else if (!strcmp(val, STRING_ON))
5697 s->adv_paper_prot = MSEL_ON;
5698 else if (!strcmp(val, STRING_OFF))
5699 s->adv_paper_prot = MSEL_OFF;
5700 return SANE_STATUS_GOOD;
5701
5702 case OPT_STAPLE_DETECT:
5703 if (!strcmp(val, STRING_DEFAULT))
5704 s->staple_detect = MSEL_DEFAULT;
5705 else if (!strcmp(val, STRING_ON))
5706 s->staple_detect = MSEL_ON;
5707 else if (!strcmp(val, STRING_OFF))
5708 s->staple_detect = MSEL_OFF;
5709 return SANE_STATUS_GOOD;
5710
5711 case OPT_BG_COLOR:
5712 if (!strcmp(val, STRING_DEFAULT))
5713 s->bg_color = COLOR_DEFAULT;
5714 else if (!strcmp(val, STRING_WHITE))
5715 s->bg_color = COLOR_WHITE;
5716 else if (!strcmp(val, STRING_BLACK))
5717 s->bg_color = COLOR_BLACK;
5718 return SANE_STATUS_GOOD;
5719
5720 case OPT_DROPOUT_COLOR:
5721 if (!strcmp(val, STRING_DEFAULT))
5722 s->dropout_color = COLOR_DEFAULT;
5723 else if (!strcmp(val, STRING_RED))
5724 s->dropout_color = COLOR_RED;
5725 else if (!strcmp(val, STRING_GREEN))
5726 s->dropout_color = COLOR_GREEN;
5727 else if (!strcmp(val, STRING_BLUE))
5728 s->dropout_color = COLOR_BLUE;
5729 return SANE_STATUS_GOOD;
5730
5731 case OPT_BUFF_MODE:
5732 if (!strcmp(val, STRING_DEFAULT))
5733 s->buff_mode = MSEL_DEFAULT;
5734 else if (!strcmp(val, STRING_ON))
5735 s->buff_mode= MSEL_ON;
5736 else if (!strcmp(val, STRING_OFF))
5737 s->buff_mode= MSEL_OFF;
5738 return SANE_STATUS_GOOD;
5739
5740 case OPT_PREPICK:
5741 if (!strcmp(val, STRING_DEFAULT))
5742 s->prepick = MSEL_DEFAULT;
5743 else if (!strcmp(val, STRING_ON))
5744 s->prepick = MSEL_ON;
5745 else if (!strcmp(val, STRING_OFF))
5746 s->prepick = MSEL_OFF;
5747 return SANE_STATUS_GOOD;
5748
5749 case OPT_OVERSCAN:
5750 if (!strcmp(val, STRING_DEFAULT))
5751 s->overscan = MSEL_DEFAULT;
5752 else if (!strcmp(val, STRING_ON))
5753 s->overscan = MSEL_ON;
5754 else if (!strcmp(val, STRING_OFF))
5755 s->overscan = MSEL_OFF;
5756
5757 *info |= SANE_INFO_RELOAD_OPTIONS;
5758 return SANE_STATUS_GOOD;
5759
5760 case OPT_SLEEP_TIME:
5761 s->sleep_time = val_c;
5762 return set_sleep_mode(s);
5763
5764 case OPT_OFF_TIME:
5765 /* do our own constrain, because we want to round up */
5766 s->off_time = (val_c + 14)/15*15;
5767 if(s->off_time != val_c){
5768 *info |= SANE_INFO_INEXACT;
5769 }
5770 return set_off_mode(s);
5771
5772 case OPT_DUPLEX_OFFSET:
5773 s->duplex_offset = val_c;
5774 return SANE_STATUS_GOOD;
5775
5776 case OPT_GREEN_OFFSET:
5777 s->green_offset = val_c;
5778 return SANE_STATUS_GOOD;
5779
5780 case OPT_BLUE_OFFSET:
5781 s->blue_offset = val_c;
5782 return SANE_STATUS_GOOD;
5783
5784 case OPT_LOW_MEM:
5785 s->low_mem = val_c;
5786 return SANE_STATUS_GOOD;
5787
5788 case OPT_HWDESKEWCROP:
5789 s->hwdeskewcrop = val_c;
5790 return SANE_STATUS_GOOD;
5791
5792 case OPT_SWDESKEW:
5793 s->swdeskew = val_c;
5794 return SANE_STATUS_GOOD;
5795
5796 case OPT_SWDESPECK:
5797 s->swdespeck = val_c;
5798 return SANE_STATUS_GOOD;
5799
5800 case OPT_SWCROP:
5801 s->swcrop = val_c;
5802 return SANE_STATUS_GOOD;
5803
5804 case OPT_SWSKIP:
5805 s->swskip = SANE_UNFIX(val_c);
5806 return SANE_STATUS_GOOD;
5807
5808 case OPT_HALT_ON_CANCEL:
5809 s->halt_on_cancel = val_c;
5810 return SANE_STATUS_GOOD;
5811
5812 /* Endorser Group */
5813 case OPT_ENDORSER:
5814 s->u_endorser = val_c;
5815 *info |= SANE_INFO_RELOAD_OPTIONS;
5816 return SANE_STATUS_GOOD;
5817
5818 case OPT_ENDORSER_BITS:
5819 s->u_endorser_bits = val_c;
5820 return SANE_STATUS_GOOD;
5821
5822 /*this val not used in send_endorser*/
5823 case OPT_ENDORSER_VAL:
5824 s->u_endorser_val = val_c;
5825 return SANE_STATUS_GOOD;
5826
5827 case OPT_ENDORSER_STEP:
5828 s->u_endorser_step = val_c;
5829 return SANE_STATUS_GOOD;
5830
5831 case OPT_ENDORSER_Y:
5832 s->u_endorser_y = FIXED_MM_TO_SCANNER_UNIT(val_c);
5833 return SANE_STATUS_GOOD;
5834
5835 case OPT_ENDORSER_FONT:
5836
5837 if (!strcmp (val, STRING_HORIZONTAL)){
5838 s->u_endorser_font = FONT_H;
5839 }
5840 else if (!strcmp (val, STRING_HORIZONTALBOLD)){
5841 s->u_endorser_font = FONT_HB;
5842 }
5843 else if (!strcmp (val, STRING_HORIZONTALNARROW)){
5844 s->u_endorser_font = FONT_HN;
5845 }
5846 else if (!strcmp (val, STRING_VERTICAL)){
5847 s->u_endorser_font = FONT_V;
5848 }
5849 else if (!strcmp (val, STRING_VERTICALBOLD)){
5850 s->u_endorser_font = FONT_VB;
5851 }
5852 return SANE_STATUS_GOOD;
5853
5854 case OPT_ENDORSER_DIR:
5855 if (!strcmp (val, STRING_TOPTOBOTTOM)){
5856 s->u_endorser_dir = DIR_TTB;
5857 }
5858 else if (!strcmp (val, STRING_BOTTOMTOTOP)){
5859 s->u_endorser_dir = DIR_BTT;
5860 }
5861 return SANE_STATUS_GOOD;
5862
5863 /*this val not used in send_endorser*/
5864 case OPT_ENDORSER_SIDE:
5865 if (!strcmp (val, STRING_FRONT)){
5866 s->u_endorser_side = ED_front;
5867 }
5868 else if (!strcmp (val, STRING_BACK)){
5869 s->u_endorser_side = ED_back;
5870 }
5871 return SANE_STATUS_GOOD;
5872
5873 case OPT_ENDORSER_STRING:
5874 strncpy(
5875 (SANE_String)s->u_endorser_string,
5876 (SANE_String)val,
5877 s->endorser_string_len+1
5878 );
5879 return SANE_STATUS_GOOD;
5880 } /* switch */
5881 } /* else */
5882
5883 return SANE_STATUS_INVAL;
5884 }
5885
5886 static SANE_Status
set_sleep_mode(struct fujitsu *s)5887 set_sleep_mode(struct fujitsu *s)
5888 {
5889 SANE_Status ret = SANE_STATUS_GOOD;
5890
5891 unsigned char cmd[MODE_SELECT_len];
5892 size_t cmdLen = MODE_SELECT_len;
5893
5894 unsigned char out[MSEL_header_len + MSEL_data_min_len];
5895 size_t outLen = MSEL_header_len + MSEL_data_min_len;
5896 unsigned char * page = out+MSEL_header_len;
5897
5898 DBG (10, "set_sleep_mode: start\n");
5899
5900 memset(cmd,0,cmdLen);
5901 set_SCSI_opcode(cmd, MODE_SELECT_code);
5902 set_MSEL_pf(cmd, 1);
5903 set_MSEL_xferlen(cmd, outLen);
5904
5905 memset(out,0,outLen);
5906 set_MSEL_pc(page, MS_pc_sleep);
5907 set_MSEL_page_len(page, MSEL_data_min_len-2);
5908 set_MSEL_sleep_mode(page, s->sleep_time);
5909
5910 ret = do_cmd (
5911 s, 1, 0,
5912 cmd, cmdLen,
5913 out, outLen,
5914 NULL, NULL
5915 );
5916
5917 DBG (10, "set_sleep_mode: finish\n");
5918
5919 return ret;
5920 }
5921
5922 static SANE_Status
set_off_mode(struct fujitsu *s)5923 set_off_mode(struct fujitsu *s)
5924 {
5925 SANE_Status ret = SANE_STATUS_GOOD;
5926
5927 unsigned char cmd[SEND_DIAGNOSTIC_len]; /*also big enough for READ_DIAG*/
5928 size_t cmdLen = SEND_DIAGNOSTIC_len;
5929
5930 unsigned char out[SD_powoff_len];
5931 size_t outLen = SD_powoff_len;
5932
5933 DBG (10, "set_off_mode: start\n");
5934
5935 if (!s->has_cmd_sdiag || !s->has_cmd_rdiag || !s->has_off_mode){
5936 DBG (5, "set_off_mode: not supported, returning\n");
5937 return ret;
5938 }
5939
5940 memset(cmd,0,cmdLen);
5941 set_SCSI_opcode(cmd, SEND_DIAGNOSTIC_code);
5942 set_SD_slftst(cmd, 0);
5943 set_SD_xferlen(cmd, outLen);
5944
5945 memcpy(out,SD_powoff_string,SD_powoff_stringlen);
5946 set_SD_powoff_disable(out,!s->off_time);
5947 set_SD_powoff_interval(out,s->off_time/15);
5948
5949 ret = do_cmd (
5950 s, 1, 0,
5951 cmd, cmdLen,
5952 out, outLen,
5953 NULL, NULL
5954 );
5955
5956 if (ret != SANE_STATUS_GOOD){
5957 DBG (5, "set_off_mode: send diag error: %d\n", ret);
5958 return ret;
5959 }
5960
5961 DBG (10, "set_off_mode: finish\n");
5962
5963 return SANE_STATUS_GOOD;
5964 }
5965
5966 static SANE_Status
get_hardware_status(struct fujitsu *s, SANE_Int option)5967 get_hardware_status (struct fujitsu *s, SANE_Int option)
5968 {
5969 SANE_Status ret = SANE_STATUS_GOOD;
5970
5971 DBG (10, "get_hardware_status: start\n");
5972
5973 /* only run this if frontend has already read the last time we got it */
5974 /* or if we don't care for such bookkeeping (private use) */
5975 if (!option || !s->hw_data_avail[option-OPT_TOP]) {
5976
5977 DBG (15, "get_hardware_status: running\n");
5978
5979 /* mark all values as available */
5980 memset(s->hw_data_avail,1,sizeof(s->hw_data_avail));
5981
5982 if (s->has_cmd_hw_status){
5983 unsigned char cmd[GET_HW_STATUS_len];
5984 size_t cmdLen = GET_HW_STATUS_len;
5985
5986 unsigned char in[GHS_data_len];
5987 size_t inLen = GHS_data_len;
5988
5989 memset(cmd,0,cmdLen);
5990 set_SCSI_opcode(cmd, GET_HW_STATUS_code);
5991 set_GHS_allocation_length(cmd, inLen);
5992
5993 DBG (15, "get_hardware_status: calling ghs\n");
5994
5995 ret = do_cmd (
5996 s, 1, 0,
5997 cmd, cmdLen,
5998 NULL, 0,
5999 in, &inLen
6000 );
6001
6002 if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) {
6003
6004 s->hw_top = get_GHS_top(in);
6005 s->hw_A3 = get_GHS_A3(in);
6006 s->hw_B4 = get_GHS_B4(in);
6007 s->hw_A4 = get_GHS_A4(in);
6008 s->hw_B5 = get_GHS_B5(in);
6009
6010 s->hw_hopper = get_GHS_hopper(in);
6011 s->hw_omr = get_GHS_omr(in);
6012 s->hw_adf_open = get_GHS_adf_open(in);
6013 s->hw_card_loaded = get_GHS_exit(in);
6014
6015 s->hw_sleep = get_GHS_sleep(in);
6016 s->hw_send_sw = get_GHS_send_sw(in);
6017 s->hw_manual_feed = get_GHS_manual_feed(in);
6018 s->hw_scan_sw = get_GHS_scan_sw(in);
6019
6020 s->hw_function = get_GHS_function(in);
6021 s->hw_ink_empty = get_GHS_ink_empty(in);
6022
6023 s->hw_double_feed = get_GHS_double_feed(in);
6024
6025 s->hw_error_code = get_GHS_error_code(in);
6026
6027 s->hw_skew_angle = get_GHS_skew_angle(in);
6028
6029 if(inLen > 9){
6030 s->hw_ink_remain = get_GHS_ink_remain(in);
6031 }
6032
6033 ret = SANE_STATUS_GOOD;
6034 }
6035 }
6036
6037 /* 3091/2 put hardware status in RS data */
6038 else if (s->ghs_in_rs){
6039 unsigned char cmd[REQUEST_SENSE_len];
6040 size_t cmdLen = REQUEST_SENSE_len;
6041
6042 unsigned char in[RS_return_size];
6043 size_t inLen = RS_return_size;
6044
6045 memset(cmd,0,cmdLen);
6046 set_SCSI_opcode(cmd, REQUEST_SENSE_code);
6047 set_RS_return_size(cmd, inLen);
6048
6049 DBG(15,"get_hardware_status: calling rs\n");
6050
6051 ret = do_cmd(
6052 s,0,0,
6053 cmd, cmdLen,
6054 NULL,0,
6055 in, &inLen
6056 );
6057
6058 /* parse the rs data */
6059 if(ret == SANE_STATUS_GOOD){
6060 if(get_RS_sense_key(in)==0 && get_RS_ASC(in)==0x80){
6061
6062 s->hw_adf_open = get_RS_adf_open(in);
6063 s->hw_send_sw = get_RS_send_sw(in);
6064 s->hw_scan_sw = get_RS_scan_sw(in);
6065 s->hw_duplex_sw = get_RS_duplex_sw(in);
6066 s->hw_top = get_RS_top(in);
6067 s->hw_hopper = get_RS_hopper(in);
6068 s->hw_function = get_RS_function(in);
6069 s->hw_density_sw = get_RS_density(in);
6070 }
6071 else{
6072 DBG (10, "get_hardware_status: unexpected RS values\n");
6073 }
6074 }
6075 }
6076 }
6077
6078 if(option)
6079 s->hw_data_avail[option-OPT_TOP] = 0;
6080
6081 DBG (10, "get_hardware_status: finish\n");
6082
6083 return ret;
6084 }
6085
6086 static SANE_Status
send_endorser(struct fujitsu *s)6087 send_endorser(struct fujitsu *s)
6088 {
6089 SANE_Status ret = SANE_STATUS_GOOD;
6090
6091 unsigned char cmd[SEND_len];
6092 size_t cmdLen = SEND_len;
6093
6094 size_t strLen = strlen(s->u_endorser_string);
6095
6096 unsigned char out[S_e_data_max_len]; /*we probably send less below*/
6097 size_t outLen = S_e_data_min_len + strLen; /*fi-5900 might want 1 more byte?*/
6098
6099 DBG (10, "send_endorser: start\n");
6100
6101 if (!s->has_endorser_f && !s->has_endorser_b){
6102 DBG (10, "send_endorser: unsupported\n");
6103 return ret;
6104 }
6105
6106 /*build the payload*/
6107 memset(out,0,outLen);
6108
6109 /*fi-5900 front side uses 0x80, assume all others*/
6110 if(s->u_endorser_side == ED_front){
6111 set_S_endorser_data_id(out,0x80);
6112 }
6113 else{
6114 set_S_endorser_data_id(out,0);
6115 }
6116
6117 set_S_endorser_stamp(out,0);
6118 set_S_endorser_elec(out,0);
6119
6120 if(s->u_endorser_step < 0){
6121 set_S_endorser_decr(out,S_e_decr_dec);
6122 }
6123 else{
6124 set_S_endorser_decr(out,S_e_decr_inc);
6125 }
6126
6127 if(s->u_endorser_bits == 24){
6128 set_S_endorser_lap24(out,S_e_lap_24bit);
6129 }
6130 else{
6131 set_S_endorser_lap24(out,S_e_lap_16bit);
6132 }
6133
6134 set_S_endorser_ctstep(out,abs(s->u_endorser_step));
6135 set_S_endorser_ulx(out,0);
6136 set_S_endorser_uly(out,s->u_endorser_y);
6137
6138 switch (s->u_endorser_font) {
6139 case FONT_H:
6140 set_S_endorser_font(out,S_e_font_horiz);
6141 set_S_endorser_bold(out,0);
6142 break;
6143 case FONT_HB:
6144 set_S_endorser_font(out,S_e_font_horiz);
6145 set_S_endorser_bold(out,1);
6146 break;
6147 case FONT_HN:
6148 set_S_endorser_font(out,S_e_font_horiz_narrow);
6149 set_S_endorser_bold(out,0);
6150 break;
6151 case FONT_V:
6152 set_S_endorser_font(out,S_e_font_vert);
6153 set_S_endorser_bold(out,0);
6154 break;
6155 case FONT_VB:
6156 set_S_endorser_font(out,S_e_font_vert);
6157 set_S_endorser_bold(out,1);
6158 break;
6159 }
6160
6161 set_S_endorser_size(out,0);
6162 set_S_endorser_revs(out,0);
6163
6164 if(s->u_endorser_dir == DIR_BTT){
6165 set_S_endorser_dirs(out,S_e_dir_bottom_top);
6166 }
6167 else{
6168 set_S_endorser_dirs(out,S_e_dir_top_bottom);
6169 }
6170
6171 set_S_endorser_string_length(out, strLen);
6172 set_S_endorser_string(out, s->u_endorser_string, strLen);
6173
6174 /*build the command*/
6175 memset(cmd,0,cmdLen);
6176 set_SCSI_opcode(cmd, SEND_code);
6177 set_S_xfer_datatype (cmd, S_datatype_endorser_data);
6178 set_S_xfer_length (cmd, outLen);
6179
6180 ret = do_cmd (
6181 s, 1, 0,
6182 cmd, cmdLen,
6183 out, outLen,
6184 NULL, NULL
6185 );
6186
6187 DBG (10, "send_endorser: finish %d\n", ret);
6188
6189 return ret;
6190 }
6191
6192 /* instead of internal brightness/contrast/gamma
6193 most scanners use a 256x256 or 1024x256 LUT
6194 default is linear table of slope 1 or 1/4 resp.
6195 brightness and contrast inputs are -127 to +127
6196
6197 contrast rotates slope of line around central input val
6198
6199 high low
6200 . x .
6201 . x . xx
6202 out . x . xxxxxxxx
6203 . x xx
6204 ....x....... ............
6205 in in
6206
6207 then brightness moves line vertically, and clamps to 8bit
6208
6209 bright dark
6210 . xxxxxxxx .
6211 . x .
6212 out x . x
6213 . . x
6214 ............ xxxxxxxx....
6215 in in
6216 */
6217 static SANE_Status
send_lut(struct fujitsu *s)6218 send_lut (struct fujitsu *s)
6219 {
6220 int i, j, bytes = 1 << s->adbits;
6221 double b, slope, offset;
6222
6223 SANE_Status ret = SANE_STATUS_GOOD;
6224
6225 unsigned char cmd[SEND_len];
6226 size_t cmdLen = SEND_len;
6227
6228 unsigned char out[S_lut_header_len + S_lut_data_max_len];
6229 size_t outLen = S_lut_header_len + S_lut_data_max_len;
6230 unsigned char * p = out + S_lut_header_len;
6231
6232 DBG (10, "send_lut: start\n");
6233
6234 if(!s->num_download_gamma || !s->adbits){
6235 DBG (10, "send_lut: unsupported\n");
6236 return ret;
6237 }
6238
6239 /* contrast is converted to a slope [0,90] degrees:
6240 * first [-127,127] to [0,254] then to [0,1]
6241 * then multiply by PI/2 to convert to radians
6242 * then take the tangent to get slope (T.O.A)
6243 * then multiply by the normal linear slope
6244 * because the table may not be square, i.e. 1024x256*/
6245 slope = tan(((double)s->contrast+127)/254 * M_PI/2) * 256/bytes;
6246
6247 /* contrast slope must stay centered, so figure
6248 * out vertical offset at central input value */
6249 offset = 127.5-(slope*bytes/2);
6250
6251 /* convert the user brightness setting (-127 to +127)
6252 * into a scale that covers the range required
6253 * to slide the contrast curve entirely off the table */
6254 b = ((double)s->brightness/127) * (256 - offset);
6255
6256 DBG (15, "send_lut: %d %f %d %f %f\n", s->brightness, b,
6257 s->contrast, slope, offset);
6258
6259 outLen = S_lut_header_len + bytes;
6260
6261 memset(cmd,0,cmdLen);
6262 set_SCSI_opcode(cmd, SEND_code);
6263
6264 set_S_xfer_datatype (cmd, S_datatype_lut_data);
6265 set_S_xfer_length (cmd, outLen);
6266
6267 memset(out,0,outLen);
6268 set_S_lut_order (out, S_lut_order_single);
6269 set_S_lut_ssize (out, bytes);
6270 set_S_lut_dsize (out, 256);
6271
6272 for(i=0;i<bytes;i++){
6273 j=slope*i + offset + b;
6274
6275 if(j<0){
6276 j=0;
6277 }
6278
6279 if(j>255){
6280 j=255;
6281 }
6282
6283 *p=j;
6284 p++;
6285 }
6286
6287 ret = do_cmd (
6288 s, 1, 0,
6289 cmd, cmdLen,
6290 out, outLen,
6291 NULL, NULL
6292 );
6293
6294 DBG (10, "send_lut: finish\n");
6295
6296 return ret;
6297 }
6298
6299 static SANE_Status
send_q_table(struct fujitsu *s)6300 send_q_table (struct fujitsu *s)
6301 {
6302 SANE_Status ret = SANE_STATUS_GOOD;
6303
6304 unsigned char cmd[SEND_len];
6305 size_t cmdLen = SEND_len;
6306
6307 unsigned char out[S_q_table_header_len + S_q_table_y_len + S_q_table_uv_len];
6308 size_t outLen = S_q_table_header_len + S_q_table_y_len + S_q_table_uv_len;
6309 unsigned char * yp = out + S_q_table_header_len;
6310 unsigned char * uvp = out + S_q_table_header_len + S_q_table_y_len;
6311
6312 /* FIXME: generate these instead of hardcode */
6313 unsigned char ydata[] = {
6314 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04,
6315 0x03, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0c,
6316 0x07, 0x07, 0x06, 0x06, 0x07, 0x0e, 0x0a, 0x0b,
6317 0x08, 0x0c, 0x11, 0x0f, 0x12, 0x12, 0x11, 0x0f,
6318 0x10, 0x10, 0x13, 0x15, 0x1b, 0x17, 0x13, 0x14,
6319 0x1a, 0x14, 0x10, 0x10, 0x18, 0x20, 0x18, 0x1a,
6320 0x1c, 0x1d, 0x1e, 0x1f, 0x1e, 0x12, 0x17, 0x21,
6321 0x24, 0x21, 0x1e, 0x24, 0x1b, 0x1e, 0x1e, 0x1d };
6322
6323 unsigned char uvdata[] = {
6324 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0e, 0x07,
6325 0x07, 0x0e, 0x1d, 0x13, 0x10, 0x13, 0x1d, 0x1d,
6326 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
6327 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
6328 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
6329 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
6330 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
6331 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d };
6332
6333 DBG (10, "send_q_table: start\n");
6334
6335 memset(cmd,0,cmdLen);
6336 set_SCSI_opcode(cmd, SEND_code);
6337 set_S_xfer_datatype (cmd, S_datatype_jpg_q_table);
6338 set_S_xfer_length (cmd, outLen);
6339
6340 memset(out,0,outLen);
6341 set_S_q_table_y_len (out, S_q_table_y_len);
6342 set_S_q_table_uv_len (out, S_q_table_uv_len);
6343 memcpy (yp, ydata, S_q_table_y_len);
6344 memcpy (uvp, uvdata, S_q_table_uv_len);
6345
6346 ret = do_cmd (
6347 s, 1, 0,
6348 cmd, cmdLen,
6349 out, outLen,
6350 NULL, NULL
6351 );
6352
6353 DBG (10, "send_q_table: finish\n");
6354
6355 return ret;
6356 }
6357
6358 /* only used by iX500? */
6359 #if 0
6360 static SANE_Status
6361 mode_select_unk (struct fujitsu *s, int foo)
6362 {
6363 SANE_Status ret = SANE_STATUS_GOOD;
6364
6365 unsigned char cmd[MODE_SELECT_len];
6366 size_t cmdLen = MODE_SELECT_len;
6367
6368 unsigned char out[MSEL_header_len + MSEL_data_min_len];
6369 size_t outLen = MSEL_header_len + MSEL_data_min_len;
6370 unsigned char * page = out+MSEL_header_len;
6371
6372 DBG (10, "mode_select_unk: start\n");
6373
6374 /*if (!s->has_MS_unk){
6375 DBG (10, "mode_select_unk: unsupported\n");
6376 return SANE_STATUS_GOOD;
6377 }*/
6378
6379 memset(cmd,0,cmdLen);
6380 set_SCSI_opcode(cmd, MODE_SELECT_code);
6381 set_MSEL_pf(cmd, 1);
6382 set_MSEL_xferlen(cmd, outLen);
6383
6384 memset(out,0,outLen);
6385 set_MSEL_pc(page, MS_pc_unk);
6386 set_MSEL_page_len(page, MSEL_data_min_len-2);
6387
6388 *(page + 0x02) = foo;
6389
6390 ret = do_cmd (
6391 s, 1, 0,
6392 cmd, cmdLen,
6393 out, outLen,
6394 NULL, NULL
6395 );
6396
6397 DBG (10, "mode_select_unk: finish\n");
6398
6399 return ret;
6400 }
6401 #endif
6402
6403 /* only used by iX500? */
6404 static SANE_Status
diag_preread(struct fujitsu *s)6405 diag_preread (struct fujitsu *s)
6406 {
6407 SANE_Status ret = SANE_STATUS_GOOD;
6408
6409 unsigned char cmd[SEND_DIAGNOSTIC_len]; /*also big enough for READ_DIAG*/
6410 size_t cmdLen = SEND_DIAGNOSTIC_len;
6411
6412 unsigned char out[SD_preread_len];
6413 size_t outLen = SD_preread_len;
6414
6415 DBG (10, "diag_preread: start\n");
6416
6417 if (!s->has_cmd_sdiag || !s->has_cmd_rdiag || !s->need_diag_preread){
6418 DBG (5, "diag_preread: not supported, returning\n");
6419 return ret;
6420 }
6421
6422 memset(cmd,0,cmdLen);
6423 set_SCSI_opcode(cmd, SEND_DIAGNOSTIC_code);
6424 set_SD_slftst(cmd, 0);
6425 set_SD_xferlen(cmd, outLen);
6426
6427 memcpy(out,SD_preread_string,SD_preread_stringlen);
6428 set_SD_preread_xres(out,s->resolution_x);
6429 set_SD_preread_yres(out,s->resolution_y);
6430 /* call helper function, scanner wants lies about paper width */
6431 set_SD_preread_paper_width(out, get_page_width(s));
6432 /* don't call helper function, scanner wants actual length? */
6433 set_SD_preread_paper_length(out, s->page_height);
6434 set_SD_preread_composition(out, s->s_mode);
6435
6436 ret = do_cmd (
6437 s, 1, 0,
6438 cmd, cmdLen,
6439 out, outLen,
6440 NULL, NULL
6441 );
6442
6443 if (ret != SANE_STATUS_GOOD){
6444 DBG (5, "diag_preread: send diag error: %d\n", ret);
6445 return ret;
6446 }
6447
6448 DBG (10, "diag_preread: finish\n");
6449
6450 return SANE_STATUS_GOOD;
6451 }
6452
6453 static SANE_Status
mode_select_df(struct fujitsu *s)6454 mode_select_df (struct fujitsu *s)
6455 {
6456 SANE_Status ret = SANE_STATUS_GOOD;
6457
6458 unsigned char cmd[MODE_SELECT_len];
6459 size_t cmdLen = MODE_SELECT_len;
6460
6461 unsigned char out[MSEL_header_len + MSEL_data_min_len];
6462 size_t outLen = MSEL_header_len + MSEL_data_min_len;
6463 unsigned char * page = out+MSEL_header_len;
6464
6465 DBG (10, "mode_select_df: start\n");
6466
6467 if(!s->has_MS_df){
6468 DBG (10, "mode_select_df: unsupported\n");
6469 return SANE_STATUS_GOOD;
6470 }
6471
6472 memset(cmd,0,cmdLen);
6473 set_SCSI_opcode(cmd, MODE_SELECT_code);
6474 set_MSEL_pf(cmd, 1);
6475 set_MSEL_xferlen(cmd, outLen);
6476
6477 memset(out,0,outLen);
6478 set_MSEL_pc(page, MS_pc_df);
6479 set_MSEL_page_len(page, MSEL_data_min_len-2);
6480
6481 /* continue/stop */
6482 if(s->df_action != DF_DEFAULT){
6483 set_MSEL_df_enable (page, 1);
6484
6485 /* continue */
6486 if(s->df_action == DF_CONTINUE){
6487 set_MSEL_df_continue (page, 1);
6488 }
6489
6490 /* skew */
6491 if(s->df_skew){
6492 set_MSEL_df_skew (page, 1);
6493 }
6494
6495 /* thickness */
6496 if(s->df_thickness){
6497 set_MSEL_df_thickness (page, 1);
6498 }
6499
6500 /* length */
6501 if(s->df_length){
6502 set_MSEL_df_length (page, 1);
6503 set_MSEL_df_diff (page, s->df_diff);
6504 }
6505 }
6506
6507 set_MSEL_df_paperprot(page,s->paper_protect);
6508 set_MSEL_df_stapledet(page,s->staple_detect);
6509 set_MSEL_df_recovery(page,s->df_recovery);
6510 set_MSEL_df_paperprot2(page,s->adv_paper_prot);
6511
6512 ret = do_cmd (
6513 s, 1, 0,
6514 cmd, cmdLen,
6515 out, outLen,
6516 NULL, NULL
6517 );
6518
6519 DBG (10, "mode_select_df: finish\n");
6520
6521 return ret;
6522 }
6523
6524 static SANE_Status
mode_select_bg(struct fujitsu *s)6525 mode_select_bg (struct fujitsu *s)
6526 {
6527 SANE_Status ret = SANE_STATUS_GOOD;
6528
6529 unsigned char cmd[MODE_SELECT_len];
6530 size_t cmdLen = MODE_SELECT_len;
6531
6532 unsigned char out[MSEL_header_len + MSEL_data_min_len];
6533 size_t outLen = MSEL_header_len + MSEL_data_min_len;
6534 unsigned char * page = out+MSEL_header_len;
6535
6536 DBG (10, "mode_select_bg: start\n");
6537
6538 if(!s->has_MS_bg){
6539 DBG (10, "mode_select_bg: unsupported\n");
6540 return SANE_STATUS_GOOD;
6541 }
6542
6543 memset(cmd,0,cmdLen);
6544 set_SCSI_opcode(cmd, MODE_SELECT_code);
6545 set_MSEL_pf(cmd, 1);
6546 set_MSEL_xferlen(cmd, outLen);
6547
6548 memset(out,0,outLen);
6549 set_MSEL_pc(page, MS_pc_bg);
6550 set_MSEL_page_len(page, MSEL_data_min_len-2);
6551
6552 if(s->bg_color != COLOR_DEFAULT){
6553 set_MSEL_bg_enable (page, 1);
6554
6555 if(s->bg_color == COLOR_BLACK){
6556 set_MSEL_bg_front (page, 1);
6557 set_MSEL_bg_back (page, 1);
6558 set_MSEL_bg_fb (page, 1);
6559 }
6560 }
6561
6562 ret = do_cmd (
6563 s, 1, 0,
6564 cmd, cmdLen,
6565 out, outLen,
6566 NULL, NULL
6567 );
6568
6569 DBG (10, "mode_select_bg: finish\n");
6570
6571 return ret;
6572 }
6573
6574 static SANE_Status
mode_select_dropout(struct fujitsu *s)6575 mode_select_dropout (struct fujitsu *s)
6576 {
6577 SANE_Status ret = SANE_STATUS_GOOD;
6578
6579 unsigned char cmd[MODE_SELECT_len];
6580 size_t cmdLen = MODE_SELECT_len;
6581
6582 unsigned char out[MSEL_header_len + MSEL_data_max_len];
6583 size_t outLen = MSEL_header_len + MSEL_data_max_len;
6584 unsigned char * page = out+MSEL_header_len;
6585
6586 DBG (10, "mode_select_dropout: start\n");
6587
6588 if(!s->has_MS_dropout){
6589 DBG (10, "mode_select_dropout: unsupported\n");
6590 return SANE_STATUS_GOOD;
6591 }
6592
6593 memset(cmd,0,cmdLen);
6594 set_SCSI_opcode(cmd, MODE_SELECT_code);
6595 set_MSEL_pf(cmd, 1);
6596 set_MSEL_xferlen(cmd, outLen);
6597
6598 memset(out,0,outLen);
6599 set_MSEL_pc(page, MS_pc_dropout);
6600 set_MSEL_page_len(page, MSEL_data_max_len-2);
6601
6602 set_MSEL_dropout_front (page, s->dropout_color);
6603 set_MSEL_dropout_back (page, s->dropout_color);
6604
6605 ret = do_cmd (
6606 s, 1, 0,
6607 cmd, cmdLen,
6608 out, outLen,
6609 NULL, NULL
6610 );
6611
6612 DBG (10, "mode_select_dropout: finish\n");
6613
6614 return ret;
6615 }
6616
6617 static SANE_Status
mode_select_buff(struct fujitsu *s)6618 mode_select_buff (struct fujitsu *s)
6619 {
6620 SANE_Status ret = SANE_STATUS_GOOD;
6621
6622 unsigned char cmd[MODE_SELECT_len];
6623 size_t cmdLen = MODE_SELECT_len;
6624
6625 unsigned char out[MSEL_header_len + MSEL_data_min_len];
6626 size_t outLen = MSEL_header_len + MSEL_data_min_len;
6627 unsigned char * page = out+MSEL_header_len;
6628
6629 DBG (10, "mode_select_buff: start\n");
6630
6631 if (!s->has_MS_buff){
6632 DBG (10, "mode_select_buff: unsupported\n");
6633 return SANE_STATUS_GOOD;
6634 }
6635
6636 memset(cmd,0,cmdLen);
6637 set_SCSI_opcode(cmd, MODE_SELECT_code);
6638 set_MSEL_pf(cmd, 1);
6639 set_MSEL_xferlen(cmd, outLen);
6640
6641 memset(out,0,outLen);
6642 set_MSEL_pc(page, MS_pc_buff);
6643 set_MSEL_page_len(page, MSEL_data_min_len-2);
6644
6645 set_MSEL_buff_mode(page, s->buff_mode);
6646 set_MSEL_buff_clear(page, 3);
6647
6648 ret = do_cmd (
6649 s, 1, 0,
6650 cmd, cmdLen,
6651 out, outLen,
6652 NULL, NULL
6653 );
6654
6655 DBG (10, "mode_select_buff: finish\n");
6656
6657 return ret;
6658 }
6659
6660 static SANE_Status
mode_select_prepick(struct fujitsu *s)6661 mode_select_prepick (struct fujitsu *s)
6662 {
6663 SANE_Status ret = SANE_STATUS_GOOD;
6664
6665 unsigned char cmd[MODE_SELECT_len];
6666 size_t cmdLen = MODE_SELECT_len;
6667
6668 unsigned char out[MSEL_header_len + MSEL_data_min_len];
6669 size_t outLen = MSEL_header_len + MSEL_data_min_len;
6670 unsigned char * page = out+MSEL_header_len;
6671
6672 DBG (10, "mode_select_prepick: start\n");
6673
6674 if (!s->has_MS_prepick){
6675 DBG (10, "mode_select_prepick: unsupported\n");
6676 return SANE_STATUS_GOOD;
6677 }
6678
6679 memset(cmd,0,cmdLen);
6680 set_SCSI_opcode(cmd, MODE_SELECT_code);
6681 set_MSEL_pf(cmd, 1);
6682 set_MSEL_xferlen(cmd, outLen);
6683
6684 memset(out,0,outLen);
6685 set_MSEL_pc(page, MS_pc_prepick);
6686 set_MSEL_page_len(page, MSEL_data_min_len-2);
6687
6688 set_MSEL_prepick(page, s->prepick);
6689
6690 ret = do_cmd (
6691 s, 1, 0,
6692 cmd, cmdLen,
6693 out, outLen,
6694 NULL, NULL
6695 );
6696
6697 DBG (10, "mode_select_prepick: finish\n");
6698
6699 return ret;
6700 }
6701
6702 static SANE_Status
mode_select_auto(struct fujitsu *s)6703 mode_select_auto (struct fujitsu *s)
6704 {
6705 SANE_Status ret = SANE_STATUS_GOOD;
6706
6707 unsigned char cmd[MODE_SELECT_len];
6708 size_t cmdLen = MODE_SELECT_len;
6709
6710 unsigned char out[MSEL_header_len + MSEL_data_min_len];
6711 size_t outLen = MSEL_header_len + MSEL_data_min_len;
6712 unsigned char * page = out+MSEL_header_len;
6713
6714 DBG (10, "mode_select_auto: start\n");
6715
6716 if(!s->has_MS_auto){
6717 DBG (10, "mode_select_auto: unsupported\n");
6718 return SANE_STATUS_GOOD;
6719 }
6720
6721 memset(cmd,0,cmdLen);
6722 set_SCSI_opcode(cmd, MODE_SELECT_code);
6723 set_MSEL_pf(cmd, 1);
6724 set_MSEL_xferlen(cmd, outLen);
6725
6726 memset(out,0,outLen);
6727 set_MSEL_pc(page, MS_pc_auto);
6728 set_MSEL_page_len(page, MSEL_data_min_len-2);
6729
6730 set_MSEL_overscan(page, s->overscan);
6731 set_MSEL_ald(page, s->ald || s->hwdeskewcrop);
6732 set_MSEL_awd(page, s->awd || s->hwdeskewcrop);
6733 set_MSEL_req_driv_crop(page, s->hwdeskewcrop && (s->swcrop || s->swdeskew));
6734 set_MSEL_deskew(page, s->hwdeskewcrop);
6735
6736 ret = do_cmd (
6737 s, 1, 0,
6738 cmd, cmdLen,
6739 out, outLen,
6740 NULL, NULL
6741 );
6742
6743 DBG (10, "mode_select_auto: finish\n");
6744
6745 return ret;
6746 }
6747
6748
6749 /*
6750 * @@ Section 4 - SANE scanning functions
6751 */
6752 /*
6753 * Called by SANE to retrieve information about the type of data
6754 * that the current scan will return.
6755 *
6756 * From the SANE spec:
6757 * This function is used to obtain the current scan parameters. The
6758 * returned parameters are guaranteed to be accurate between the time
6759 * a scan has been started (sane_start() has been called) and the
6760 * completion of that request. Outside of that window, the returned
6761 * values are best-effort estimates of what the parameters will be
6762 * when sane_start() gets invoked.
6763 *
6764 * Calling this function before a scan has actually started allows,
6765 * for example, to get an estimate of how big the scanned image will
6766 * be. The parameters passed to this function are the handle h of the
6767 * device for which the parameters should be obtained and a pointer p
6768 * to a parameter structure.
6769 */
6770 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)6771 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
6772 {
6773 SANE_Status ret = SANE_STATUS_GOOD;
6774 struct fujitsu *s = (struct fujitsu *) handle;
6775
6776 DBG (10, "sane_get_parameters: start\n");
6777
6778 /* not started? update param data from user settings */
6779 if(!s->started){
6780 ret = update_params(s);
6781 if(ret)
6782 return ret;
6783 }
6784
6785 params->format = s->u_params.format;
6786 params->last_frame = s->u_params.last_frame;
6787 params->lines = s->u_params.lines;
6788 params->depth = s->u_params.depth;
6789 params->pixels_per_line = s->u_params.pixels_per_line;
6790 params->bytes_per_line = s->u_params.bytes_per_line;
6791
6792 /* we won't know the end until we get to it */
6793 if(s->ald && !must_fully_buffer(s)){
6794 DBG (15, "sane_get_parameters: hand-scanner mode\n");
6795 params->lines = -1;
6796 }
6797
6798 DBG (10, "sane_get_parameters: finish\n");
6799 return ret;
6800 }
6801
6802 /* set s_params and u_params data based on user settings
6803 * and scanner capabilities. */
6804 SANE_Status
update_params(struct fujitsu * s)6805 update_params (struct fujitsu * s)
6806 {
6807 SANE_Status ret = SANE_STATUS_GOOD;
6808 SANE_Parameters * params = &(s->s_params);
6809
6810 DBG (10, "update_params: start\n");
6811
6812 /* first, we setup s_params to describe the image to the scanner */
6813 /* this backend only sends single frame images */
6814 params->last_frame = 1;
6815
6816 /* initial ppl from user settings */
6817 params->pixels_per_line = s->resolution_x * (s->br_x - s->tl_x) / 1200;
6818
6819 /* some scanners require even number of bytes in each transfer block,
6820 * so we round to even # of total lines, to ensure last block is even */
6821 params->lines = s->resolution_y * (s->br_y - s->tl_y) / 1200;
6822 params->lines -= params->lines % 2;
6823
6824 if (s->s_mode == MODE_COLOR) {
6825 params->depth = 8;
6826
6827 /* jpeg requires 8x8 squares */
6828 if(s->compress == COMP_JPEG){
6829 params->format = SANE_FRAME_JPEG;
6830 params->pixels_per_line -= params->pixels_per_line % 8;
6831 params->lines -= params->lines % 8;
6832 }
6833 else{
6834 params->format = SANE_FRAME_RGB;
6835 params->pixels_per_line -= params->pixels_per_line
6836 % max(s->ppl_mod_by_mode[s->s_mode], s->ppl_mod_by_mode[s->u_mode]);
6837 }
6838
6839 params->bytes_per_line = params->pixels_per_line * 3;
6840 }
6841 else if (s->s_mode == MODE_GRAYSCALE) {
6842 params->depth = 8;
6843
6844 /* jpeg requires 8x8 squares */
6845 if(s->compress == COMP_JPEG){
6846 params->format = SANE_FRAME_JPEG;
6847 params->pixels_per_line -= params->pixels_per_line % 8;
6848 params->lines -= params->lines % 8;
6849 }
6850 else{
6851 params->format = SANE_FRAME_GRAY;
6852 params->pixels_per_line -= params->pixels_per_line
6853 % max(s->ppl_mod_by_mode[s->s_mode], s->ppl_mod_by_mode[s->u_mode]);
6854 }
6855
6856 params->bytes_per_line = params->pixels_per_line;
6857 }
6858 else {
6859 params->depth = 1;
6860 params->format = SANE_FRAME_GRAY;
6861 params->pixels_per_line -= params->pixels_per_line
6862 % max(s->ppl_mod_by_mode[s->s_mode], s->ppl_mod_by_mode[s->u_mode]);
6863 params->bytes_per_line = params->pixels_per_line / 8;
6864 }
6865
6866 DBG(15,"update_params: x: max=%d, page=%d, gpw=%d, res=%d\n",
6867 s->max_x, s->page_width, get_page_width(s), s->resolution_x);
6868
6869 DBG(15,"update_params: y: max=%d, page=%d, gph=%d, res=%d\n",
6870 s->max_y, s->page_height, get_page_height(s), s->resolution_y);
6871
6872 DBG(15,"update_params: area: tlx=%d, brx=%d, tly=%d, bry=%d\n",
6873 s->tl_x, s->br_x, s->tl_y, s->br_y);
6874
6875 DBG(15,"update_params: params: ppl=%d, Bpl=%d, lines=%d\n",
6876 params->pixels_per_line, params->bytes_per_line, params->lines);
6877
6878 DBG(15,"update_params: params: format=%d, depth=%d, last=%d\n",
6879 params->format, params->depth, params->last_frame);
6880
6881 /* second, we setup u_params to describe the image to the user */
6882 /* use a helper function cause it is called elsewhere */
6883 ret = update_u_params(s);
6884
6885 DBG (10, "update_params: finish\n");
6886 return ret;
6887 }
6888
6889 /* set u_param data based on user settings, and s_params */
6890 SANE_Status
update_u_params(struct fujitsu * s)6891 update_u_params (struct fujitsu * s)
6892 {
6893 SANE_Status ret = SANE_STATUS_GOOD;
6894 SANE_Parameters * params = &(s->u_params);
6895
6896 DBG (10, "update_u_params: start\n");
6897
6898 /* for most machines, it is the same, so we just copy */
6899 memcpy(&(s->u_params), &(s->s_params), sizeof(SANE_Parameters));
6900
6901 /* some scanners don't support the user's mode, so params differ */
6902 /* but not in jpeg mode. we don't support that. */
6903 if(must_downsample(s)){
6904
6905 /* making gray from a color scan */
6906 if (s->u_mode == MODE_GRAYSCALE) {
6907 params->format = SANE_FRAME_GRAY;
6908 params->bytes_per_line = params->pixels_per_line;
6909 }
6910 /* making binary from a gray or color scan */
6911 else if (s->u_mode == MODE_LINEART) {
6912 params->depth = 1;
6913 params->format = SANE_FRAME_GRAY;
6914 params->bytes_per_line = params->pixels_per_line / 8;
6915 }
6916
6917 DBG(15,"update_u_params: x: max=%d, page=%d, gpw=%d, res=%d\n",
6918 s->max_x, s->page_width, get_page_width(s), s->resolution_x);
6919
6920 DBG(15,"update_u_params: y: max=%d, page=%d, gph=%d, res=%d\n",
6921 s->max_y, s->page_height, get_page_height(s), s->resolution_y);
6922
6923 DBG(15,"update_u_params: area: tlx=%d, brx=%d, tly=%d, bry=%d\n",
6924 s->tl_x, s->br_x, s->tl_y, s->br_y);
6925
6926 DBG(15,"update_u_params: params: ppl=%d, Bpl=%d, lines=%d\n",
6927 params->pixels_per_line, params->bytes_per_line, params->lines);
6928
6929 DBG(15,"update_u_params: params: format=%d, depth=%d, last=%d\n",
6930 params->format, params->depth, params->last_frame);
6931 }
6932
6933 DBG (10, "update_u_params: finish\n");
6934 return ret;
6935 }
6936
6937 /*
6938 * Called by SANE when a page acquisition operation is to be started.
6939 * commands: scanner control (lampon), send (lut), send (dither),
6940 * set window, object pos, and scan
6941 *
6942 * this will be called between sides of a duplex scan,
6943 * and at the start of each page of an adf batch.
6944 * hence, we spend a lot of time playing with s->started, etc.
6945 */
6946 SANE_Status
sane_start(SANE_Handle handle)6947 sane_start (SANE_Handle handle)
6948 {
6949 struct fujitsu *s = handle;
6950 SANE_Status ret = SANE_STATUS_GOOD;
6951
6952 DBG (10, "sane_start: start\n");
6953 DBG (15, "started=%d, side=%d, source=%d\n", s->started, s->side, s->source);
6954
6955 /* undo any prior sane_cancel calls */
6956 s->cancelled=0;
6957
6958 /* protect this block from sane_cancel */
6959 s->reading=1;
6960
6961 /* not finished with current side, error */
6962 if (s->started && !s->eof_tx[s->side]) {
6963 DBG(5,"sane_start: previous transfer not finished?");
6964 ret = SANE_STATUS_INVAL;
6965 goto errors;
6966 }
6967
6968 /* low mem mode messes up the side marker, reset it */
6969 if((s->source == SOURCE_ADF_DUPLEX || s->source == SOURCE_CARD_DUPLEX)
6970 && s->low_mem && s->eof_tx[SIDE_FRONT] && s->eof_tx[SIDE_BACK]
6971 ){
6972 s->side = SIDE_BACK;
6973 }
6974
6975 /* batch start? initialize struct and scanner */
6976 if(!s->started){
6977
6978 /* load side marker */
6979 if(s->source == SOURCE_ADF_BACK || s->source == SOURCE_CARD_BACK){
6980 s->side = SIDE_BACK;
6981 }
6982 else{
6983 s->side = SIDE_FRONT;
6984 }
6985
6986 /* load our own private copy of scan params */
6987 ret = update_params(s);
6988 if (ret != SANE_STATUS_GOOD) {
6989 DBG (5, "sane_start: ERROR: cannot update params\n");
6990 goto errors;
6991 }
6992
6993 /* switch source */
6994 if(s->source == SOURCE_FLATBED){
6995 ret = scanner_control(s, SC_function_fb);
6996 if (ret != SANE_STATUS_GOOD) {
6997 DBG (5, "sane_start: ERROR: cannot control fb, ignoring\n");
6998 }
6999 }
7000 else if(s->source == SOURCE_CARD_FRONT || s->source == SOURCE_CARD_BACK || s->source == SOURCE_CARD_DUPLEX){
7001 ret = scanner_control(s, SC_function_rpath);
7002 if (ret != SANE_STATUS_GOOD) {
7003 DBG (5, "sane_start: ERROR: cannot control rp, ignoring\n");
7004 }
7005 }
7006 else{
7007 ret = scanner_control(s, SC_function_adf);
7008 if (ret != SANE_STATUS_GOOD) {
7009 DBG (5, "sane_start: ERROR: cannot control ADF, ignoring\n");
7010 }
7011 }
7012
7013 /* required for hi res scans on iX500? */
7014 ret = diag_preread(s);
7015 if (ret != SANE_STATUS_GOOD)
7016 DBG (5, "sane_start: WARNING: cannot diag_preread %d\n", ret);
7017
7018 /* enable overscan/auto detection */
7019 ret = mode_select_auto(s);
7020 if (ret != SANE_STATUS_GOOD)
7021 DBG (5, "sane_start: WARNING: cannot mode_select_auto %d\n", ret);
7022
7023 /* enable double feed detection */
7024 ret = mode_select_df(s);
7025 if (ret != SANE_STATUS_GOOD)
7026 DBG (5, "sane_start: WARNING: cannot mode_select_df %d\n", ret);
7027
7028 /* enable background color setting */
7029 ret = mode_select_bg(s);
7030 if (ret != SANE_STATUS_GOOD)
7031 DBG (5, "sane_start: WARNING: cannot mode_select_bg %d\n", ret);
7032
7033 /* enable dropout color setting */
7034 ret = mode_select_dropout(s);
7035 if (ret != SANE_STATUS_GOOD)
7036 DBG (5, "sane_start: WARNING: cannot mode_select_dropout %d\n", ret);
7037
7038 /* enable buffering setting */
7039 ret = mode_select_buff(s);
7040 if (ret != SANE_STATUS_GOOD)
7041 DBG (5, "sane_start: WARNING: cannot mode_select_buff %d\n", ret);
7042
7043 /* enable prepick setting */
7044 ret = mode_select_prepick(s);
7045 if (ret != SANE_STATUS_GOOD)
7046 DBG (5, "sane_start: WARNING: cannot mode_select_prepick %d\n", ret);
7047
7048 /* send endorser config */
7049 ret = send_endorser(s);
7050 if (ret != SANE_STATUS_GOOD)
7051 DBG (5, "sane_start: WARNING: cannot send_endorser %d\n", ret);
7052
7053 /* set window command */
7054 ret = set_window(s);
7055 if (ret != SANE_STATUS_GOOD) {
7056 DBG (5, "sane_start: ERROR: cannot set window\n");
7057 goto errors;
7058 }
7059
7060 /* send lut if set_window said we would */
7061 if ( s->window_gamma ){
7062 ret = send_lut(s);
7063 if (ret != SANE_STATUS_GOOD)
7064 DBG (5, "sane_start: WARNING: cannot send_lut %d\n", ret);
7065 }
7066
7067 /* some scanners need the q table sent, even when not scanning jpeg */
7068 if (s->need_q_table){
7069 ret = send_q_table(s);
7070 if (ret != SANE_STATUS_GOOD)
7071 DBG (5, "sane_start: WARNING: cannot send_q_table %d\n", ret);
7072 }
7073
7074 /* start/stop endorser */
7075 ret = endorser(s);
7076 if (ret != SANE_STATUS_GOOD) {
7077 DBG (5, "sane_start: ERROR: cannot start/stop endorser\n");
7078 goto errors;
7079 }
7080
7081 /* turn lamp on */
7082 ret = scanner_control(s, SC_function_lamp_on);
7083 if (ret != SANE_STATUS_GOOD) {
7084 DBG (5, "sane_start: WARNING: cannot start lamp, ignoring\n");
7085 }
7086
7087 /* iX500 errors if op is called with no paper
7088 * at the beginning of a batch, so we check */
7089 if(s->hopper_before_op && s->source != SOURCE_FLATBED){
7090 ret = get_hardware_status(s,0);
7091 if(!s->hw_hopper){
7092 ret = SANE_STATUS_NO_DOCS;
7093 DBG (5, "sane_start: ERROR: hopper empty\n");
7094 goto errors;
7095 }
7096 }
7097 }
7098 /* if already running, duplex needs to switch sides */
7099 else if(s->source == SOURCE_ADF_DUPLEX || s->source == SOURCE_CARD_DUPLEX){
7100 s->side = !s->side;
7101 }
7102
7103 /* set clean defaults with new sheet of paper */
7104 /* don't reset the transfer vars on backside of duplex page */
7105 /* otherwise buffered back page will be lost */
7106 /* ingest paper with adf (no-op for fb) */
7107 /* don't call object pos or scan on back side of duplex scan */
7108 if(s->side == SIDE_FRONT || s->source == SOURCE_ADF_BACK || s->source == SOURCE_CARD_BACK){
7109
7110 s->bytes_rx[0]=0;
7111 s->bytes_rx[1]=0;
7112 s->lines_rx[0]=0;
7113 s->lines_rx[1]=0;
7114 s->eof_rx[0]=0;
7115 s->eof_rx[1]=0;
7116 s->ili_rx[0]=0;
7117 s->ili_rx[1]=0;
7118 s->eom_rx=0;
7119
7120 s->bytes_tx[0]=0;
7121 s->bytes_tx[1]=0;
7122 s->eof_tx[0]=0;
7123 s->eof_tx[1]=0;
7124
7125 s->buff_rx[0]=0;
7126 s->buff_rx[1]=0;
7127 s->buff_tx[0]=0;
7128 s->buff_tx[1]=0;
7129
7130 /* reset jpeg just in case... */
7131 s->jpeg_stage = JPEG_STAGE_NONE;
7132 s->jpeg_ff_offset = -1;
7133 s->jpeg_front_rst = 0;
7134 s->jpeg_back_rst = 0;
7135
7136 ret = object_position (s, OP_Feed);
7137 if (ret != SANE_STATUS_GOOD) {
7138 DBG (5, "sane_start: ERROR: cannot load page\n");
7139 goto errors;
7140 }
7141
7142 ret = start_scan (s);
7143 if (ret != SANE_STATUS_GOOD) {
7144 DBG (5, "sane_start: ERROR: cannot start_scan\n");
7145 goto errors;
7146 }
7147
7148 /* try to read scan size from scanner */
7149 ret = get_pixelsize(s,0);
7150 if (ret != SANE_STATUS_GOOD) {
7151 DBG (5, "sane_start: ERROR: cannot get pixelsize\n");
7152 goto errors;
7153 }
7154
7155 /* store the number of front bytes */
7156 if ( s->source != SOURCE_ADF_BACK && s->source != SOURCE_CARD_BACK ){
7157 s->bytes_tot[SIDE_FRONT] = s->s_params.bytes_per_line * s->s_params.lines;
7158 s->buff_tot[SIDE_FRONT] = s->buffer_size;
7159
7160 /* the front buffer is normally very small, but some scanners or
7161 * option combinations can't handle it, so we make a big one */
7162 if(
7163 (s->s_mode == MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091)
7164 || must_fully_buffer(s)
7165 ){
7166 s->buff_tot[SIDE_FRONT] = s->bytes_tot[SIDE_FRONT];
7167 }
7168 }
7169 else{
7170 s->bytes_tot[SIDE_FRONT] = 0;
7171 s->buff_tot[SIDE_FRONT] = 0;
7172 }
7173
7174 /* store the number of back bytes */
7175 if ( s->source == SOURCE_ADF_DUPLEX || s->source == SOURCE_ADF_BACK
7176 || s->source == SOURCE_CARD_DUPLEX || s->source == SOURCE_CARD_BACK ){
7177 s->bytes_tot[SIDE_BACK] = s->s_params.bytes_per_line * s->s_params.lines;
7178 s->buff_tot[SIDE_BACK] = s->bytes_tot[SIDE_BACK];
7179
7180 /* the back buffer is normally very large, but some scanners or
7181 * option combinations don't need it, so we make a small one */
7182 if(s->low_mem || s->source == SOURCE_ADF_BACK || s->source == SOURCE_CARD_BACK
7183 || s->duplex_interlace == DUPLEX_INTERLACE_NONE)
7184 s->buff_tot[SIDE_BACK] = s->buffer_size;
7185 }
7186 else{
7187 s->bytes_tot[SIDE_BACK] = 0;
7188 s->buff_tot[SIDE_BACK] = 0;
7189 }
7190
7191 /* first page of batch */
7192 /* make large buffer to hold the images */
7193 /* and set started flag */
7194 if(!s->started){
7195 ret = setup_buffers(s);
7196 if (ret != SANE_STATUS_GOOD) {
7197 DBG (5, "sane_start: ERROR: cannot load buffers\n");
7198 goto errors;
7199 }
7200
7201 s->started=1;
7202 }
7203 }
7204 else{
7205 /* try to read scan size from scanner */
7206 ret = get_pixelsize(s,0);
7207 if (ret != SANE_STATUS_GOOD) {
7208 DBG (5, "sane_start: ERROR: cannot get pixelsize\n");
7209 goto errors;
7210 }
7211 }
7212
7213 DBG (15, "started=%d, side=%d, source=%d\n", s->started, s->side, s->source);
7214
7215 /* certain options require the entire image to
7216 * be collected from the scanner before we can
7217 * tell the user the size of the image. the sane
7218 * API has no way to inform the frontend of this,
7219 * so we block and buffer. yuck */
7220 if( must_fully_buffer(s) ){
7221
7222 /* get image */
7223 while(!s->eof_rx[s->side] && !ret){
7224 SANE_Int len = 0;
7225 ret = sane_read((SANE_Handle)s, NULL, 0, &len);
7226 }
7227
7228 /* check for errors */
7229 if (ret != SANE_STATUS_GOOD) {
7230 DBG (5, "sane_start: ERROR: cannot buffer image\n");
7231 goto errors;
7232 }
7233
7234 DBG (5, "sane_start: OK: done buffering\n");
7235
7236 /* hardware deskew will tell image size after transfer */
7237 ret = get_pixelsize(s,1);
7238 if (ret != SANE_STATUS_GOOD) {
7239 DBG (5, "sane_start: ERROR: cannot get final pixelsize\n");
7240 goto errors;
7241 }
7242
7243 /* finished buffering, adjust image as required */
7244 if(s->swdeskew && (!s->hwdeskewcrop || s->req_driv_crop)){
7245 buffer_deskew(s,s->side);
7246 }
7247 if(s->swcrop && (!s->hwdeskewcrop || s->req_driv_crop)){
7248 buffer_crop(s,s->side);
7249 }
7250 if(s->swdespeck){
7251 buffer_despeck(s,s->side);
7252 }
7253 if(s->swskip){
7254 /* Skipping means throwing out this image.
7255 * Pretend the user read the whole thing
7256 * and call sane_start again.
7257 * This assumes we are running in batch mode. */
7258 if(buffer_isblank(s,s->side)){
7259 s->bytes_tx[s->side] = s->bytes_rx[s->side];
7260 s->eof_tx[s->side] = 1;
7261 return sane_start(handle);
7262 }
7263 }
7264
7265 }
7266
7267 /* check if user cancelled during this start */
7268 ret = check_for_cancel(s);
7269
7270 /* unprotect this block from sane_cancel */
7271 s->reading=0;
7272
7273 DBG (10, "sane_start: finish %d\n", ret);
7274 return ret;
7275
7276 errors:
7277 DBG (10, "sane_start: error %d\n", ret);
7278
7279 /* if we are started, but something went wrong,
7280 * chances are there is image data inside scanner,
7281 * which should be discarded via cancel command */
7282 if(s->started){
7283 s->cancelled = 1;
7284 check_for_cancel(s);
7285 }
7286
7287 s->started = 0;
7288 s->cancelled = 0;
7289 s->reading = 0;
7290 return ret;
7291 }
7292
7293 static SANE_Status
endorser(struct fujitsu *s)7294 endorser(struct fujitsu *s)
7295 {
7296 SANE_Status ret = SANE_STATUS_GOOD;
7297
7298 unsigned char cmd[ENDORSER_len];
7299 size_t cmdLen = ENDORSER_len;
7300
7301 unsigned char out[ED_max_len];
7302 size_t outLen = ED_max_len;
7303
7304 DBG (10, "endorser: start\n");
7305
7306 memset(cmd,0,cmdLen);
7307 set_SCSI_opcode(cmd, ENDORSER_code);
7308
7309 memset(out,0,outLen);
7310
7311 if (s->has_endorser_f || s->has_endorser_b){
7312
7313 /*fi-5900 front side uses 0x80, assume all others*/
7314 if(s->u_endorser_side == ED_front){
7315 set_ED_endorser_data_id(out,0x80);
7316 }
7317 else{
7318 set_ED_endorser_data_id(out,0);
7319 }
7320
7321 if(s->u_endorser){
7322 set_ED_stop(out,ED_start);
7323 }
7324 else{
7325 set_ED_stop(out,ED_stop);
7326 }
7327
7328 set_ED_side(out,s->u_endorser_side);
7329
7330 if(s->u_endorser_bits == 24){
7331 set_ED_lap24(out,ED_lap_24bit);
7332 set_ED_initial_count_24(out,s->u_endorser_val);
7333 }
7334
7335 else{
7336 outLen = ED_min_len;
7337 set_ED_lap24(out,ED_lap_16bit);
7338 set_ED_initial_count_16(out,s->u_endorser_val);
7339 }
7340
7341 set_E_xferlen(cmd, outLen);
7342 ret = do_cmd (
7343 s, 1, 0,
7344 cmd, cmdLen,
7345 out, outLen,
7346 NULL, NULL
7347 );
7348 }
7349
7350 DBG (10, "endorser: finish %d\n", ret);
7351
7352 return ret;
7353 }
7354
7355 static SANE_Status
scanner_control(struct fujitsu *s, int function)7356 scanner_control (struct fujitsu *s, int function)
7357 {
7358 SANE_Status ret = SANE_STATUS_GOOD;
7359 int tries = 0;
7360
7361 unsigned char cmd[SCANNER_CONTROL_len];
7362 size_t cmdLen = SCANNER_CONTROL_len;
7363
7364 DBG (10, "scanner_control: start\n");
7365
7366 if(s->has_cmd_scanner_ctl){
7367
7368 memset(cmd,0,cmdLen);
7369 set_SCSI_opcode(cmd, SCANNER_CONTROL_code);
7370 set_SC_function_1 (cmd, function);
7371 set_SC_function_2 (cmd, function);
7372
7373 DBG (15, "scanner_control: function %d\n",function);
7374
7375 /* don't really need to ask for adf if that's the only option */
7376 /* doing so causes the 3091 to complain */
7377 if(function == SC_function_adf && !s->has_flatbed && !s->has_return_path){
7378 DBG (10, "scanner_control: adf function not required\n");
7379 return ret;
7380 }
7381
7382 /* extremely long retry period */
7383 while(tries++ < 120){
7384
7385 ret = do_cmd (
7386 s, 1, 0,
7387 cmd, cmdLen,
7388 NULL, 0,
7389 NULL, NULL
7390 );
7391
7392 if(ret == SANE_STATUS_GOOD || function != SC_function_lamp_on){
7393 break;
7394 }
7395
7396 usleep(500000);
7397 }
7398
7399 if(ret == SANE_STATUS_GOOD){
7400 DBG (15, "scanner_control: success, tries %d, ret %d\n",tries,ret);
7401 }
7402 else{
7403 DBG (5, "scanner_control: error, tries %d, ret %d\n",tries,ret);
7404 }
7405 }
7406
7407 DBG (10, "scanner_control: finish\n");
7408
7409 return ret;
7410 }
7411
7412 static SANE_Status
scanner_control_ric(struct fujitsu *s, int bytes, int side)7413 scanner_control_ric (struct fujitsu *s, int bytes, int side)
7414 {
7415 SANE_Status ret = SANE_STATUS_GOOD;
7416 int tries = 0;
7417
7418 unsigned char cmd[SCANNER_CONTROL_len];
7419 size_t cmdLen = SCANNER_CONTROL_len;
7420
7421 DBG (10, "scanner_control_ric: start\n");
7422
7423 if(s->has_cmd_scanner_ctl){
7424
7425 memset(cmd,0,cmdLen);
7426 set_SCSI_opcode(cmd, SCANNER_CONTROL_code);
7427
7428 set_SC_ric(cmd, 1);
7429 if (side == SIDE_BACK) {
7430 set_SC_ric_dtq(cmd, WD_wid_back);
7431 }
7432 else{
7433 set_SC_ric_dtq(cmd, WD_wid_front);
7434 }
7435
7436 set_SC_ric_len(cmd, bytes);
7437
7438 DBG (15, "scanner_control_ric: %d %d\n",bytes,side);
7439
7440 /* extremely long retry period */
7441 while(tries++ < 120){
7442
7443 ret = do_cmd (
7444 s, 1, 0,
7445 cmd, cmdLen,
7446 NULL, 0,
7447 NULL, NULL
7448 );
7449
7450 if(ret != SANE_STATUS_DEVICE_BUSY){
7451 break;
7452 }
7453
7454 usleep(500000);
7455 }
7456
7457 if(ret == SANE_STATUS_GOOD){
7458 DBG (15, "scanner_control_ric: success, tries %d, ret %d\n",tries,ret);
7459 }
7460 /* some errors pass thru unchanged */
7461 else if(ret == SANE_STATUS_CANCELLED || ret == SANE_STATUS_JAMMED
7462 || ret == SANE_STATUS_NO_DOCS || ret == SANE_STATUS_COVER_OPEN
7463 ){
7464 DBG (5, "scanner_control_ric: error, tries %d, ret %d\n",tries,ret);
7465 }
7466 /* other errors are ignored, since scanner may not support RIC */
7467 else{
7468 DBG (5, "scanner_control_ric: ignoring, tries %d, ret %d\n",tries,ret);
7469 ret = SANE_STATUS_GOOD;
7470 }
7471 }
7472
7473 DBG (10, "scanner_control_ric: finish\n");
7474
7475 return ret;
7476 }
7477
7478 /*
7479 * callocs a buffer to hold the scan data
7480 */
7481 static SANE_Status
setup_buffers(struct fujitsu *s)7482 setup_buffers (struct fujitsu *s)
7483 {
7484 SANE_Status ret = SANE_STATUS_GOOD;
7485 int side;
7486
7487 DBG (10, "setup_buffers: start\n");
7488
7489 for(side=0;side<2;side++){
7490
7491 /* free old mem */
7492 if (s->buffers[side]) {
7493 DBG (15, "setup_buffers: free buffer %d.\n",side);
7494 free(s->buffers[side]);
7495 s->buffers[side] = NULL;
7496 }
7497
7498 if(s->buff_tot[side]){
7499 s->buffers[side] = calloc (1,s->buff_tot[side]);
7500
7501 if (!s->buffers[side]) {
7502 DBG (5, "setup_buffers: Error, no buffer %d.\n",side);
7503 return SANE_STATUS_NO_MEM;
7504 }
7505 }
7506 }
7507
7508 DBG (10, "setup_buffers: finish\n");
7509
7510 return ret;
7511 }
7512
7513 /*
7514 * This routine issues a SCSI SET WINDOW command to the scanner, using the
7515 * values currently in the scanner data structure.
7516 */
7517 static SANE_Status
set_window(struct fujitsu *s)7518 set_window (struct fujitsu *s)
7519 {
7520 SANE_Status ret = SANE_STATUS_GOOD;
7521
7522 /* The command specifies the number of bytes in the data phase
7523 * the data phase has a header, followed by 1 or 2 window desc blocks
7524 * the header specifies the number of bytes in 1 window desc block
7525 */
7526
7527 unsigned char cmd[SET_WINDOW_len];
7528 size_t cmdLen = SET_WINDOW_len;
7529
7530 /*this is max size, we might send less below*/
7531 unsigned char out[SW_header_len + SW_desc_len + SW_desc_len];
7532 size_t outLen = SW_header_len + SW_desc_len + SW_desc_len;
7533
7534 unsigned char * header = out; /*header*/
7535 unsigned char * desc1 = out + SW_header_len; /*1st desc*/
7536 unsigned char * desc2 = out + SW_header_len + SW_desc_len; /*2nd desc*/
7537
7538 int length = 0;
7539
7540 DBG (10, "set_window: start\n");
7541
7542 /*build the payload*/
7543 memset(out,0,outLen);
7544
7545 /* set window desc size in header */
7546 set_WPDB_wdblen(header, SW_desc_len);
7547
7548 /* init the window block */
7549 if (s->source == SOURCE_ADF_BACK || s->source == SOURCE_CARD_BACK) {
7550 set_WD_wid (desc1, WD_wid_back);
7551 }
7552 else{
7553 set_WD_wid (desc1, WD_wid_front);
7554 }
7555
7556 set_WD_Xres (desc1, s->resolution_x);
7557 set_WD_Yres (desc1, s->resolution_y);
7558
7559 set_WD_ULX (desc1, s->tl_x);
7560 /* low-end scanners ignore paper-size,
7561 * so we have to center the window ourselves */
7562 if(s->cropping_mode == CROP_ABSOLUTE){
7563 set_WD_ULX (desc1, s->tl_x + (s->max_x - s->page_width) / 2);
7564 }
7565
7566 set_WD_ULY (desc1, s->tl_y);
7567 set_WD_width (desc1, s->s_params.pixels_per_line * 1200/s->resolution_x);
7568
7569 length = s->s_params.lines * 1200/s->resolution_y;
7570
7571 /* stupid trick. 3091/2 require reading extra lines,
7572 * because they have a gap between R G and B */
7573 if(s->s_mode == MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091){
7574 length += (s->color_raster_offset+s->green_offset) * 1200/300 * 2;
7575 DBG(5,"set_window: Increasing length to %d\n",length);
7576 }
7577 set_WD_length (desc1, length);
7578
7579 set_WD_brightness (desc1, 0);
7580 if(s->brightness_steps){
7581 /*convert our common -127 to +127 range into HW's range
7582 *FIXME: this code assumes hardware range of 0-255 */
7583 set_WD_brightness (desc1, s->brightness+128);
7584 }
7585
7586 set_WD_threshold (desc1, s->threshold);
7587
7588 set_WD_contrast (desc1, 0);
7589 if(s->contrast_steps){
7590 /*convert our common -127 to +127 range into HW's range
7591 *FIXME: this code assumes hardware range of 0-255 */
7592 set_WD_contrast (desc1, s->contrast+128);
7593 }
7594
7595 set_WD_composition (desc1, s->s_mode);
7596
7597 set_WD_bitsperpixel (desc1, s->s_params.depth);
7598
7599 if(s->s_mode == MODE_HALFTONE){
7600 set_WD_ht_type(desc1, s->ht_type);
7601 set_WD_ht_pattern(desc1, s->ht_pattern);
7602 }
7603
7604 set_WD_rif (desc1, s->rif);
7605
7606 set_WD_compress_type(desc1, COMP_NONE);
7607 set_WD_compress_arg(desc1, 0);
7608
7609 /* some scanners support jpeg image compression, for color/gs only */
7610 if(s->s_params.format == SANE_FRAME_JPEG){
7611 set_WD_compress_type(desc1, COMP_JPEG);
7612 set_WD_compress_arg(desc1, s->compress_arg);
7613 }
7614
7615 /* the remainder of the block varies based on model and mode,
7616 * except for gamma and paper size, those are in the same place */
7617
7618 /* determine if we need to send gamma LUT.
7619 * send lut if scanner supports it and any of:
7620 * has no hardware brightness but user changed it
7621 * has no hardware contrast but user changed it
7622 * has no internal gamma table */
7623 if ( s->num_download_gamma && (
7624 (!s->brightness_steps && s->brightness != 0)
7625 || (!s->contrast_steps && s->contrast != 0 )
7626 || !s->num_internal_gamma
7627 ) ){
7628 s->window_gamma = 0x80;
7629 }
7630 /* otherwise, use the internal table */
7631 else{
7632 s->window_gamma = 0;
7633 }
7634
7635 /*vuid c0*/
7636 if(s->has_vuid_3091){
7637 set_WD_vendor_id_code (desc1, WD_VUID_3091);
7638 set_WD_gamma (desc1, s->window_gamma);
7639
7640 if (s->s_mode != MODE_COLOR){
7641 switch (s->dropout_color) {
7642 case COLOR_RED:
7643 set_WD_lamp_color (desc1, WD_LAMP_RED);
7644 break;
7645 case COLOR_GREEN:
7646 set_WD_lamp_color (desc1, WD_LAMP_GREEN);
7647 break;
7648 case COLOR_BLUE:
7649 set_WD_lamp_color (desc1, WD_LAMP_BLUE);
7650 break;
7651 default:
7652 set_WD_lamp_color (desc1, WD_LAMP_DEFAULT);
7653 break;
7654 }
7655 }
7656 /*set_WD_quality(desc1,s->quality);*/
7657 }
7658
7659 /*vuid c1*/
7660 else if(s->s_mode == MODE_COLOR && s->has_vuid_color){
7661 set_WD_vendor_id_code (desc1, WD_VUID_COLOR);
7662 set_WD_gamma (desc1, s->window_gamma);
7663
7664 if(s->color_interlace == COLOR_INTERLACE_RGB){
7665 set_WD_scanning_order (desc1, WD_SCAN_ORDER_DOT);
7666 set_WD_scanning_order_arg (desc1, WD_SCAN_ARG_RGB);
7667 }
7668 else if(s->color_interlace == COLOR_INTERLACE_BGR){
7669 set_WD_scanning_order (desc1, WD_SCAN_ORDER_DOT);
7670 set_WD_scanning_order_arg (desc1, WD_SCAN_ARG_BGR);
7671 }
7672 else if(s->color_interlace == COLOR_INTERLACE_RRGGBB){
7673 set_WD_scanning_order (desc1, WD_SCAN_ORDER_LINE);
7674 set_WD_scanning_order_arg (desc1, WD_SCAN_ARG_RGB);
7675 }
7676 else{
7677 DBG (5,"set_window: unknown color interlacing\n");
7678 return SANE_STATUS_INVAL;
7679 }
7680
7681 /*scanner emphasis ranges from 0 to 7f and smoothing from 80 to ff*/
7682 /* but we expose them to user as a single linear range smooth->emphasis */
7683 /* flip the smooth part over, and tack it onto the upper end of emphasis */
7684 if(s->emphasis < 0)
7685 set_WD_c1_emphasis(desc1,127-s->emphasis);
7686 else
7687 set_WD_c1_emphasis(desc1,s->emphasis);
7688
7689 set_WD_c1_mirroring(desc1,s->mirroring);
7690
7691 set_WD_wl_follow(desc1,s->wl_follow);
7692 }
7693
7694 /*vuid 00*/
7695 else if(s->has_vuid_mono){
7696 set_WD_vendor_id_code (desc1, WD_VUID_MONO);
7697 set_WD_gamma (desc1, s->window_gamma);
7698
7699 set_WD_outline(desc1,s->outline);
7700
7701 /*scanner emphasis ranges from 0 to 7f and smoothing from 80 to ff*/
7702 /* but we expose them to user as a single linear range smooth->emphasis */
7703 /* flip the smooth part over, and tack it onto the upper end of emphasis */
7704 if(s->emphasis < 0)
7705 set_WD_emphasis(desc1,127-s->emphasis);
7706 else
7707 set_WD_emphasis(desc1,s->emphasis);
7708
7709 set_WD_separation(desc1,s->separation);
7710 set_WD_mirroring(desc1,s->mirroring);
7711
7712 if (get_ipc_mode(s) == WD_ipc_SDTC)
7713 set_WD_variance(desc1,s->variance);
7714
7715 else if (get_ipc_mode(s) == WD_ipc_DTC){
7716 set_WD_filtering(desc1,s->bp_filter);
7717 set_WD_smoothing(desc1,s->smoothing);
7718 set_WD_gamma_curve(desc1,s->gamma_curve);
7719 set_WD_threshold_curve(desc1,s->threshold_curve);
7720 set_WD_noise_removal(desc1,s->noise_removal);
7721 if(s->noise_removal){
7722 set_WD_matrix5x5(desc1,s->matrix_5);
7723 set_WD_matrix4x4(desc1,s->matrix_4);
7724 set_WD_matrix3x3(desc1,s->matrix_3);
7725 set_WD_matrix2x2(desc1,s->matrix_2);
7726 }
7727 set_WD_background(desc1,s->threshold_white);
7728 }
7729
7730 set_WD_wl_follow(desc1,s->wl_follow);
7731 set_WD_subwindow_list(desc1,0);
7732 set_WD_ipc_mode(desc1,get_ipc_mode(s));
7733 }
7734
7735 else{
7736 DBG (5,"set_window: no vuid to send?\n");
7737 return SANE_STATUS_INVAL;
7738 }
7739
7740 /* common to all vuids */
7741 if(s->source == SOURCE_FLATBED){
7742 set_WD_paper_selection(desc1,WD_paper_SEL_UNDEFINED);
7743 }
7744 else{
7745 set_WD_paper_selection (desc1, WD_paper_SEL_NON_STANDARD);
7746
7747 /* call helper function, scanner wants lies about paper width */
7748 set_WD_paper_width_X (desc1, get_page_width(s));
7749
7750 /* don't call helper function, scanner wants actual length? */
7751 set_WD_paper_length_Y (desc1, s->page_height);
7752 }
7753
7754 /* when in duplex mode, copy first desc block into second */
7755 if (s->source == SOURCE_ADF_DUPLEX || s->source == SOURCE_CARD_DUPLEX) {
7756 memcpy (desc2, desc1, SW_desc_len);
7757
7758 set_WD_wid (desc2, WD_wid_back);
7759
7760 /* FIXME: do we really need these on back of page? */
7761 set_WD_paper_selection (desc2, WD_paper_SEL_UNDEFINED);
7762 set_WD_paper_width_X (desc2, 0);
7763 set_WD_paper_length_Y (desc2, 0);
7764 }
7765 /* output shorter if not using duplex */
7766 else{
7767 outLen -= SW_desc_len;
7768 }
7769
7770 /*build the command*/
7771 memset(cmd,0,cmdLen);
7772 set_SCSI_opcode(cmd, SET_WINDOW_code);
7773 set_SW_xferlen(cmd, outLen);
7774
7775 ret = do_cmd (
7776 s, 1, 0,
7777 cmd, cmdLen,
7778 out, outLen,
7779 NULL, NULL
7780 );
7781
7782 DBG (10, "set_window: finish\n");
7783
7784 return ret;
7785 }
7786
7787 /* update s_params with actual data size scanner reports */
7788 /* then copy as required to the u_params to send to user */
7789 static SANE_Status
get_pixelsize(struct fujitsu *s, int actual)7790 get_pixelsize(struct fujitsu *s, int actual)
7791 {
7792 SANE_Status ret;
7793
7794 unsigned char cmd[READ_len];
7795 size_t cmdLen = READ_len;
7796
7797 unsigned char in[R_PSIZE_len];
7798 size_t inLen = R_PSIZE_len;
7799
7800 DBG (10, "get_pixelsize: start %d\n",actual);
7801
7802 if (!s->has_pixelsize){
7803 DBG (10, "get_pixelsize: unsupported\n");
7804 return SANE_STATUS_GOOD;
7805 }
7806
7807 memset(cmd,0,cmdLen);
7808 set_SCSI_opcode(cmd, READ_code);
7809 set_R_datatype_code (cmd, R_datatype_pixelsize);
7810
7811 if(s->side == SIDE_BACK){
7812 set_R_window_id (cmd, WD_wid_back);
7813 }
7814 else{
7815 set_R_window_id (cmd, WD_wid_front);
7816 }
7817 set_R_xfer_length (cmd, inLen);
7818
7819 ret = do_cmd (
7820 s, 1, 0,
7821 cmd, cmdLen,
7822 NULL, 0,
7823 in, &inLen
7824 );
7825 if (ret == SANE_STATUS_GOOD){
7826
7827 /* when we are called post-scan, the scanner may give
7828 * more accurate data in other fields */
7829 if(actual && !s->has_short_pixelsize && get_PSIZE_paper_w(in)){
7830 DBG(5,"get_pixelsize: Actual width %d -> %d\n", s->s_params.pixels_per_line, get_PSIZE_paper_w(in));
7831 s->s_params.pixels_per_line = get_PSIZE_paper_w(in);
7832 }
7833 else{
7834 s->s_params.pixels_per_line = get_PSIZE_num_x(in);
7835 }
7836
7837 /* stupid trick. 3091/2 require reading extra lines,
7838 * because they have a gap between R G and B
7839 * we only want to report the shorter value to the frontend */
7840 if(s->s_mode == MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091){
7841 DBG(5,"get_pixelsize: Ignoring length %d\n",get_PSIZE_num_y(in));
7842 }
7843 /* when we are called post-scan, the scanner may give
7844 * more accurate data in other fields */
7845 else if(actual && !s->has_short_pixelsize && get_PSIZE_paper_l(in)){
7846 DBG(5,"get_pixelsize: Actual length %d -> %d\n", s->s_params.lines, get_PSIZE_paper_l(in));
7847 s->s_params.lines = get_PSIZE_paper_l(in);
7848 }
7849 else{
7850 s->s_params.lines = get_PSIZE_num_y(in);
7851 }
7852
7853 /* bytes per line differs by mode */
7854 if (s->s_mode == MODE_COLOR) {
7855 s->s_params.bytes_per_line = s->s_params.pixels_per_line * 3;
7856 }
7857 else if (s->s_mode == MODE_GRAYSCALE) {
7858 s->s_params.bytes_per_line = s->s_params.pixels_per_line;
7859 }
7860 else {
7861 s->s_params.bytes_per_line = s->s_params.pixels_per_line / 8;
7862 }
7863
7864 /* some scanners can request that the driver clean img */
7865 if(!s->has_short_pixelsize && get_PSIZE_req_driv_valid(in)){
7866 s->req_driv_crop = get_PSIZE_req_driv_crop(in);
7867 s->req_driv_lut = get_PSIZE_req_driv_lut(in);
7868 DBG(5,"get_pixelsize: scanner requests: crop=%d, lut=%d\n",
7869 s->req_driv_crop,s->req_driv_lut);
7870 }
7871
7872 DBG (15, "get_pixelsize: scan_x=%d, Bpl=%d, scan_y=%d\n",
7873 s->s_params.pixels_per_line, s->s_params.bytes_per_line, s->s_params.lines );
7874
7875 /* the user params are usually the same */
7876 s->u_params.pixels_per_line = s->s_params.pixels_per_line;
7877 s->u_params.lines = s->s_params.lines;
7878
7879 /* bytes per line differs by mode */
7880 if (s->u_mode == MODE_COLOR) {
7881 s->u_params.bytes_per_line = s->u_params.pixels_per_line * 3;
7882 }
7883 else if (s->u_mode == MODE_GRAYSCALE) {
7884 s->u_params.bytes_per_line = s->u_params.pixels_per_line;
7885 }
7886 else {
7887 s->u_params.bytes_per_line = s->u_params.pixels_per_line / 8;
7888 }
7889
7890 }
7891 else{
7892 DBG (10, "get_pixelsize: got bad status %d, ignoring\n", ret);
7893 s->has_pixelsize = 0;
7894 ret = SANE_STATUS_GOOD;
7895 }
7896
7897 DBG (10, "get_pixelsize: finish\n");
7898
7899 return ret;
7900 }
7901
7902 /*
7903 * Issues the SCSI OBJECT POSITION command if an ADF or card scanner is in use.
7904 */
7905 static SANE_Status
object_position(struct fujitsu *s, int action)7906 object_position (struct fujitsu *s, int action)
7907 {
7908 SANE_Status ret = SANE_STATUS_GOOD;
7909
7910 unsigned char cmd[OBJECT_POSITION_len];
7911 size_t cmdLen = OBJECT_POSITION_len;
7912
7913 DBG (10, "object_position: start %d\n", action);
7914
7915 if (s->source == SOURCE_FLATBED && action < OP_Halt) {
7916 DBG (10, "object_position: flatbed no-op\n");
7917 return SANE_STATUS_GOOD;
7918 }
7919
7920 memset(cmd,0,cmdLen);
7921 set_SCSI_opcode(cmd, OBJECT_POSITION_code);
7922 set_OP_action (cmd, action);
7923
7924 ret = do_cmd (
7925 s, 1, 0,
7926 cmd, cmdLen,
7927 NULL, 0,
7928 NULL, NULL
7929 );
7930 if (ret != SANE_STATUS_GOOD)
7931 return ret;
7932
7933 if(!s->no_wait_after_op)
7934 wait_scanner (s);
7935
7936 DBG (10, "object_position: finish\n");
7937
7938 return ret;
7939 }
7940
7941 /*
7942 * Issues SCAN command.
7943 *
7944 * (This doesn't actually read anything, it just tells the scanner
7945 * to start scanning.)
7946 */
7947 static SANE_Status
start_scan(struct fujitsu *s)7948 start_scan (struct fujitsu *s)
7949 {
7950 SANE_Status ret = SANE_STATUS_GOOD;
7951
7952 unsigned char cmd[SCAN_len];
7953 size_t cmdLen = SCAN_len;
7954
7955 unsigned char out[] = {WD_wid_front, WD_wid_back};
7956 size_t outLen = 2;
7957
7958 DBG (10, "start_scan: start\n");
7959
7960 if (s->source != SOURCE_ADF_DUPLEX && s->source != SOURCE_CARD_DUPLEX) {
7961 outLen--;
7962 if(s->source == SOURCE_ADF_BACK || s->source == SOURCE_CARD_BACK) {
7963 out[0] = WD_wid_back;
7964 }
7965 }
7966
7967 memset(cmd,0,cmdLen);
7968 set_SCSI_opcode(cmd, SCAN_code);
7969 set_SC_xfer_length (cmd, outLen);
7970
7971 ret = do_cmd (
7972 s, 1, 0,
7973 cmd, cmdLen,
7974 out, outLen,
7975 NULL, NULL
7976 );
7977
7978 DBG (10, "start_scan: finish\n");
7979
7980 return ret;
7981 }
7982
7983 /* checks started and cancelled flags in scanner struct,
7984 * sends cancel command to scanner if required. don't call
7985 * this function asynchronously, wait for pending operation */
7986 static SANE_Status
check_for_cancel(struct fujitsu *s)7987 check_for_cancel(struct fujitsu *s)
7988 {
7989 SANE_Status ret=SANE_STATUS_GOOD;
7990
7991 DBG (10, "check_for_cancel: start %d %d\n",s->started,s->cancelled);
7992
7993 if(s->started && s->cancelled){
7994
7995 /* halt scan */
7996 if(s->halt_on_cancel){
7997 DBG (15, "check_for_cancel: halting\n");
7998 ret = object_position (s, OP_Halt);
7999 }
8000 /* cancel scan */
8001 else{
8002 DBG (15, "check_for_cancel: cancelling\n");
8003 ret = scanner_control(s, SC_function_cancel);
8004 }
8005
8006 if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_CANCELLED) {
8007 ret = SANE_STATUS_CANCELLED;
8008 }
8009 else{
8010 DBG (5, "check_for_cancel: ERROR: cannot cancel\n");
8011 }
8012
8013 s->started = 0;
8014 s->cancelled = 0;
8015 }
8016 else if(s->cancelled){
8017 DBG (15, "check_for_cancel: already cancelled\n");
8018 ret = SANE_STATUS_CANCELLED;
8019 s->cancelled = 0;
8020 }
8021
8022 DBG (10, "check_for_cancel: finish %d\n",ret);
8023 return ret;
8024 }
8025
8026 /*
8027 * Called by SANE to read data.
8028 *
8029 * From the SANE spec:
8030 * This function is used to read image data from the device
8031 * represented by handle h. Argument buf is a pointer to a memory
8032 * area that is at least maxlen bytes long. The number of bytes
8033 * returned is stored in *len. A backend must set this to zero when
8034 * the call fails (i.e., when a status other than SANE_STATUS_GOOD is
8035 * returned).
8036 *
8037 * When the call succeeds, the number of bytes returned can be
8038 * anywhere in the range from 0 to maxlen bytes.
8039 */
8040 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len)8041 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len)
8042 {
8043 struct fujitsu *s = (struct fujitsu *) handle;
8044 SANE_Status ret=SANE_STATUS_GOOD;
8045
8046 DBG (10, "sane_read: start\n");
8047
8048 *len=0;
8049
8050 /* maybe cancelled? */
8051 if(!s->started){
8052 DBG (5, "sane_read: not started, call sane_start\n");
8053 return SANE_STATUS_CANCELLED;
8054 }
8055
8056 /* sane_start required between sides */
8057 if(s->eof_rx[s->side] && s->bytes_tx[s->side] == s->bytes_rx[s->side]){
8058 DBG (15, "sane_read: returning eof\n");
8059 s->eof_tx[s->side] = 1;
8060
8061 /* swap sides if user asked for low-mem mode, we are duplexing,
8062 * and there is data waiting on the other side */
8063 if(s->low_mem
8064 && (s->source == SOURCE_ADF_DUPLEX || s->source == SOURCE_CARD_DUPLEX)
8065 && (s->bytes_rx[!s->side] > s->bytes_tx[!s->side]
8066 || (s->eof_rx[!s->side] && !s->eof_tx[!s->side])
8067 )
8068 ){
8069 s->side = !s->side;
8070 }
8071
8072 return SANE_STATUS_EOF;
8073 }
8074
8075 /* protect this block from sane_cancel */
8076 s->reading = 1;
8077
8078 /* ----------------------------------------------
8079 * try to read some data from scanner into buffer
8080 * these functions are expected not to overrun */
8081
8082 /* 3091/2 are on crack, get their own duplex reader function */
8083 if(s->source == SOURCE_ADF_DUPLEX
8084 && s->duplex_interlace == DUPLEX_INTERLACE_3091
8085 ){
8086 ret = read_from_3091duplex(s);
8087 if(ret){
8088 DBG(5,"sane_read: 3091 returning %d\n",ret);
8089 return ret;
8090 }
8091 } /* end 3091 */
8092
8093 /* alternating jpeg duplex interlacing */
8094 else if((s->source == SOURCE_ADF_DUPLEX || s->source == SOURCE_CARD_DUPLEX)
8095 && s->s_params.format == SANE_FRAME_JPEG
8096 && s->jpeg_interlace == JPEG_INTERLACE_ALT
8097 ){
8098 ret = read_from_JPEGduplex(s);
8099 if(ret){
8100 DBG(5,"sane_read: jpeg duplex returning %d\n",ret);
8101 return ret;
8102 }
8103 } /* end alt jpeg */
8104
8105 /* alternating pnm duplex interlacing */
8106 else if((s->source == SOURCE_ADF_DUPLEX || s->source == SOURCE_CARD_DUPLEX)
8107 && s->s_params.format != SANE_FRAME_JPEG
8108 && s->duplex_interlace == DUPLEX_INTERLACE_ALT
8109 ){
8110
8111 /* buffer front side */
8112 ret = read_from_scanner(s, SIDE_FRONT);
8113 if(ret){
8114 DBG(5,"sane_read: front returning %d\n",ret);
8115 return ret;
8116 }
8117
8118 /* buffer back side, but don't get too far ahead of the front! */
8119 if(s->bytes_rx[SIDE_BACK] < s->bytes_rx[SIDE_FRONT] + s->buffer_size){
8120 ret = read_from_scanner(s, SIDE_BACK);
8121 if(ret){
8122 DBG(5,"sane_read: back returning %d\n",ret);
8123 return ret;
8124 }
8125 }
8126 } /* end alt pnm */
8127
8128 /* simplex or non-alternating duplex */
8129 else{
8130 ret = read_from_scanner(s, s->side);
8131 if(ret){
8132 DBG(5,"sane_read: side %d returning %d\n",s->side,ret);
8133 return ret;
8134 }
8135 } /*end simplex*/
8136
8137 /* uncommon case, downsample and copy a block from buffer to frontend */
8138 if(must_downsample(s)){
8139 ret = downsample_from_buffer(s,buf,max_len,len,s->side);
8140 }
8141
8142 /* common case, memcpy a block from buffer to frontend */
8143 else{
8144 ret = read_from_buffer(s,buf,max_len,len,s->side);
8145 }
8146
8147 /*finished sending small buffer, reset it*/
8148 if(s->buff_tx[s->side] == s->buff_rx[s->side]
8149 && s->buff_tot[s->side] < s->bytes_tot[s->side]
8150 ){
8151 DBG (15, "sane_read: reset buffers\n");
8152 s->buff_rx[s->side] = 0;
8153 s->buff_tx[s->side] = 0;
8154 }
8155
8156 /* check if user cancelled during this read */
8157 ret = check_for_cancel(s);
8158
8159 /* swap sides if user asked for low-mem mode, we are duplexing,
8160 * and there is data waiting on the other side */
8161 if(s->low_mem
8162 && (s->source == SOURCE_ADF_DUPLEX || s->source == SOURCE_CARD_DUPLEX)
8163 && (s->bytes_rx[!s->side] > s->bytes_tx[!s->side]
8164 || (s->eof_rx[!s->side] && !s->eof_tx[!s->side])
8165 )
8166 ){
8167 s->side = !s->side;
8168 }
8169
8170 /* unprotect this block from sane_cancel */
8171 s->reading = 0;
8172
8173 DBG (10, "sane_read: finish %d\n", ret);
8174 return ret;
8175 }
8176
8177 /* bare jpeg images don't contain resolution, but JFIF APP0 does, so we add */
8178 static SANE_Status
inject_jfif_header(struct fujitsu *s, int side)8179 inject_jfif_header(struct fujitsu *s, int side)
8180 {
8181 SANE_Status ret=SANE_STATUS_GOOD;
8182
8183 unsigned char out[] = {
8184 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46,
8185 0x00, 0x01, 0x02, 0x01, 0x00, 0x48, 0x00, 0x48,
8186 0x00, 0x00
8187 };
8188 size_t outLen=JFIF_APP0_LENGTH;
8189
8190 DBG (10, "inject_jfif_header: start %d\n", side);
8191
8192 putnbyte(out + 12, s->resolution_x, 2);
8193 putnbyte(out + 14, s->resolution_y, 2);
8194
8195 memcpy(s->buffers[side]+s->buff_rx[side], out, outLen);
8196 s->buff_rx[side] += outLen;
8197 s->bytes_rx[side] += outLen;
8198
8199 DBG (10, "inject_jfif_header: finish %d\n", ret);
8200
8201 return ret;
8202 }
8203
8204 static SANE_Status
read_from_JPEGduplex(struct fujitsu *s)8205 read_from_JPEGduplex(struct fujitsu *s)
8206 {
8207 SANE_Status ret=SANE_STATUS_GOOD;
8208
8209 unsigned char cmd[READ_len];
8210 size_t cmdLen = READ_len;
8211
8212 unsigned char * in;
8213 size_t inLen = 0;
8214
8215 int bytes = s->buffer_size;
8216 int i = 0;
8217
8218 DBG (10, "read_from_JPEGduplex: start\n");
8219
8220 if(s->eof_rx[SIDE_FRONT] && s->eof_rx[SIDE_BACK]){
8221 DBG (10, "read_from_JPEGduplex: already have eofs, done\n");
8222 return ret;
8223 }
8224
8225 /* we don't know if the following read will give us front or back data
8226 * so we only get enough to fill whichever is smaller (and not yet done) */
8227 if(!s->eof_rx[SIDE_FRONT]){
8228 int avail = s->buff_tot[SIDE_FRONT] - s->buff_rx[SIDE_FRONT];
8229 if(bytes > avail){
8230 bytes = avail;
8231 }
8232 }
8233 if(!s->eof_rx[SIDE_BACK]){
8234 int avail = s->buff_tot[SIDE_BACK] - s->buff_rx[SIDE_BACK];
8235 if(bytes > avail){
8236 bytes = avail;
8237 }
8238 }
8239
8240 /* leave space for JFIF header in the small front side buffer,
8241 * if we are at the beginning of the image */
8242 if(s->bytes_rx[SIDE_FRONT] < 3){
8243 bytes -= JFIF_APP0_LENGTH;
8244 }
8245
8246 DBG(15, "read_from_JPEGduplex: fto:%d frx:%d bto:%d brx:%d pa:%d\n",
8247 s->bytes_tot[SIDE_FRONT], s->bytes_rx[SIDE_FRONT],
8248 s->bytes_tot[SIDE_BACK], s->bytes_rx[SIDE_BACK],
8249 bytes);
8250
8251 /* this will happen if buffer is not drained yet */
8252 if(bytes < 1){
8253 DBG(5, "read_from_JPEGduplex: Warning: no bytes this pass\n");
8254 return ret;
8255 }
8256
8257 /* fi-6770A gets mad if you 'read' too soon on usb, see if it is ready */
8258 if(!s->bytes_rx[SIDE_FRONT] && s->connection == CONNECTION_USB){
8259 DBG (15, "read: start of usb page, checking RIC\n");
8260 ret = scanner_control_ric(s,bytes,SIDE_FRONT);
8261 if(ret){
8262 DBG(5,"read: ric returning %d\n",ret);
8263 return ret;
8264 }
8265 }
8266
8267 inLen = bytes;
8268 in = malloc(inLen);
8269 if(!in){
8270 DBG(5, "read_from_JPEGduplex: not enough mem for buffer: %d\n",(int)inLen);
8271 return SANE_STATUS_NO_MEM;
8272 }
8273
8274 memset(cmd,0,cmdLen);
8275 set_SCSI_opcode(cmd, READ_code);
8276 set_R_datatype_code (cmd, R_datatype_imagedata);
8277 /* interlaced jpeg duplex always reads from front */
8278 set_R_window_id (cmd, WD_wid_front);
8279 set_R_xfer_length (cmd, inLen);
8280
8281 ret = do_cmd (
8282 s, 1, 0,
8283 cmd, cmdLen,
8284 NULL, 0,
8285 in, &inLen
8286 );
8287
8288 if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) {
8289 DBG(15, "read_from_JPEGduplex: got GOOD/EOF, returning GOOD\n");
8290 }
8291 else if (ret == SANE_STATUS_DEVICE_BUSY) {
8292 DBG(5, "read_from_JPEGduplex: got BUSY, returning GOOD\n");
8293 inLen = 0;
8294 ret = SANE_STATUS_GOOD;
8295 }
8296 else {
8297 DBG(5, "read_from_JPEGduplex: error reading data status = %d\n", ret);
8298 inLen = 0;
8299 }
8300
8301 for(i=0;i<(int)inLen;i++){
8302
8303 /* about to change stage */
8304 if(in[i] == 0xff && s->jpeg_ff_offset != 0){
8305 s->jpeg_ff_offset=0;
8306 continue;
8307 }
8308
8309 /* last byte was an ff, this byte will change stage */
8310 if(s->jpeg_ff_offset == 0){
8311
8312 /* first marker after SOI is not APP0, add one */
8313 if(s->jpeg_stage == JPEG_STAGE_SOI && in[i] != 0xe0){
8314 inject_jfif_header(s,SIDE_FRONT);
8315 inject_jfif_header(s,SIDE_BACK);
8316 s->jpeg_stage = JPEG_STAGE_HEAD;
8317 }
8318
8319 /* SOI header, in both sides */
8320 if(in[i] == 0xd8){
8321 s->jpeg_stage = JPEG_STAGE_SOI;
8322 DBG(15, "read_from_JPEGduplex: stage SOI\n");
8323 }
8324
8325 /* headers (HuffTab/QTab/DRI), in both sides */
8326 else if(in[i] == 0xc4 || in[i] == 0xdb || in[i] == 0xdd){
8327 s->jpeg_stage = JPEG_STAGE_HEAD;
8328 DBG(15, "read_from_JPEGduplex: stage head\n");
8329 }
8330
8331 /* start of frame, in both sides, update x first */
8332 else if(in[i]==0xc0){
8333 s->jpeg_stage = JPEG_STAGE_SOF;
8334 DBG(15, "read_from_JPEGduplex: stage sof\n");
8335 }
8336
8337 /* start of scan, first few bytes of marker in both sides
8338 * but rest in front */
8339 else if(in[i]==0xda){
8340 s->jpeg_stage = JPEG_STAGE_SOS;
8341 DBG(15, "read_from_JPEGduplex: stage sos\n");
8342 }
8343
8344 /* found image block. images are not interlaced */
8345 /* copy to front, don't change RST */
8346 else if(in[i] >= 0xd0 && in[i] <= 0xd7
8347 && s->jpeg_interlace == JPEG_INTERLACE_NONE){
8348 s->jpeg_stage = JPEG_STAGE_FRONT;
8349 DBG(35, "read_from_JPEGduplex: stage front (all)\n");
8350 }
8351
8352 /* found even numbered image block. */
8353 /* images are interlaced, so switch to back. */
8354 /* also change from even RST to proper one */
8355 else if(in[i] == 0xd0 || in[i] == 0xd2
8356 || in[i] == 0xd4 || in[i] == 0xd6){
8357 s->jpeg_stage = JPEG_STAGE_BACK;
8358 DBG(35, "read_from_JPEGduplex: stage back\n");
8359
8360 /* skip first RST for back side*/
8361 if(!s->jpeg_back_rst){
8362 DBG(15, "read_from_JPEGduplex: stage back jump\n");
8363 s->jpeg_ff_offset++;
8364 s->jpeg_back_rst++;
8365 continue;
8366 }
8367
8368 in[i] = 0xd0 + (s->jpeg_back_rst-1) % 8;
8369 s->jpeg_back_rst++;
8370 }
8371
8372 /* finished back image block, switch to front */
8373 /* also change from odd RST to proper one */
8374 else if(in[i] == 0xd1 || in[i] == 0xd3
8375 || in[i] == 0xd5 || in[i] == 0xd7){
8376 s->jpeg_stage = JPEG_STAGE_FRONT;
8377 DBG(35, "read_from_JPEGduplex: stage front\n");
8378 in[i] = 0xd0 + (s->jpeg_front_rst % 8);
8379 s->jpeg_front_rst++;
8380 }
8381
8382 /* finished image, update totals */
8383 else if(in[i]==0xd9){
8384 s->jpeg_stage = JPEG_STAGE_EOI;
8385 DBG(15, "read_from_JPEGduplex: stage eoi %d %d\n",(int)inLen,i);
8386 }
8387
8388 /* unknown, warn */
8389 else if(in[i] != 0x00){
8390 DBG(15, "read_from_JPEGduplex: unknown %02x\n", in[i]);
8391 }
8392 }
8393 s->jpeg_ff_offset++;
8394
8395 /* first x byte in start of frame, buffer it */
8396 if(s->jpeg_stage == JPEG_STAGE_SOF && s->jpeg_ff_offset == 7){
8397 s->jpeg_x_byte = in[i];
8398 continue;
8399 }
8400
8401 /* second x byte in start of frame */
8402 if(s->jpeg_stage == JPEG_STAGE_SOF && s->jpeg_ff_offset == 8){
8403
8404 int width = (s->jpeg_x_byte << 8) | in[i];
8405
8406 /* if image width equals what we asked for, then
8407 * the image is not interlaced, clean up the mess */
8408 if(width == s->s_params.pixels_per_line){
8409
8410 DBG(15, "read_from_JPEGduplex: right width, req:%d got:%d\n",
8411 s->s_params.pixels_per_line,width);
8412
8413 /* stop copying to the back */
8414 s->jpeg_interlace = JPEG_INTERLACE_NONE;
8415
8416 /* clear what is already in the back */
8417 s->bytes_rx[SIDE_BACK]=0;
8418 s->lines_rx[SIDE_BACK]=0;
8419 s->buff_rx[SIDE_BACK]=0;
8420
8421 /* and put the high-order width byte into front unchanged */
8422 s->buffers[SIDE_FRONT][s->buff_rx[SIDE_FRONT]++] = s->jpeg_x_byte;
8423 s->bytes_rx[SIDE_FRONT]++;
8424 }
8425
8426 /* image is interlaced after all, continue */
8427 else{
8428 DBG(15, "read_from_JPEGduplex: wrong width, req:%d got:%d\n",
8429 s->s_params.pixels_per_line,width);
8430
8431 /* put the high-order width byte into front side, shifted down */
8432 s->buffers[SIDE_FRONT][s->buff_rx[SIDE_FRONT]++] = width >> 9;
8433 s->bytes_rx[SIDE_FRONT]++;
8434
8435 /* put the high-order width byte into back side, shifted down */
8436 s->buffers[SIDE_BACK][s->buff_rx[SIDE_BACK]++] = width >> 9;
8437 s->bytes_rx[SIDE_BACK]++;
8438
8439 /* shift down low order byte */
8440 in[i] = (width >> 1) & 0xff;
8441 }
8442 }
8443
8444 /* copy these stages to front */
8445 if(s->jpeg_stage == JPEG_STAGE_SOI
8446 || s->jpeg_stage == JPEG_STAGE_HEAD
8447 || s->jpeg_stage == JPEG_STAGE_SOF
8448 || s->jpeg_stage == JPEG_STAGE_SOS
8449 || s->jpeg_stage == JPEG_STAGE_EOI
8450 || s->jpeg_stage == JPEG_STAGE_FRONT
8451 ){
8452 /* first byte after ff, send the ff first */
8453 if(s->jpeg_ff_offset == 1){
8454 s->buffers[SIDE_FRONT][s->buff_rx[SIDE_FRONT]++] = 0xff;
8455 s->bytes_rx[SIDE_FRONT]++;
8456 }
8457 s->buffers[SIDE_FRONT][s->buff_rx[SIDE_FRONT]++] = in[i];
8458 s->bytes_rx[SIDE_FRONT]++;
8459 }
8460
8461 /* copy these stages to back */
8462 if( s->jpeg_interlace == JPEG_INTERLACE_ALT
8463 &&
8464 ( s->jpeg_stage == JPEG_STAGE_SOI
8465 || s->jpeg_stage == JPEG_STAGE_HEAD
8466 || s->jpeg_stage == JPEG_STAGE_SOF
8467 || s->jpeg_stage == JPEG_STAGE_SOS
8468 || s->jpeg_stage == JPEG_STAGE_EOI
8469 || s->jpeg_stage == JPEG_STAGE_BACK )
8470 ){
8471 /* first byte after ff, send the ff first */
8472 if(s->jpeg_ff_offset == 1){
8473 s->buffers[SIDE_BACK][s->buff_rx[SIDE_BACK]++] = 0xff;
8474 s->bytes_rx[SIDE_BACK]++;
8475 }
8476 s->buffers[SIDE_BACK][s->buff_rx[SIDE_BACK]++] = in[i];
8477 s->bytes_rx[SIDE_BACK]++;
8478 }
8479
8480 /* reached last byte of SOS section, next byte front */
8481 if(s->jpeg_stage == JPEG_STAGE_SOS && s->jpeg_ff_offset == 0x0d){
8482 s->jpeg_stage = JPEG_STAGE_FRONT;
8483 }
8484
8485 /* last byte of file, update totals, bail out */
8486 if(s->jpeg_stage == JPEG_STAGE_EOI){
8487 s->eof_rx[SIDE_FRONT] = 1;
8488 if(s->jpeg_interlace == JPEG_INTERLACE_ALT)
8489 s->eof_rx[SIDE_BACK] = 1;
8490 }
8491 }
8492
8493 free(in);
8494
8495 /* jpeg uses in-band EOI marker, so this is usually redundant */
8496 if(ret == SANE_STATUS_EOF){
8497 DBG(15, "read_from_JPEGduplex: got EOF, finishing\n");
8498 s->eof_rx[SIDE_FRONT] = 1;
8499 if(s->jpeg_interlace == JPEG_INTERLACE_ALT)
8500 s->eof_rx[SIDE_BACK] = 1;
8501 ret = SANE_STATUS_GOOD;
8502 }
8503
8504 DBG (10, "read_from_JPEGduplex: finish\n");
8505
8506 return ret;
8507 }
8508
8509 static SANE_Status
read_from_3091duplex(struct fujitsu *s)8510 read_from_3091duplex(struct fujitsu *s)
8511 {
8512 SANE_Status ret=SANE_STATUS_GOOD;
8513
8514 unsigned char cmd[READ_len];
8515 size_t cmdLen = READ_len;
8516
8517 unsigned char * in;
8518 size_t inLen = 0;
8519
8520 int side = SIDE_FRONT;
8521 int bytes = s->buffer_size;
8522 int off = (s->duplex_raster_offset+s->duplex_offset) * s->resolution_y/300;
8523 unsigned int i;
8524
8525 DBG (10, "read_from_3091duplex: start\n");
8526
8527 if(s->eof_rx[SIDE_FRONT] && s->eof_rx[SIDE_BACK]){
8528 DBG (10, "read_from_3091duplex: already have eofs, done\n");
8529 return ret;
8530 }
8531
8532 /* we don't know if the following read will give us front,back or both data
8533 * so we only get enough to fill whichever is smaller (and not yet done) */
8534 if(!s->eof_rx[SIDE_FRONT]){
8535 int avail = s->buff_tot[SIDE_FRONT] - s->buff_rx[SIDE_FRONT];
8536 if(bytes > avail)
8537 bytes = avail;
8538 }
8539 if(!s->eof_rx[SIDE_BACK]){
8540 int avail = s->buff_tot[SIDE_BACK] - s->buff_rx[SIDE_BACK];
8541 if(bytes > avail)
8542 bytes = avail;
8543 }
8544
8545 /* all requests must end on a line boundary */
8546 bytes -= (bytes % s->s_params.bytes_per_line);
8547
8548 DBG(15, "read_from_3091duplex: front img: to:%d rx:%d tx:%d li:%d\n",
8549 s->bytes_tot[SIDE_FRONT], s->bytes_rx[SIDE_FRONT],
8550 s->bytes_tx[SIDE_FRONT], s->lines_rx[SIDE_FRONT]);
8551
8552 DBG(15, "read_from_3091duplex: front buf: to:%d rx:%d tx:%d\n",
8553 s->buff_tot[SIDE_FRONT], s->buff_rx[SIDE_FRONT],
8554 s->buff_tx[SIDE_FRONT]);
8555
8556 DBG(15, "read_from_3091duplex: back img: to:%d rx:%d tx:%d li:%d\n",
8557 s->bytes_tot[SIDE_BACK], s->bytes_rx[SIDE_BACK],
8558 s->bytes_tx[SIDE_BACK], s->lines_rx[SIDE_BACK]);
8559
8560 DBG(15, "read_from_3091duplex: back buf: to:%d rx:%d tx:%d\n",
8561 s->buff_tot[SIDE_BACK], s->buff_rx[SIDE_BACK],
8562 s->buff_tx[SIDE_BACK]);
8563
8564 DBG(15, "read_from_3091duplex: bu:%d pa:%d of:%d\n",
8565 s->buffer_size, bytes, off);
8566
8567 /* this could happen if the front buffer is not drained fast enough */
8568 if(bytes < 1){
8569 DBG(10, "read_from_3091duplex: Warning: no bytes this pass\n");
8570 return ret;
8571 }
8572
8573 inLen = bytes;
8574
8575 in = malloc(inLen);
8576 if(!in){
8577 DBG(5, "read_from_3091duplex: not enough mem for buffer: %d\n",(int)inLen);
8578 return SANE_STATUS_NO_MEM;
8579 }
8580
8581 memset(cmd,0,cmdLen);
8582 set_SCSI_opcode(cmd, READ_code);
8583 set_R_datatype_code (cmd, R_datatype_imagedata);
8584 /* 3091 duplex always reads from front */
8585 set_R_window_id (cmd, WD_wid_front);
8586 set_R_xfer_length (cmd, inLen);
8587
8588 ret = do_cmd (
8589 s, 1, 0,
8590 cmd, cmdLen,
8591 NULL, 0,
8592 in, &inLen
8593 );
8594
8595 if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) {
8596 DBG(15, "read_from_3091duplex: got GOOD/EOF, returning GOOD\n");
8597 }
8598 else if (ret == SANE_STATUS_DEVICE_BUSY) {
8599 DBG(5, "read_from_3091duplex: got BUSY, returning GOOD\n");
8600 inLen = 0;
8601 ret = SANE_STATUS_GOOD;
8602 }
8603 else {
8604 DBG(5, "read_from_3091duplex: error reading data block status = %d\n", ret);
8605 inLen = 0;
8606 }
8607
8608 /* loop thru all lines in read buffer */
8609 for(i=0;i<inLen/s->s_params.bytes_per_line;i++){
8610
8611 /* start is front */
8612 if(s->lines_rx[SIDE_FRONT] < off){
8613 side=SIDE_FRONT;
8614 }
8615
8616 /* end is back */
8617 else if(s->eof_rx[SIDE_FRONT]){
8618 side=SIDE_BACK;
8619 }
8620
8621 /* odd are back */
8622 else if( ((s->lines_rx[SIDE_FRONT] + s->lines_rx[SIDE_BACK] - off) % 2) ){
8623 side=SIDE_BACK;
8624 }
8625
8626 /* even are front */
8627 else{
8628 side=SIDE_FRONT;
8629 }
8630
8631 if(s->s_mode == MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091){
8632 copy_3091 (s, in + i*s->s_params.bytes_per_line, s->s_params.bytes_per_line, side);
8633 }
8634 else{
8635 copy_buffer (s, in + i*s->s_params.bytes_per_line, s->s_params.bytes_per_line, side);
8636 }
8637 }
8638
8639 if(ret == SANE_STATUS_EOF){
8640 DBG(15, "read_from_3091duplex: got EOF, finishing both sides\n");
8641 s->eof_rx[SIDE_FRONT] = 1;
8642 s->eof_rx[SIDE_BACK] = 1;
8643 ret = SANE_STATUS_GOOD;
8644 }
8645
8646 free(in);
8647
8648 DBG (10, "read_from_3091duplex: finish\n");
8649
8650 return ret;
8651 }
8652
8653 static SANE_Status
read_from_scanner(struct fujitsu *s, int side)8654 read_from_scanner(struct fujitsu *s, int side)
8655 {
8656 SANE_Status ret=SANE_STATUS_GOOD;
8657
8658 unsigned char cmd[READ_len];
8659 size_t cmdLen = READ_len;
8660
8661 unsigned char * in;
8662 size_t inLen = 0;
8663
8664 int bytes = s->buffer_size;
8665 int avail = s->buff_tot[side] - s->buff_rx[side];
8666 int remain = s->bytes_tot[side] - s->bytes_rx[side];
8667
8668 DBG (10, "read_from_scanner: start %d\n", side);
8669
8670 if(s->eof_rx[side]){
8671 DBG (10, "read_from_scanner: already have eof, done\n");
8672 return ret;
8673 }
8674
8675 /* figure out the max amount to transfer */
8676 if(bytes > avail)
8677 bytes = avail;
8678
8679 /* all requests must end on line boundary */
8680 bytes -= (bytes % s->s_params.bytes_per_line);
8681
8682 /* some larger scanners require even bytes per block */
8683 /* so we get even lines, but not on the last block */
8684 /* cause odd number of lines would never finish */
8685 if(bytes % 2 && bytes < remain){
8686 bytes -= s->s_params.bytes_per_line;
8687 }
8688
8689 /* jpeg scans leave space for JFIF header at start of image */
8690 if(s->s_params.format == SANE_FRAME_JPEG && s->bytes_rx[side] < 2)
8691 bytes -= JFIF_APP0_LENGTH;
8692
8693 DBG(15, "read_from_scanner: si:%d re:%d bs:%d by:%d av:%d\n",
8694 side, remain, s->buffer_size, bytes, avail);
8695
8696 DBG(15, "read_from_scanner: img to:%d rx:%d tx:%d li:%d\n",
8697 s->bytes_tot[side], s->bytes_rx[side], s->bytes_tx[side],
8698 s->lines_rx[side]);
8699
8700 DBG(15, "read_from_scanner: buf to:%d rx:%d tx:%d\n",
8701 s->buff_tot[side], s->buff_rx[side], s->buff_tx[side]);
8702
8703 /* this will happen if buffer is not drained yet */
8704 if(bytes < 1){
8705 DBG(5, "read_from_scanner: no bytes this pass\n");
8706 return ret;
8707 }
8708
8709 /* fi-6770A gets mad if you 'read' too soon on usb, see if it is ready */
8710 if(!s->bytes_rx[side] && s->connection == CONNECTION_USB){
8711 DBG (15, "read_from_scanner: start of usb page, checking RIC\n");
8712 ret = scanner_control_ric(s,bytes,side);
8713 if(ret){
8714 DBG(5,"read_from_scanner: ric returning %d\n",ret);
8715 return ret;
8716 }
8717 }
8718
8719 inLen = bytes;
8720 in = malloc(inLen);
8721 if(!in){
8722 DBG(5, "read_from_scanner: not enough mem for buffer: %d\n",(int)inLen);
8723 return SANE_STATUS_NO_MEM;
8724 }
8725
8726 memset(cmd,0,cmdLen);
8727 set_SCSI_opcode(cmd, READ_code);
8728 set_R_datatype_code (cmd, R_datatype_imagedata);
8729
8730 if (side == SIDE_BACK) {
8731 set_R_window_id (cmd, WD_wid_back);
8732 }
8733 else{
8734 set_R_window_id (cmd, WD_wid_front);
8735 }
8736
8737 set_R_xfer_length (cmd, inLen);
8738
8739 ret = do_cmd (
8740 s, 1, 0,
8741 cmd, cmdLen,
8742 NULL, 0,
8743 in, &inLen
8744 );
8745
8746 if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) {
8747 DBG(15, "read_from_scanner: got GOOD/EOF, returning GOOD\n");
8748 ret = SANE_STATUS_GOOD;
8749 }
8750 else if (ret == SANE_STATUS_DEVICE_BUSY) {
8751 DBG(5, "read_from_scanner: got BUSY, returning GOOD\n");
8752 inLen = 0;
8753 ret = SANE_STATUS_GOOD;
8754 }
8755 else {
8756 DBG(5, "read_from_scanner: error reading data block status = %d\n",ret);
8757 inLen = 0;
8758 }
8759
8760 DBG(15, "read_from_scanner: read %lu bytes\n",(unsigned long)inLen);
8761
8762 if(inLen){
8763 if(s->s_mode==MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091){
8764 copy_3091 (s, in, inLen, side);
8765 }
8766 else if(s->s_params.format == SANE_FRAME_JPEG){
8767 copy_JPEG (s, in, inLen, side);
8768 }
8769 else{
8770 copy_buffer (s, in, inLen, side);
8771 }
8772 }
8773
8774 free(in);
8775
8776 /* if this was a short read or not, log it */
8777 s->ili_rx[side] = s->rs_ili;
8778 if(s->ili_rx[side]){
8779 DBG(15, "read_from_scanner: got ILI\n");
8780 }
8781
8782 /* if this was an end of medium, log it */
8783 if(s->rs_eom){
8784 DBG(15, "read_from_scanner: got EOM\n");
8785 s->eom_rx = 1;
8786 }
8787
8788 /* paper ran out. lets try to set the eof flag on both sides,
8789 * but only if that side had a short read last time */
8790 if(s->eom_rx){
8791 int i;
8792 for(i=0;i<2;i++){
8793 if(s->ili_rx[i]){
8794 DBG(15, "read_from_scanner: finishing side %d\n",i);
8795 s->eof_rx[i] = 1;
8796 }
8797 }
8798 }
8799
8800 DBG (10, "read_from_scanner: finish\n");
8801
8802 return ret;
8803 }
8804
8805 static SANE_Status
copy_3091(struct fujitsu *s, unsigned char * buf, int len, int side)8806 copy_3091(struct fujitsu *s, unsigned char * buf, int len, int side)
8807 {
8808 SANE_Status ret=SANE_STATUS_GOOD;
8809 int i, j, dest, boff, goff;
8810
8811 DBG (10, "copy_3091: start\n");
8812
8813 /* Data is RR...GG...BB... on each line,
8814 * green is back 8 lines from red at 300 dpi
8815 * blue is back 4 lines from red at 300 dpi.
8816 *
8817 * Here, we get things on correct line, and
8818 * interlace to make RGBRGB.
8819 *
8820 * We add the user-supplied offsets before we scale
8821 * so that they are independent of scanning resolution.
8822 */
8823 goff = (s->color_raster_offset+s->green_offset) * s->resolution_y/150;
8824 boff = (s->color_raster_offset+s->blue_offset) * s->resolution_y/300;
8825
8826 /* loop thru all lines in read buffer */
8827 for(i=0;i<len;i+=s->s_params.bytes_per_line){
8828
8829 /* red at start of line */
8830 dest = s->lines_rx[side] * s->s_params.bytes_per_line;
8831
8832 if(dest >= 0 && dest < s->bytes_tot[side]){
8833 for (j=0; j<s->s_params.pixels_per_line; j++){
8834 s->buffers[side][dest+j*3] = buf[i+j];
8835 }
8836 }
8837
8838 /* green is in middle of line */
8839 dest = (s->lines_rx[side] - goff) * s->s_params.bytes_per_line;
8840
8841 if(dest >= 0 && dest < s->bytes_tot[side]){
8842 for (j=0; j<s->s_params.pixels_per_line; j++){
8843 s->buffers[side][dest+j*3+1] = buf[i+s->s_params.pixels_per_line+j];
8844 }
8845 }
8846
8847 /* blue is at end of line */
8848 dest = (s->lines_rx[side] - boff) * s->s_params.bytes_per_line;
8849
8850 if(dest >= 0 && dest < s->bytes_tot[side]){
8851 for (j=0; j<s->s_params.pixels_per_line; j++){
8852 s->buffers[side][dest+j*3+2] = buf[i+2*s->s_params.pixels_per_line+j];
8853 }
8854 }
8855
8856 s->lines_rx[side]++;
8857 }
8858
8859 /* even if we have read data, we may not have any
8860 * full lines loaded yet, so we may have to lie */
8861 i = (s->lines_rx[side]-goff) * s->s_params.bytes_per_line;
8862 if(i < 0){
8863 i = 0;
8864 }
8865 s->bytes_rx[side] = i;
8866 s->buff_rx[side] = i;
8867
8868 if(s->bytes_rx[side] == s->bytes_tot[side]){
8869 s->eof_rx[side] = 1;
8870 }
8871
8872 DBG(15, "copy_3091: si:%d imgrx:%d bufrx:%d li:%d eof:%d\n",
8873 side, s->bytes_rx[side], s->buff_rx[side], s->lines_rx[side],
8874 s->eof_rx[side]);
8875
8876 DBG (10, "copy_3091: finish\n");
8877
8878 return ret;
8879 }
8880
8881 static SANE_Status
copy_JPEG(struct fujitsu *s, unsigned char * buf, int len, int side)8882 copy_JPEG(struct fujitsu *s, unsigned char * buf, int len, int side)
8883 {
8884 SANE_Status ret=SANE_STATUS_GOOD;
8885 int i, seen = 0;
8886
8887 DBG (10, "copy_JPEG: start\n");
8888
8889 /* A jpeg image starts with the SOI marker, FF D8.
8890 * This is optionally followed by the JFIF APP0
8891 * marker, FF E0. If that marker is not present,
8892 * we add it, so we can insert the resolution */
8893
8894 if(!s->bytes_rx[side] && len >= 4
8895 && buf[0] == 0xFF && buf[1] == 0xD8
8896 && buf[2] == 0xFF && buf[3] != 0xE0
8897 ){
8898 /* SOI marker */
8899 for (i=0; i<2; i++){
8900 s->buffers[side][s->buff_rx[side]++] = buf[i];
8901 s->bytes_rx[side]++;
8902 seen++;
8903 }
8904
8905 /* JFIF header after SOI */
8906 inject_jfif_header(s,side);
8907 }
8908
8909 memcpy(s->buffers[side]+s->buff_rx[side],buf+seen,len-seen);
8910 s->buff_rx[side] += len-seen;
8911 s->bytes_rx[side] += len-seen;
8912
8913 /* should never happen with jpeg */
8914 if(s->bytes_rx[side] == s->bytes_tot[side]){
8915 s->eof_rx[side] = 1;
8916 }
8917
8918 DBG (10, "copy_JPEG: finish\n");
8919
8920 return ret;
8921 }
8922
8923 static SANE_Status
copy_buffer(struct fujitsu *s, unsigned char * buf, int len, int side)8924 copy_buffer(struct fujitsu *s, unsigned char * buf, int len, int side)
8925 {
8926 SANE_Status ret=SANE_STATUS_GOOD;
8927 int i, j;
8928 int bwidth = s->s_params.bytes_per_line;
8929 int pwidth = s->s_params.pixels_per_line;
8930
8931 DBG (10, "copy_buffer: start\n");
8932
8933 /* invert image if scanner needs it for this mode */
8934 /* jpeg data does not use inverting */
8935 if(s->s_params.format != SANE_FRAME_JPEG && s->reverse_by_mode[s->s_mode]){
8936 for(i=0; i<len; i++){
8937 buf[i] ^= 0xff;
8938 }
8939 }
8940
8941 /* scanners interlace colors in many different ways */
8942 if(s->s_params.format == SANE_FRAME_RGB){
8943
8944 switch (s->color_interlace) {
8945
8946 /* scanner returns pixel data as bgrbgr... */
8947 case COLOR_INTERLACE_BGR:
8948 for(i=0; i<len; i+=bwidth){
8949 for (j=0; j<pwidth; j++){
8950 s->buffers[side][s->buff_rx[side]++] = buf[i+j*3+2];
8951 s->buffers[side][s->buff_rx[side]++] = buf[i+j*3+1];
8952 s->buffers[side][s->buff_rx[side]++] = buf[i+j*3];
8953 }
8954 }
8955 break;
8956
8957 /* one line has the following format: rrr...rrrggg...gggbbb...bbb */
8958 case COLOR_INTERLACE_RRGGBB:
8959 for(i=0; i<len; i+=bwidth){
8960 for (j=0; j<pwidth; j++){
8961 s->buffers[side][s->buff_rx[side]++] = buf[i+j];
8962 s->buffers[side][s->buff_rx[side]++] = buf[i+pwidth+j];
8963 s->buffers[side][s->buff_rx[side]++] = buf[i+2*pwidth+j];
8964 }
8965 }
8966 break;
8967
8968 default:
8969 memcpy(s->buffers[side]+s->buff_rx[side],buf,len);
8970 s->buff_rx[side] += len;
8971 break;
8972 }
8973 }
8974
8975 /* jpeg/gray/ht/binary */
8976 else{
8977 memcpy(s->buffers[side]+s->buff_rx[side],buf,len);
8978 s->buff_rx[side] += len;
8979 }
8980
8981 s->bytes_rx[side] += len;
8982 s->lines_rx[side] += len/s->s_params.bytes_per_line;
8983
8984 if(s->bytes_rx[side] == s->bytes_tot[side]){
8985 s->eof_rx[side] = 1;
8986 }
8987
8988 DBG (10, "copy_buffer: finish\n");
8989
8990 return ret;
8991 }
8992
8993 static SANE_Status
read_from_buffer(struct fujitsu *s, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len, int side)8994 read_from_buffer(struct fujitsu *s, SANE_Byte * buf,
8995 SANE_Int max_len, SANE_Int * len, int side)
8996 {
8997 SANE_Status ret=SANE_STATUS_GOOD;
8998 int bytes = max_len;
8999 int remain = s->buff_rx[side] - s->buff_tx[side];
9000
9001 DBG (10, "read_from_buffer: start\n");
9002
9003 /* figure out the max amount to transfer */
9004 if(bytes > remain){
9005 bytes = remain;
9006 }
9007
9008 *len = bytes;
9009
9010 DBG(15, "read_from_buffer: si:%d re:%d ml:%d by:%d\n",
9011 side, remain, max_len, bytes);
9012
9013 DBG(15, "read_from_buffer: img to:%d rx:%d tx:%d\n",
9014 s->bytes_tot[side], s->bytes_rx[side], s->bytes_tx[side]);
9015
9016 DBG(15, "read_from_buffer: buf to:%d rx:%d tx:%d\n",
9017 s->buff_tot[side], s->buff_rx[side], s->buff_tx[side]);
9018
9019 /*FIXME this needs to timeout eventually */
9020 if(!bytes){
9021 DBG(5,"read_from_buffer: nothing to do\n");
9022 return SANE_STATUS_GOOD;
9023 }
9024
9025 memcpy(buf,s->buffers[side]+s->buff_tx[side],bytes);
9026 s->buff_tx[side] += bytes;
9027 s->bytes_tx[side] += bytes;
9028
9029 DBG (10, "read_from_buffer: finish\n");
9030
9031 return ret;
9032 }
9033
9034 /* we have bytes of higher mode image data in s->buffers */
9035 /* user asked for lower mode image. downsample and copy to buf */
9036
9037 static SANE_Status
downsample_from_buffer(struct fujitsu *s, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len, int side)9038 downsample_from_buffer(struct fujitsu *s, SANE_Byte * buf,
9039 SANE_Int max_len, SANE_Int * len, int side)
9040 {
9041 SANE_Status ret=SANE_STATUS_GOOD;
9042
9043 DBG (10, "downsample_from_buffer: start %d %d %d %d\n", s->bytes_rx[side], s->bytes_tx[side], s->buff_rx[side], s->buff_tx[side]);
9044
9045 if(s->s_mode == MODE_COLOR && s->u_mode == MODE_GRAYSCALE){
9046
9047 while(*len < max_len && s->buff_rx[side] - s->buff_tx[side] >= 3){
9048
9049 int gray = 0;
9050
9051 switch (s->dropout_color) {
9052 case COLOR_RED:
9053 gray = *(s->buffers[side]+s->buff_tx[side]) * 3;
9054 break;
9055 case COLOR_GREEN:
9056 gray = *(s->buffers[side]+s->buff_tx[side]+1) * 3;
9057 break;
9058 case COLOR_BLUE:
9059 gray = *(s->buffers[side]+s->buff_tx[side]+2) * 3;
9060 break;
9061 default:
9062 gray = *(s->buffers[side]+s->buff_tx[side])
9063 + *(s->buffers[side]+s->buff_tx[side]+1)
9064 + *(s->buffers[side]+s->buff_tx[side]+2);
9065 break;
9066 }
9067
9068 /* bookkeeping for input */
9069 s->buff_tx[side] += 3;
9070 s->bytes_tx[side] += 3;
9071
9072 /* add byte to output */
9073 *(buf + *len) = gray/3;
9074 (*len)++;
9075 }
9076 }
9077
9078 else if(s->s_mode == MODE_COLOR && s->u_mode == MODE_LINEART){
9079
9080 /* threshold of 0 is actually middle of range */
9081 /*FIXME: add dynamic threshold? */
9082 unsigned char thresh = (s->threshold ? s->threshold : 127);
9083
9084 while(*len < max_len && s->buff_rx[side] - s->buff_tx[side] >= 24){
9085
9086 int i;
9087 unsigned char out = 0;
9088
9089 for(i=0; i<8; i++){
9090
9091 int gray = 0;
9092
9093 switch (s->dropout_color) {
9094 case COLOR_RED:
9095 gray = *(s->buffers[side]+s->buff_tx[side]) * 3;
9096 break;
9097 case COLOR_GREEN:
9098 gray = *(s->buffers[side]+s->buff_tx[side]+1) * 3;
9099 break;
9100 case COLOR_BLUE:
9101 gray = *(s->buffers[side]+s->buff_tx[side]+2) * 3;
9102 break;
9103 default:
9104 gray = *(s->buffers[side]+s->buff_tx[side])
9105 + *(s->buffers[side]+s->buff_tx[side]+1)
9106 + *(s->buffers[side]+s->buff_tx[side]+2);
9107 break;
9108 }
9109
9110 /* black if input gray is lower than threshold */
9111 if(gray/3 < thresh){
9112 out |= (0x80 >> i);
9113 }
9114
9115 /* bookkeeping for input */
9116 s->buff_tx[side] += 3;
9117 s->bytes_tx[side] += 3;
9118 }
9119
9120 /* add byte to output */
9121 *(buf + *len) = out;
9122 (*len)++;
9123 }
9124 }
9125
9126 else{
9127 DBG (5, "downsample_from_buffer: invalid mode combination\n");
9128 ret = SANE_STATUS_INVAL;
9129 }
9130
9131 DBG (10, "downsample_from_buffer: finish %d %d %d %d\n", s->bytes_rx[side], s->bytes_tx[side], s->buff_rx[side], s->buff_tx[side]);
9132
9133 return ret;
9134 }
9135
9136
9137 /*
9138 * @@ Section 5 - SANE cleanup functions
9139 */
9140 /*
9141 * Cancels a scan.
9142 *
9143 * It has been said on the mailing list that sane_cancel is a bit of a
9144 * misnomer because it is routinely called to signal the end of a
9145 * batch - quoting David Mosberger-Tang:
9146 *
9147 * > In other words, the idea is to have sane_start() be called, and
9148 * > collect as many images as the frontend wants (which could in turn
9149 * > consist of multiple frames each as indicated by frame-type) and
9150 * > when the frontend is done, it should call sane_cancel().
9151 * > Sometimes it's better to think of sane_cancel() as "sane_stop()"
9152 * > but that name would have had some misleading connotations as
9153 * > well, that's why we stuck with "cancel".
9154 *
9155 * The current consensus regarding duplex and ADF scans seems to be
9156 * the following call sequence: sane_start; sane_read (repeat until
9157 * EOF); sane_start; sane_read... and then call sane_cancel if the
9158 * batch is at an end. I.e. do not call sane_cancel during the run but
9159 * as soon as you get a SANE_STATUS_NO_DOCS.
9160 *
9161 * From the SANE spec:
9162 * This function is used to immediately or as quickly as possible
9163 * cancel the currently pending operation of the device represented by
9164 * handle h. This function can be called at any time (as long as
9165 * handle h is a valid handle) but usually affects long-running
9166 * operations only (such as image is acquisition). It is safe to call
9167 * this function asynchronously (e.g., from within a signal handler).
9168 * It is important to note that completion of this operation does not
9169 * imply that the currently pending operation has been cancelled. It
9170 * only guarantees that cancellation has been initiated. Cancellation
9171 * completes only when the cancelled call returns (typically with a
9172 * status value of SANE_STATUS_CANCELLED). Since the SANE API does
9173 * not require any other operations to be re-entrant, this implies
9174 * that a frontend must not call any other operation until the
9175 * cancelled operation has returned.
9176 */
9177 void
sane_cancel(SANE_Handle handle)9178 sane_cancel (SANE_Handle handle)
9179 {
9180 struct fujitsu * s = (struct fujitsu *) handle;
9181
9182 DBG (10, "sane_cancel: start\n");
9183 s->cancelled = 1;
9184
9185 /* if there is no other running function to check, we do it */
9186 if(!s->reading)
9187 check_for_cancel(s);
9188
9189 DBG (10, "sane_cancel: finish\n");
9190 }
9191
9192 /*
9193 * Ends use of the scanner.
9194 *
9195 * From the SANE spec:
9196 * This function terminates the association between the device handle
9197 * passed in argument h and the device it represents. If the device is
9198 * presently active, a call to sane_cancel() is performed first. After
9199 * this function returns, handle h must not be used anymore.
9200 */
9201 void
sane_close(SANE_Handle handle)9202 sane_close (SANE_Handle handle)
9203 {
9204 struct fujitsu * s = (struct fujitsu *) handle;
9205
9206 DBG (10, "sane_close: start\n");
9207 /*clears any held scans*/
9208 mode_select_buff(s);
9209 disconnect_fd(s);
9210 DBG (10, "sane_close: finish\n");
9211 }
9212
9213 static SANE_Status
disconnect_fd(struct fujitsu *s)9214 disconnect_fd (struct fujitsu *s)
9215 {
9216 DBG (10, "disconnect_fd: start\n");
9217
9218 if(s->fd > -1){
9219 if (s->connection == CONNECTION_USB) {
9220 DBG (15, "disconnecting usb device\n");
9221 sanei_usb_close (s->fd);
9222 }
9223 else if (s->connection == CONNECTION_SCSI) {
9224 DBG (15, "disconnecting scsi device\n");
9225 sanei_scsi_close (s->fd);
9226 }
9227 s->fd = -1;
9228 }
9229
9230 DBG (10, "disconnect_fd: finish\n");
9231
9232 return SANE_STATUS_GOOD;
9233 }
9234
9235 /*
9236 * Terminates the backend.
9237 *
9238 * From the SANE spec:
9239 * This function must be called to terminate use of a backend. The
9240 * function will first close all device handles that still might be
9241 * open (it is recommended to close device handles explicitly through
9242 * a call to sane_close(), but backends are required to release all
9243 * resources upon a call to this function). After this function
9244 * returns, no function other than sane_init() may be called
9245 * (regardless of the status value returned by sane_exit(). Neglecting
9246 * to call this function may result in some resources not being
9247 * released properly.
9248 */
9249 void
sane_exit(void)9250 sane_exit (void)
9251 {
9252 struct fujitsu *dev, *next;
9253
9254 DBG (10, "sane_exit: start\n");
9255
9256 for (dev = fujitsu_devList; dev; dev = next) {
9257 disconnect_fd(dev);
9258 next = dev->next;
9259 free (dev);
9260 }
9261
9262 if (sane_devArray)
9263 free (sane_devArray);
9264
9265 fujitsu_devList = NULL;
9266 sane_devArray = NULL;
9267
9268 DBG (10, "sane_exit: finish\n");
9269 }
9270
9271 /*
9272 * @@ Section 6 - misc helper functions
9273 */
9274 /*
9275 * Called by the SANE SCSI core and our usb code on device errors
9276 * parses the request sense return data buffer,
9277 * decides the best SANE_Status for the problem, produces debug msgs,
9278 * and copies the sense buffer into the scanner struct
9279 */
9280 static SANE_Status
sense_handler(int fd, unsigned char * sensed_data, void *arg)9281 sense_handler (int fd, unsigned char * sensed_data, void *arg)
9282 {
9283 struct fujitsu *s = arg;
9284 unsigned int sense = get_RS_sense_key (sensed_data);
9285 unsigned int asc = get_RS_ASC (sensed_data);
9286 unsigned int ascq = get_RS_ASCQ (sensed_data);
9287
9288 DBG (5, "sense_handler: start\n");
9289
9290 /* kill compiler warning */
9291 (void) fd;
9292
9293 /* copy the rs return data into the scanner struct
9294 so that the caller can use it if he wants */
9295 s->rs_info = get_RS_information (sensed_data);
9296 s->rs_eom = get_RS_EOM (sensed_data);
9297 s->rs_ili = get_RS_ILI (sensed_data);
9298
9299 DBG (5, "Sense=%#02x, ASC=%#02x, ASCQ=%#02x, EOM=%d, ILI=%d, info=%#08lx\n", sense, asc, ascq, s->rs_eom, s->rs_ili, (unsigned long)s->rs_info);
9300
9301 switch (sense) {
9302 case 0x0:
9303 if (0x80 == asc) {
9304 DBG (5, "No sense: hardware status bits?\n");
9305 return SANE_STATUS_GOOD;
9306 }
9307 if (0x00 != asc) {
9308 DBG (5, "No sense: unknown asc\n");
9309 return SANE_STATUS_IO_ERROR;
9310 }
9311 if (0x00 != ascq) {
9312 DBG (5, "No sense: unknown ascq\n");
9313 return SANE_STATUS_IO_ERROR;
9314 }
9315 /* ready, but short read */
9316 if (s->rs_ili) {
9317 DBG (5, "No sense: ILI remainder:%lu\n",(unsigned long)s->rs_info);
9318 }
9319 /* ready, but end of paper */
9320 if (s->rs_eom) {
9321 DBG (5, "No sense: EOM\n");
9322 return SANE_STATUS_EOF;
9323 }
9324 DBG (5, "No sense: ready\n");
9325 return SANE_STATUS_GOOD;
9326
9327 case 0x2:
9328 if (0x00 != asc) {
9329 DBG (5, "Not ready: unknown asc\n");
9330 return SANE_STATUS_IO_ERROR;
9331 }
9332 if (0x00 != ascq) {
9333 DBG (5, "Not ready: unknown ascq\n");
9334 return SANE_STATUS_IO_ERROR;
9335 }
9336 DBG (5, "Not ready: busy\n");
9337 return SANE_STATUS_DEVICE_BUSY;
9338 break;
9339
9340 case 0x3:
9341 if (0x80 != asc) {
9342 DBG (5, "Medium error: unknown asc\n");
9343 return SANE_STATUS_IO_ERROR;
9344 }
9345 if (0x01 == ascq) {
9346 DBG (5, "Medium error: paper jam\n");
9347 return SANE_STATUS_JAMMED;
9348 }
9349 if (0x02 == ascq) {
9350 DBG (5, "Medium error: cover open\n");
9351 return SANE_STATUS_COVER_OPEN;
9352 }
9353 if (0x03 == ascq) {
9354 DBG (5, "Medium error: hopper empty\n");
9355 return SANE_STATUS_NO_DOCS;
9356 }
9357 if (0x04 == ascq) {
9358 DBG (5, "Medium error: unusual paper\n");
9359 return SANE_STATUS_JAMMED;
9360 }
9361 if (0x07 == ascq) {
9362 DBG (5, "Medium error: double feed\n");
9363 return SANE_STATUS_JAMMED;
9364 }
9365 if (0x08 == ascq) {
9366 DBG (5, "Medium error: ADF setup error\n");
9367 return SANE_STATUS_JAMMED;
9368 }
9369 if (0x09 == ascq) {
9370 DBG (5, "Medium error: Carrier sheet\n");
9371 return SANE_STATUS_JAMMED;
9372 }
9373 if (0x0c == ascq) {
9374 DBG (5, "Medium error: ADF blocked by card\n");
9375 return SANE_STATUS_JAMMED;
9376 }
9377 if (0x10 == ascq) {
9378 DBG (5, "Medium error: no ink cartridge\n");
9379 return SANE_STATUS_IO_ERROR;
9380 }
9381 if (0x13 == ascq) {
9382 DBG (5, "Medium error: temporary no data\n");
9383 return SANE_STATUS_DEVICE_BUSY;
9384 }
9385 if (0x14 == ascq) {
9386 DBG (5, "Medium error: endorser error\n");
9387 return SANE_STATUS_IO_ERROR;
9388 }
9389 if (0x20 == ascq) {
9390 DBG (5, "Medium error: Stop button\n");
9391 return SANE_STATUS_NO_DOCS;
9392 }
9393 if (0x22 == ascq) {
9394 DBG (5, "Medium error: scanning halted\n");
9395 return SANE_STATUS_CANCELLED;
9396 }
9397 if (0x30 == ascq) {
9398 DBG (5, "Medium error: Not enough paper\n");
9399 return SANE_STATUS_NO_DOCS;
9400 }
9401 if (0x31 == ascq) {
9402 DBG (5, "Medium error: scanning disabled\n");
9403 return SANE_STATUS_IO_ERROR;
9404 }
9405 if (0x32 == ascq) {
9406 DBG (5, "Medium error: scanning paused\n");
9407 return SANE_STATUS_DEVICE_BUSY;
9408 }
9409 if (0x33 == ascq) {
9410 DBG (5, "Medium error: WiFi control error\n");
9411 return SANE_STATUS_IO_ERROR;
9412 }
9413 DBG (5, "Medium error: unknown ascq\n");
9414 return SANE_STATUS_IO_ERROR;
9415 break;
9416
9417 case 0x4:
9418 if (0x80 != asc && 0x44 != asc) {
9419 DBG (5, "Hardware error: unknown asc\n");
9420 return SANE_STATUS_IO_ERROR;
9421 }
9422 if ((0x44 == asc) && (0x00 == ascq)) {
9423 DBG (5, "Hardware error: EEPROM error\n");
9424 return SANE_STATUS_IO_ERROR;
9425 }
9426 if ((0x80 == asc) && (0x01 == ascq)) {
9427 DBG (5, "Hardware error: FB motor fuse\n");
9428 return SANE_STATUS_IO_ERROR;
9429 }
9430 if ((0x80 == asc) && (0x02 == ascq)) {
9431 DBG (5, "Hardware error: heater fuse\n");
9432 return SANE_STATUS_IO_ERROR;
9433 }
9434 if ((0x80 == asc) && (0x03 == ascq)) {
9435 DBG (5, "Hardware error: lamp fuse\n");
9436 return SANE_STATUS_IO_ERROR;
9437 }
9438 if ((0x80 == asc) && (0x04 == ascq)) {
9439 DBG (5, "Hardware error: ADF motor fuse\n");
9440 return SANE_STATUS_IO_ERROR;
9441 }
9442 if ((0x80 == asc) && (0x05 == ascq)) {
9443 DBG (5, "Hardware error: mechanical error\n");
9444 return SANE_STATUS_IO_ERROR;
9445 }
9446 if ((0x80 == asc) && (0x06 == ascq)) {
9447 DBG (5, "Hardware error: optical error\n");
9448 return SANE_STATUS_IO_ERROR;
9449 }
9450 if ((0x80 == asc) && (0x07 == ascq)) {
9451 DBG (5, "Hardware error: Fan error\n");
9452 return SANE_STATUS_IO_ERROR;
9453 }
9454 if ((0x80 == asc) && (0x08 == ascq)) {
9455 DBG (5, "Hardware error: IPC option error\n");
9456 return SANE_STATUS_IO_ERROR;
9457 }
9458 if ((0x80 == asc) && (0x10 == ascq)) {
9459 DBG (5, "Hardware error: endorser error\n");
9460 return SANE_STATUS_IO_ERROR;
9461 }
9462 if ((0x80 == asc) && (0x11 == ascq)) {
9463 DBG (5, "Hardware error: endorser fuse\n");
9464 return SANE_STATUS_IO_ERROR;
9465 }
9466 if ((0x80 == asc) && (0x80 == ascq)) {
9467 DBG (5, "Hardware error: interface board timeout\n");
9468 return SANE_STATUS_IO_ERROR;
9469 }
9470 if ((0x80 == asc) && (0x81 == ascq)) {
9471 DBG (5, "Hardware error: interface board error 1\n");
9472 return SANE_STATUS_IO_ERROR;
9473 }
9474 if ((0x80 == asc) && (0x82 == ascq)) {
9475 DBG (5, "Hardware error: interface board error 2\n");
9476 return SANE_STATUS_IO_ERROR;
9477 }
9478 DBG (5, "Hardware error: unknown asc/ascq\n");
9479 return SANE_STATUS_IO_ERROR;
9480 break;
9481
9482 case 0x5:
9483 if ((0x00 == asc) && (0x00 == ascq)) {
9484 DBG (5, "Illegal request: paper edge detected too soon\n");
9485 return SANE_STATUS_INVAL;
9486 }
9487 if ((0x1a == asc) && (0x00 == ascq)) {
9488 DBG (5, "Illegal request: Parameter list error\n");
9489 return SANE_STATUS_INVAL;
9490 }
9491 if ((0x20 == asc) && (0x00 == ascq)) {
9492 DBG (5, "Illegal request: invalid command\n");
9493 return SANE_STATUS_INVAL;
9494 }
9495 if ((0x24 == asc) && (0x00 == ascq)) {
9496 DBG (5, "Illegal request: invalid CDB field\n");
9497 return SANE_STATUS_INVAL;
9498 }
9499 if ((0x25 == asc) && (0x00 == ascq)) {
9500 DBG (5, "Illegal request: unsupported logical unit\n");
9501 return SANE_STATUS_UNSUPPORTED;
9502 }
9503 if ((0x26 == asc) && (0x00 == ascq)) {
9504 DBG (5, "Illegal request: invalid field in parm list\n");
9505 if (get_RS_additional_length(sensed_data) >= 0x0a) {
9506 DBG (5, "Offending byte is %#02x\n", get_RS_offending_byte(sensed_data));
9507
9508 /* move this to set_window() ? */
9509 if (get_RS_offending_byte(sensed_data) >= 8) {
9510 DBG (5, "Window desc block? byte %#02x\n",get_RS_offending_byte(sensed_data)-8);
9511 }
9512 }
9513 return SANE_STATUS_INVAL;
9514 }
9515 if ((0x2C == asc) && (0x00 == ascq)) {
9516 DBG (5, "Illegal request: command sequence error\n");
9517 return SANE_STATUS_INVAL;
9518 }
9519 if ((0x2C == asc) && (0x02 == ascq)) {
9520 DBG (5, "Illegal request: wrong window combination \n");
9521 return SANE_STATUS_INVAL;
9522 }
9523 DBG (5, "Illegal request: unknown asc/ascq\n");
9524 return SANE_STATUS_IO_ERROR;
9525 break;
9526
9527 case 0x6:
9528 if ((0x00 == asc) && (0x00 == ascq)) {
9529 DBG (5, "Unit attention: device reset\n");
9530 return SANE_STATUS_GOOD;
9531 }
9532 if ((0x80 == asc) && (0x01 == ascq)) {
9533 DBG (5, "Unit attention: power saving\n");
9534 return SANE_STATUS_GOOD;
9535 }
9536 DBG (5, "Unit attention: unknown asc/ascq\n");
9537 return SANE_STATUS_IO_ERROR;
9538 break;
9539
9540 case 0xb:
9541 if ((0x43 == asc) && (0x00 == ascq)) {
9542 DBG (5, "Aborted command: message error\n");
9543 return SANE_STATUS_IO_ERROR;
9544 }
9545 if ((0x45 == asc) && (0x00 == ascq)) {
9546 DBG (5, "Aborted command: select failure\n");
9547 return SANE_STATUS_IO_ERROR;
9548 }
9549 if ((0x47 == asc) && (0x00 == ascq)) {
9550 DBG (5, "Aborted command: SCSI parity error\n");
9551 return SANE_STATUS_IO_ERROR;
9552 }
9553 if ((0x48 == asc) && (0x00 == ascq)) {
9554 DBG (5, "Aborted command: initiator error message\n");
9555 return SANE_STATUS_IO_ERROR;
9556 }
9557 if ((0x4e == asc) && (0x00 == ascq)) {
9558 DBG (5, "Aborted command: overlapped commands\n");
9559 return SANE_STATUS_IO_ERROR;
9560 }
9561 if ((0x80 == asc) && (0x01 == ascq)) {
9562 DBG (5, "Aborted command: image transfer error\n");
9563 return SANE_STATUS_IO_ERROR;
9564 }
9565 if ((0x80 == asc) && (0x03 == ascq)) {
9566 DBG (5, "Aborted command: JPEG overflow error\n");
9567 return SANE_STATUS_NO_MEM;
9568 }
9569 DBG (5, "Aborted command: unknown asc/ascq\n");
9570 return SANE_STATUS_IO_ERROR;
9571 break;
9572
9573 default:
9574 DBG (5, "Unknown Sense Code\n");
9575 return SANE_STATUS_IO_ERROR;
9576 }
9577
9578 DBG (5, "sense_handler: should never happen!\n");
9579
9580 return SANE_STATUS_IO_ERROR;
9581 }
9582
9583 /*
9584 * take a bunch of pointers, send commands to scanner
9585 */
9586 static SANE_Status
do_cmd(struct fujitsu *s, int runRS, int shortTime, unsigned char * cmdBuff, size_t cmdLen, unsigned char * outBuff, size_t outLen, unsigned char * inBuff, size_t * inLen )9587 do_cmd(struct fujitsu *s, int runRS, int shortTime,
9588 unsigned char * cmdBuff, size_t cmdLen,
9589 unsigned char * outBuff, size_t outLen,
9590 unsigned char * inBuff, size_t * inLen
9591 )
9592 {
9593
9594 /* unset the request sense vars first */
9595 s->rs_info = 0;
9596 s->rs_ili = 0;
9597 s->rs_eom = 0;
9598
9599 if (s->connection == CONNECTION_SCSI) {
9600 return do_scsi_cmd(s, runRS, shortTime,
9601 cmdBuff, cmdLen,
9602 outBuff, outLen,
9603 inBuff, inLen
9604 );
9605 }
9606 if (s->connection == CONNECTION_USB) {
9607 return do_usb_cmd(s, runRS, shortTime,
9608 cmdBuff, cmdLen,
9609 outBuff, outLen,
9610 inBuff, inLen
9611 );
9612 }
9613 return SANE_STATUS_INVAL;
9614 }
9615
9616 SANE_Status
do_scsi_cmd(struct fujitsu *s, int runRS, int shortTime, unsigned char * cmdBuff, size_t cmdLen, unsigned char * outBuff, size_t outLen, unsigned char * inBuff, size_t * inLen )9617 do_scsi_cmd(struct fujitsu *s, int runRS, int shortTime,
9618 unsigned char * cmdBuff, size_t cmdLen,
9619 unsigned char * outBuff, size_t outLen,
9620 unsigned char * inBuff, size_t * inLen
9621 )
9622 {
9623 int ret;
9624
9625 /*shut up compiler*/
9626 (void) runRS;
9627 (void) shortTime;
9628
9629 DBG(10, "do_scsi_cmd: start\n");
9630
9631 DBG(25, "cmd: writing %d bytes\n", (int)cmdLen);
9632 hexdump(30, "cmd: >>", cmdBuff, cmdLen);
9633
9634 if(outBuff && outLen){
9635 DBG(25, "out: writing %d bytes\n", (int)outLen);
9636 hexdump(30, "out: >>", outBuff, outLen);
9637 }
9638 if (inBuff && inLen){
9639 DBG(25, "in: reading %d bytes\n", (int)*inLen);
9640 memset(inBuff,0,*inLen);
9641 }
9642
9643 ret = sanei_scsi_cmd2(s->fd, cmdBuff, cmdLen, outBuff, outLen, inBuff, inLen);
9644
9645 if(ret != SANE_STATUS_GOOD && ret != SANE_STATUS_EOF){
9646 DBG(5,"do_scsi_cmd: return '%s'\n",sane_strstatus(ret));
9647 return ret;
9648 }
9649
9650 /* FIXME: should we look at s->rs_info here? */
9651 if (inBuff && inLen){
9652 hexdump(30, "in: <<", inBuff, *inLen);
9653 DBG(25, "in: read %d bytes\n", (int)*inLen);
9654 }
9655
9656 DBG(10, "do_scsi_cmd: finish\n");
9657
9658 return ret;
9659 }
9660
9661 SANE_Status
do_usb_cmd(struct fujitsu *s, int runRS, int shortTime, unsigned char * cmdBuff, size_t cmdLen, unsigned char * outBuff, size_t outLen, unsigned char * inBuff, size_t * inLen )9662 do_usb_cmd(struct fujitsu *s, int runRS, int shortTime,
9663 unsigned char * cmdBuff, size_t cmdLen,
9664 unsigned char * outBuff, size_t outLen,
9665 unsigned char * inBuff, size_t * inLen
9666 )
9667 {
9668 /*sanei_usb overwrites the transfer size,
9669 * so make some local copies */
9670 size_t usb_cmdLen = USB_COMMAND_LEN;
9671 size_t usb_outLen = outLen;
9672 size_t usb_statLen = USB_STATUS_LEN;
9673 size_t askLen = 0;
9674
9675 /*copy the callers buffs into larger, padded ones*/
9676 unsigned char usb_cmdBuff[USB_COMMAND_LEN];
9677 unsigned char usb_statBuff[USB_STATUS_LEN];
9678
9679 int cmdTime = USB_COMMAND_TIME;
9680 int outTime = USB_DATA_TIME;
9681 int inTime = USB_DATA_TIME;
9682 int statTime = USB_STATUS_TIME;
9683
9684 int ret = 0;
9685 int ret2 = 0;
9686
9687 DBG (10, "do_usb_cmd: start\n");
9688
9689 if(shortTime){
9690 cmdTime = USB_COMMAND_TIME/60;
9691 outTime = USB_DATA_TIME/60;
9692 inTime = USB_DATA_TIME/60;
9693 statTime = USB_STATUS_TIME/60;
9694 }
9695
9696 /* build a USB packet around the SCSI command */
9697 memset(&usb_cmdBuff,0,USB_COMMAND_LEN);
9698 usb_cmdBuff[0] = USB_COMMAND_CODE;
9699 memcpy(&usb_cmdBuff[USB_COMMAND_OFFSET],cmdBuff,cmdLen);
9700
9701 /* change timeout */
9702 sanei_usb_set_timeout(cmdTime);
9703
9704 /* write the command out */
9705 DBG(25, "cmd: writing %d bytes, timeout %d\n", USB_COMMAND_LEN, cmdTime);
9706 hexdump(30, "cmd: >>", usb_cmdBuff, USB_COMMAND_LEN);
9707 ret = sanei_usb_write_bulk(s->fd, usb_cmdBuff, &usb_cmdLen);
9708 DBG(25, "cmd: wrote %d bytes, retVal %d\n", (int)usb_cmdLen, ret);
9709
9710 if(ret == SANE_STATUS_EOF){
9711 DBG(5,"cmd: got EOF, returning IO_ERROR\n");
9712 return SANE_STATUS_IO_ERROR;
9713 }
9714 if(ret != SANE_STATUS_GOOD){
9715 DBG(5,"cmd: return error '%s'\n",sane_strstatus(ret));
9716 return ret;
9717 }
9718 if(usb_cmdLen != USB_COMMAND_LEN){
9719 DBG(5,"cmd: wrong size %d/%d\n", USB_COMMAND_LEN, (int)usb_cmdLen);
9720 return SANE_STATUS_IO_ERROR;
9721 }
9722
9723 /* this command has a write component, and a place to get it */
9724 if(outBuff && outLen && outTime){
9725
9726 /* change timeout */
9727 sanei_usb_set_timeout(outTime);
9728
9729 DBG(25, "out: writing %d bytes, timeout %d\n", (int)outLen, outTime);
9730 hexdump(30, "out: >>", outBuff, outLen);
9731 ret = sanei_usb_write_bulk(s->fd, outBuff, &usb_outLen);
9732 DBG(25, "out: wrote %d bytes, retVal %d\n", (int)usb_outLen, ret);
9733
9734 if(ret == SANE_STATUS_EOF){
9735 DBG(5,"out: got EOF, returning IO_ERROR\n");
9736 return SANE_STATUS_IO_ERROR;
9737 }
9738 if(ret != SANE_STATUS_GOOD){
9739 DBG(5,"out: return error '%s'\n",sane_strstatus(ret));
9740 return ret;
9741 }
9742 if(usb_outLen != outLen){
9743 DBG(5,"out: wrong size %d/%d\n", (int)outLen, (int)usb_outLen);
9744 return SANE_STATUS_IO_ERROR;
9745 }
9746 }
9747
9748 /* this command has a read component, and a place to put it */
9749 if(inBuff && inLen && inTime){
9750
9751 askLen = *inLen;
9752 memset(inBuff,0,askLen);
9753
9754 /* change timeout */
9755 sanei_usb_set_timeout(inTime);
9756
9757 DBG(25, "in: reading %lu bytes, timeout %d\n",
9758 (unsigned long)askLen, inTime);
9759
9760 ret = sanei_usb_read_bulk(s->fd, inBuff, inLen);
9761 DBG(25, "in: retVal %d\n", ret);
9762
9763 if(ret == SANE_STATUS_EOF){
9764 DBG(5,"in: got EOF, continuing\n");
9765 ret = SANE_STATUS_GOOD;
9766 }
9767
9768 if(ret != SANE_STATUS_GOOD){
9769 DBG(5,"in: return error '%s'\n",sane_strstatus(ret));
9770 return ret;
9771 }
9772
9773 DBG(25, "in: read %lu bytes\n", (unsigned long)*inLen);
9774 if(*inLen){
9775 hexdump(31, "in: <<", inBuff, *inLen);
9776 }
9777
9778 if(*inLen && *inLen != askLen){
9779 ret = SANE_STATUS_EOF;
9780 DBG(5,"in: short read, %lu/%lu\n",
9781 (unsigned long)*inLen,(unsigned long)askLen);
9782 }
9783 }
9784
9785 /*gather the scsi status byte. use ret2 instead of ret for status*/
9786
9787 memset(&usb_statBuff,0,USB_STATUS_LEN);
9788
9789 /* change timeout */
9790 sanei_usb_set_timeout(statTime);
9791
9792 DBG(25, "stat: reading %d bytes, timeout %d\n", USB_STATUS_LEN, statTime);
9793 ret2 = sanei_usb_read_bulk(s->fd, usb_statBuff, &usb_statLen);
9794 hexdump(30, "stat: <<", usb_statBuff, usb_statLen);
9795 DBG(25, "stat: read %d bytes, retVal %d\n", (int)usb_statLen, ret2);
9796
9797 if(ret2 == SANE_STATUS_EOF){
9798 DBG(5,"stat: got EOF, returning IO_ERROR\n");
9799 return SANE_STATUS_IO_ERROR;
9800 }
9801 if(ret2 != SANE_STATUS_GOOD){
9802 DBG(5,"stat: return error '%s'\n",sane_strstatus(ret2));
9803 return ret2;
9804 }
9805 if(usb_statLen != USB_STATUS_LEN){
9806 DBG(5,"stat: wrong size %d/%d\n", USB_STATUS_LEN, (int)usb_statLen);
9807 return SANE_STATUS_IO_ERROR;
9808 }
9809
9810 /* busy status */
9811 if(usb_statBuff[USB_STATUS_OFFSET] == 8){
9812 DBG(25,"stat: busy\n");
9813 return SANE_STATUS_DEVICE_BUSY;
9814 }
9815
9816 /* if there is a non-busy status >0, try to figure out why */
9817 if(usb_statBuff[USB_STATUS_OFFSET] > 0){
9818 DBG(25,"stat: value %d\n", usb_statBuff[USB_STATUS_OFFSET]);
9819
9820 /* caller is interested in having RS run on errors */
9821 if(runRS){
9822 unsigned char rs_cmd[REQUEST_SENSE_len];
9823 size_t rs_cmdLen = REQUEST_SENSE_len;
9824
9825 unsigned char rs_in[RS_return_size];
9826 size_t rs_inLen = RS_return_size;
9827
9828 memset(rs_cmd,0,rs_cmdLen);
9829 set_SCSI_opcode(rs_cmd, REQUEST_SENSE_code);
9830 set_RS_return_size(rs_cmd, rs_inLen);
9831
9832 DBG(25,"rs sub call >>\n");
9833 ret2 = do_cmd(
9834 s,0,0,
9835 rs_cmd, rs_cmdLen,
9836 NULL,0,
9837 rs_in, &rs_inLen
9838 );
9839 DBG(25,"rs sub call <<\n");
9840
9841 if(ret2 == SANE_STATUS_EOF){
9842 DBG(5,"rs: got EOF, returning IO_ERROR\n");
9843 return SANE_STATUS_IO_ERROR;
9844 }
9845 if(ret2 != SANE_STATUS_GOOD){
9846 DBG(5,"rs: return error '%s'\n",sane_strstatus(ret2));
9847 return ret2;
9848 }
9849
9850 /* parse the rs data */
9851 ret2 = sense_handler( 0, rs_in, (void *)s );
9852
9853 /* this was a short read, but the usb layer did not know */
9854 if(s->rs_ili && inBuff && inLen && inTime){
9855 *inLen = askLen - s->rs_info;
9856 DBG(5,"do_usb_cmd: short read via rs, %lu/%lu\n",
9857 (unsigned long)*inLen,(unsigned long)askLen);
9858 }
9859 return ret2;
9860 }
9861 else{
9862 DBG(5,"do_usb_cmd: Not calling rs!\n");
9863 return SANE_STATUS_IO_ERROR;
9864 }
9865 }
9866
9867 DBG (10, "do_usb_cmd: finish\n");
9868
9869 return ret;
9870 }
9871
9872 static SANE_Status
wait_scanner(struct fujitsu *s)9873 wait_scanner(struct fujitsu *s)
9874 {
9875 SANE_Status ret = SANE_STATUS_GOOD;
9876
9877 unsigned char cmd[TEST_UNIT_READY_len];
9878 size_t cmdLen = TEST_UNIT_READY_len;
9879
9880 DBG (10, "wait_scanner: start\n");
9881
9882 memset(cmd,0,cmdLen);
9883 set_SCSI_opcode(cmd,TEST_UNIT_READY_code);
9884
9885 ret = do_cmd (
9886 s, 0, 1,
9887 cmd, cmdLen,
9888 NULL, 0,
9889 NULL, NULL
9890 );
9891
9892 if (ret != SANE_STATUS_GOOD) {
9893 DBG(5,"WARNING: Brain-dead scanner. Hitting with stick\n");
9894 ret = do_cmd (
9895 s, 0, 1,
9896 cmd, cmdLen,
9897 NULL, 0,
9898 NULL, NULL
9899 );
9900 }
9901 if (ret != SANE_STATUS_GOOD) {
9902 DBG(5,"WARNING: Brain-dead scanner. Hitting with stick again\n");
9903 ret = do_cmd (
9904 s, 0, 1,
9905 cmd, cmdLen,
9906 NULL, 0,
9907 NULL, NULL
9908 );
9909 }
9910
9911 if (ret != SANE_STATUS_GOOD) {
9912 DBG (5, "wait_scanner: error '%s'\n", sane_strstatus (ret));
9913 }
9914
9915 DBG (10, "wait_scanner: finish\n");
9916
9917 return ret;
9918 }
9919
9920 /* certain options require the entire image to
9921 * be collected from the scanner before we can
9922 * tell the user the size of the image. */
9923 static int
must_fully_buffer(struct fujitsu *s)9924 must_fully_buffer(struct fujitsu *s)
9925 {
9926 if(s->hwdeskewcrop){
9927 return 1;
9928 }
9929
9930 if(
9931 (s->swdeskew || s->swdespeck || s->swcrop || s->swskip)
9932 && s->s_params.format != SANE_FRAME_JPEG
9933 ){
9934 return 1;
9935 }
9936
9937 return 0;
9938 }
9939
9940 /* certain scanners require the mode of the
9941 * image to be changed in software. */
9942 static int
must_downsample(struct fujitsu *s)9943 must_downsample(struct fujitsu *s)
9944 {
9945 if(s->s_mode != s->u_mode
9946 && s->compress != COMP_JPEG
9947 ){
9948 return 1;
9949 }
9950
9951 return 0;
9952 }
9953
9954 /* s->page_width stores the user setting
9955 * for the paper width in adf. sometimes,
9956 * we need a value that differs from this
9957 * due to using FB or overscan.
9958 */
9959 static int
get_page_width(struct fujitsu *s)9960 get_page_width(struct fujitsu *s)
9961 {
9962 int width = s->page_width + 2 * (s->os_x_basic*1200/s->basic_x_res);
9963
9964 /* scanner max for fb */
9965 if(s->source == SOURCE_FLATBED){
9966 return s->max_x_fb;
9967 }
9968
9969 /* current paper size for adf not overscan */
9970 if(s->overscan != MSEL_ON){
9971 return s->page_width;
9972 }
9973
9974 /* can't overscan larger than scanner max */
9975 if(width > s->max_x){
9976 return s->max_x;
9977 }
9978
9979 /* overscan adds a margin to both sides */
9980 return width;
9981 }
9982
9983 /* s->page_height stores the user setting
9984 * for the paper height in adf. sometimes,
9985 * we need a value that differs from this
9986 * due to using FB or overscan.
9987 */
9988 static int
get_page_height(struct fujitsu *s)9989 get_page_height(struct fujitsu *s)
9990 {
9991 int height = s->page_height + 2 * (s->os_y_basic*1200/s->basic_y_res);
9992
9993 /* scanner max for fb */
9994 if(s->source == SOURCE_FLATBED){
9995 return s->max_y_fb;
9996 }
9997
9998 /* current paper size for adf not overscan */
9999 if(s->overscan != MSEL_ON){
10000 return s->page_height;
10001 }
10002
10003 /* can't overscan larger than scanner max */
10004 if(height > s->max_y){
10005 return s->max_y;
10006 }
10007
10008 /* overscan adds a margin to both sides */
10009 return height;
10010 }
10011
10012 /* scanners have two different possible IPC
10013 * modes, which enable a different series of
10014 * subordinate options. Rather than provide
10015 * the user with an option to pick the IPC
10016 * mode, we show them the subordinate ones,
10017 * and pick the right mode to match.
10018 */
10019 static int
get_ipc_mode(struct fujitsu *s)10020 get_ipc_mode(struct fujitsu *s)
10021 {
10022 if ( s->bp_filter
10023 || s->smoothing
10024 || s->gamma_curve
10025 || s->threshold_curve
10026 || s->threshold_white
10027 || s->noise_removal
10028 || s->matrix_5
10029 || s->matrix_4
10030 || s->matrix_3
10031 || s->matrix_2
10032 )
10033 return WD_ipc_DTC;
10034
10035 if(s->variance)
10036 return WD_ipc_SDTC;
10037
10038 /* special case: 0 threshold should activate IPC */
10039 if(!s->threshold){
10040 if(s->has_sdtc)
10041 return WD_ipc_SDTC;
10042 if(s->has_dtc)
10043 return WD_ipc_DTC;
10044 }
10045
10046 return WD_ipc_DEFAULT;
10047 }
10048
10049 /* s->max_y gives the maximum height of paper which can be scanned
10050 * this actually varies by resolution, so a helper to change it */
10051 static int
set_max_y(struct fujitsu *s)10052 set_max_y(struct fujitsu *s)
10053 {
10054 int i;
10055
10056 for(i=0;i<4;i++){
10057 if(!s->max_y_by_res[i].res)
10058 break;
10059 if(s->resolution_x <= s->max_y_by_res[i].res){
10060 s->max_y = s->max_y_by_res[i].len;
10061 }
10062 }
10063
10064 return s->max_y;
10065 }
10066
10067 /**
10068 * Convenience method to determine longest string size in a list.
10069 */
10070 static size_t
maxStringSize(const SANE_String_Const strings[])10071 maxStringSize (const SANE_String_Const strings[])
10072 {
10073 size_t size, max_size = 0;
10074 int i;
10075
10076 for (i = 0; strings[i]; ++i) {
10077 size = strlen (strings[i]) + 1;
10078 if (size > max_size)
10079 max_size = size;
10080 }
10081
10082 return max_size;
10083 }
10084
10085 /*
10086 * Prints a hex dump of the given buffer onto the debug output stream.
10087 */
10088 static void
hexdump(int level, char *comment, unsigned char *p, int l)10089 hexdump (int level, char *comment, unsigned char *p, int l)
10090 {
10091 int i;
10092 char line[70]; /* 'xxx: xx xx ... xx xx abc */
10093 char *hex = line+4;
10094 char *bin = line+53;
10095
10096 if(DBG_LEVEL < level)
10097 return;
10098
10099 DBG (level, "%s\n", comment);
10100
10101 for (i = 0; i < l; i++, p++) {
10102
10103 /* at start of line */
10104 if ((i % 16) == 0) {
10105
10106 /* not at start of first line, print current, reset */
10107 if (i) {
10108 DBG (level, "%s\n", line);
10109 }
10110
10111 memset(line,0x20,69);
10112 line[69] = 0;
10113 hex = line + 4;
10114 bin = line + 53;
10115
10116 sprintf (line, "%3.3x:", i);
10117 }
10118
10119 /* the hex section */
10120 sprintf (hex, " %2.2x", *p);
10121 hex += 3;
10122 *hex = ' ';
10123
10124 /* the char section */
10125 if(*p >= 0x20 && *p <= 0x7e){
10126 *bin=*p;
10127 }
10128 else{
10129 *bin='.';
10130 }
10131 bin++;
10132 }
10133
10134 /* print last (partial) line */
10135 if (i)
10136 DBG (level, "%s\n", line);
10137 }
10138
10139 /**
10140 * An advanced method we don't support but have to define.
10141 */
10142 SANE_Status
sane_set_io_mode(SANE_Handle h, SANE_Bool non_blocking)10143 sane_set_io_mode (SANE_Handle h, SANE_Bool non_blocking)
10144 {
10145 DBG (10, "sane_set_io_mode\n");
10146 DBG (15, "%d %p\n", non_blocking, h);
10147 return SANE_STATUS_UNSUPPORTED;
10148 }
10149
10150 /**
10151 * An advanced method we don't support but have to define.
10152 */
10153 SANE_Status
sane_get_select_fd(SANE_Handle h, SANE_Int *fdp)10154 sane_get_select_fd (SANE_Handle h, SANE_Int *fdp)
10155 {
10156 DBG (10, "sane_get_select_fd\n");
10157 DBG (15, "%p %d\n", h, *fdp);
10158 return SANE_STATUS_UNSUPPORTED;
10159 }
10160
10161 /*
10162 * @@ Section 7 - Image processing functions
10163 */
10164
10165 /* Look in image for likely upper and left paper edges, then rotate
10166 * image so that upper left corner of paper is upper left of image.
10167 * FIXME: should we do this before we binarize instead of after? */
10168 static SANE_Status
buffer_deskew(struct fujitsu *s, int side)10169 buffer_deskew(struct fujitsu *s, int side)
10170 {
10171 SANE_Status ret = SANE_STATUS_GOOD;
10172
10173 int bg_color = 0xd6;
10174
10175 DBG (10, "buffer_deskew: start\n");
10176
10177 /*only find skew on first image from a page, or if first image had error */
10178 if(s->side == SIDE_FRONT
10179 || s->source == SOURCE_ADF_BACK || s->source == SOURCE_CARD_BACK
10180 || s->deskew_stat){
10181
10182 s->deskew_stat = sanei_magic_findSkew(
10183 &s->s_params,s->buffers[side],s->resolution_x,s->resolution_y,
10184 &s->deskew_vals[0],&s->deskew_vals[1],&s->deskew_slope);
10185
10186 if(s->deskew_stat){
10187 DBG (5, "buffer_deskew: bad findSkew, bailing\n");
10188 goto cleanup;
10189 }
10190 }
10191 /* backside images can use a 'flipped' version of frontside data */
10192 else{
10193 s->deskew_slope *= -1;
10194 s->deskew_vals[0] = s->s_params.pixels_per_line - s->deskew_vals[0];
10195 }
10196
10197 /* tweak the bg color based on scanner settings */
10198 if(s->s_mode == MODE_HALFTONE || s->s_mode == MODE_LINEART){
10199 if(s->bg_color == COLOR_BLACK || s->hwdeskewcrop || s->overscan)
10200 bg_color = 0xff;
10201 else
10202 bg_color = 0;
10203 }
10204 else if(s->bg_color == COLOR_BLACK || s->hwdeskewcrop || s->overscan)
10205 bg_color = 0;
10206
10207 ret = sanei_magic_rotate(&s->s_params,s->buffers[side],
10208 s->deskew_vals[0],s->deskew_vals[1],s->deskew_slope,bg_color);
10209
10210 if(ret){
10211 DBG(5,"buffer_deskew: rotate error: %d",ret);
10212 ret = SANE_STATUS_GOOD;
10213 goto cleanup;
10214 }
10215
10216 cleanup:
10217 DBG (10, "buffer_deskew: finish\n");
10218 return ret;
10219 }
10220
10221 /* Look in image for likely left/right/bottom paper edges, then crop image.
10222 * Does not attempt to rotate the image, that should be done first.
10223 * FIXME: should we do this before we binarize instead of after? */
10224 static SANE_Status
buffer_crop(struct fujitsu *s, int side)10225 buffer_crop(struct fujitsu *s, int side)
10226 {
10227 SANE_Status ret = SANE_STATUS_GOOD;
10228
10229 DBG (10, "buffer_crop: start\n");
10230
10231 ret = sanei_magic_findEdges(
10232 &s->s_params,s->buffers[side],s->resolution_x,s->resolution_y,
10233 &s->crop_vals[0],&s->crop_vals[1],&s->crop_vals[2],&s->crop_vals[3]);
10234
10235 if(ret){
10236 DBG (5, "buffer_crop: bad edges, bailing\n");
10237 ret = SANE_STATUS_GOOD;
10238 goto cleanup;
10239 }
10240
10241 DBG (15, "buffer_crop: t:%d b:%d l:%d r:%d\n",
10242 s->crop_vals[0],s->crop_vals[1],s->crop_vals[2],s->crop_vals[3]);
10243
10244 /* if we will later binarize this image, make sure the width
10245 * is a multiple of 8 pixels, by adjusting the right side */
10246 if ( must_downsample(s) && s->u_mode < MODE_GRAYSCALE ){
10247 s->crop_vals[3] -= (s->crop_vals[3]-s->crop_vals[2]) % 8;
10248 }
10249
10250 /* now crop the image */
10251 ret = sanei_magic_crop(&s->s_params,s->buffers[side],
10252 s->crop_vals[0],s->crop_vals[1],s->crop_vals[2],s->crop_vals[3]);
10253
10254 if(ret){
10255 DBG (5, "buffer_crop: bad crop, bailing\n");
10256 ret = SANE_STATUS_GOOD;
10257 goto cleanup;
10258 }
10259
10260 /* need to update user with new size */
10261 update_u_params(s);
10262
10263 /* update image size counter to new, smaller size */
10264 s->bytes_rx[side] = s->s_params.lines * s->s_params.bytes_per_line;
10265 s->buff_rx[side] = s->bytes_rx[side];
10266
10267 cleanup:
10268 DBG (10, "buffer_crop: finish\n");
10269 return ret;
10270 }
10271
10272 /* Look in image for disconnected 'spots' of the requested size.
10273 * Replace the spots with the average color of the surrounding pixels.
10274 * FIXME: should we do this before we binarize instead of after? */
10275 static SANE_Status
buffer_despeck(struct fujitsu *s, int side)10276 buffer_despeck(struct fujitsu *s, int side)
10277 {
10278 SANE_Status ret = SANE_STATUS_GOOD;
10279
10280 DBG (10, "buffer_despeck: start\n");
10281
10282 ret = sanei_magic_despeck(&s->s_params,s->buffers[side],s->swdespeck);
10283 if(ret){
10284 DBG (5, "buffer_despeck: bad despeck, bailing\n");
10285 ret = SANE_STATUS_GOOD;
10286 goto cleanup;
10287 }
10288
10289 cleanup:
10290 DBG (10, "buffer_despeck: finish\n");
10291 return ret;
10292 }
10293
10294 /* Look if image has too few dark pixels.*/
10295 static int
buffer_isblank(struct fujitsu *s, int side)10296 buffer_isblank(struct fujitsu *s, int side)
10297 {
10298 SANE_Status ret = SANE_STATUS_GOOD;
10299 int status = 0;
10300
10301 DBG (10, "buffer_isblank: start\n");
10302
10303 ret = sanei_magic_isBlank2(&s->s_params, s->buffers[side],
10304 s->resolution_x, s->resolution_y, s->swskip);
10305
10306 if(ret == SANE_STATUS_NO_DOCS){
10307 DBG (5, "buffer_isblank: blank!\n");
10308 status = 1;
10309 }
10310 else if(ret){
10311 DBG (5, "buffer_isblank: error %d\n",ret);
10312 }
10313
10314 DBG (10, "buffer_isblank: finished\n");
10315 return status;
10316 }
10317