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