• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* sane - Scanner Access Now Easy.
2 
3    This file is part of the SANE package, and implements a SANE backend
4    for various Canon DR-series scanners.
5 
6    Copyright (C) 2008-2022 m. allan noah
7 
8    Yabarana Corp. www.yabarana.com provided significant funding
9    EvriChart, Inc. www.evrichart.com provided funding and loaned equipment
10    Canon, USA. www.usa.canon.com loaned equipment
11    HPrint hprint.com.br provided funding and testing for DR-2510 support
12    Stone-IT www.stone-it.com provided funding for DR-2010 and DR-2050 support
13    Smartmatic www.smartmatic.com provided testing and changes for DR-X10C support
14 
15    --------------------------------------------------------------------------
16 
17    This program is free software; you can redistribute it and/or
18    modify it under the terms of the GNU General Public License as
19    published by the Free Software Foundation; either version 2 of the
20    License, or (at your option) any later version.
21 
22    This program is distributed in the hope that it will be useful, but
23    WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25    General Public License for more details.
26 
27    You should have received a copy of the GNU General Public License
28    along with this program.  If not, see <https://www.gnu.org/licenses/>.
29 
30    As a special exception, the authors of SANE give permission for
31    additional uses of the libraries contained in this release of SANE.
32 
33    The exception is that, if you link a SANE library with other files
34    to produce an executable, this does not by itself cause the
35    resulting executable to be covered by the GNU General Public
36    License.  Your use of that executable is in no way restricted on
37    account of linking the SANE library code into it.
38 
39    This exception does not, however, invalidate any other reasons why
40    the executable file might be covered by the GNU General Public
41    License.
42 
43    If you submit changes to SANE to the maintainers to be included in
44    a subsequent release, you agree by submitting the changes that
45    those changes may be distributed with this exception intact.
46 
47    If you write modifications of your own for SANE, it is your choice
48    whether to permit this exception to apply to your modifications.
49    If you do not wish that, delete this exception notice.
50 
51    --------------------------------------------------------------------------
52 
53    The source code is divided in sections which you can easily find by
54    searching for the tag "@@".
55 
56    Section 1 - Init & static stuff
57    Section 2 - sane_init, _get_devices, _open & friends
58    Section 3 - sane_*_option functions
59    Section 4 - sane_start, _get_param, _read & friends
60    Section 5 - calibration functions
61    Section 6 - sane_close functions
62    Section 7 - misc functions
63    Section 8 - image processing functions
64 
65    Changes:
66       v1 2008-10-29, MAN
67          - initial version
68       v2 2008-11-04, MAN
69          - round scanlines to even bytes
70 	 - spin RS and usb_clear_halt code into new function
71 	 - update various scsi payloads
72 	 - calloc out block so it gets set to 0 initially
73       v3 2008-11-07, MAN
74          - back window uses id 1
75          - add option and functions to read/send page counter
76          - add rif option
77       v4 2008-11-11, MAN
78          - eject document when sane_read() returns EOF
79       v5 2008-11-25, MAN
80          - remove EOF ejection code
81          - add SSM and GSM commands
82          - add dropout, doublefeed, and jpeg compression options
83          - disable adf backside
84          - fix adf duplex
85          - read two extra lines (ignore errors) at end of image
86          - only send scan command at beginning of batch
87 	 - fix bug in hexdump with 0 length string
88          - DR-7580 support
89       v6 2008-11-29, MAN
90          - fix adf simplex
91          - rename ssm_duplex to ssm_buffer
92          - add --buffer option
93          - reduce inter-page commands when buffering is enabled
94          - improve sense_handler output
95          - enable counter option
96          - drop unused code
97       v7 2008-11-29, MAN
98          - jpeg support (size rounding and header overwrite)
99          - call object_position(load) between pages even if buffering is on
100          - use request sense info bytes on short scsi reads
101          - byte swap color BGR to RGB
102          - round image width down, not up
103          - round image height down to even # of lines
104          - always transfer even # of lines per block
105          - scsi and jpeg don't require reading extra lines to reach EOF
106          - rename buffer option to buffermode to avoid conflict with scanimage
107          - send ssm_do and ssm_df during sane_start
108          - improve sense_handler output
109       v8 2008-12-07, MAN
110          - rename read/send_counter to read/send_panel
111          - enable control panel during init
112          - add options for all buttons
113          - call TUR twice in wait_scanner(), even if first succeeds
114          - disable rif
115          - enable brightness/contrast/threshold options
116       v9 2008-12-07, MAN
117          - add rollerdeskew and stapledetect options
118          - add rollerdeskew and stapledetect bits to ssm_df()
119       v10 2008-12-10, MAN
120          - add all documented request sense codes to sense_handler()
121          - fix color jpeg (remove unneeded BGR to RGB swapping code)
122          - add macros for LUT data
123       v11 2009-01-10, MAN
124          - send_panel() can disable too
125          - add cancel() to send d8 command
126          - call cancel() only after final read from scanner
127          - stop button requests cancel
128       v12 2009-01-21, MAN
129          - don't export private symbols
130       v13 2009-03-06, MAN
131          - new vendor ID for recent machines
132          - add usb ids for several new machines
133       v14 2009-03-07, MAN
134          - remove HARD_SELECT from counter (Legitimate, but API violation)
135          - attach to CR-series scanners as well
136       v15 2009-03-15, MAN
137          - add byte-oriented duplex interlace code
138          - add RRGGBB color interlace code
139          - add basic support for DR-2580C
140       v16 2009-03-20, MAN
141          - add more unknown setwindow bits
142          - add support for 16 byte status packets
143          - clean do_usb_cmd error handling (call reset more often)
144          - add basic support for DR-2050C, DR-2080C, DR-2510C
145       v17 2009-03-20, MAN
146          - set status packet size from config file
147       v18 2009-03-21, MAN
148          - rewrite config file parsing to reset options after each scanner
149          - add config options for vendor, model, version
150          - don't call inquiry if those 3 options are set
151          - remove default config file from code
152          - add initial gray deinterlacing code for DR-2510C
153          - rename do_usb_reset to do_usb_clear
154       v19 2009-03-22, MAN
155          - pad gray deinterlacing area for DR-2510C
156          - override tl_x and br_x for fixed width scanners
157       v20 2009-03-23, MAN
158          - improved macros for inquiry and set window
159          - shorten inquiry vpd length to match windows driver
160          - remove status-length config option
161          - add padded-read config option
162          - rewrite do_usb_cmd to pad reads and calloc/copy buffers
163       v21 2009-03-24, MAN
164          - correct rgb padding macro
165          - skip send_panel and ssm_df commands for DR-20xx scanners
166       v22 2009-03-25, MAN
167          - add deinterlacing code for DR-2510C in duplex and color
168       v23 2009-03-27, MAN
169          - rewrite all image data processing code
170          - handle more image interlacing formats
171          - re-enable binary mode on some scanners
172          - limit some machines to full-width scanning
173       v24 2009-04-02, MAN
174          - fix DR-2510C duplex deinterlacing code
175          - rewrite sane_read helpers to read until EOF
176          - update sane_start for scanners that don't use object_position
177          - don't call sanei_usb_clear_halt() if device is not open
178          - increase default buffer size to 4 megs
179          - set buffermode on by default
180          - hide modes and resolutions that DR-2510C lies about
181          - read_panel() logs front-end access to sensors instead of timing
182          - rewrite do_usb_cmd() to use remainder from RS info
183       v25 2009-04-12, MAN
184          - disable SANE_FRAME_JPEG
185       v26 2009-04-14, MAN (SANE 1.0.20)
186          - return cmd status for reads on sensors
187          - allow rs to adjust read length for all bad status responses
188       v27 2009-05-08, MAN
189          - bug fix in read_panel()
190          - initialize vars in do_usb_cmd()
191          - set buffermode off by default
192          - clear page counter during init and sane_start()
193          - eject previous page during init and sane_start()
194          - improved SSM_BUFF macros
195          - moved set_window() to after ssm-*()
196          - add coarse calibration (AFE offset/gain & per-channel exposure)
197          - add fine calibration (per-cell offset/gain)
198          - free image and fine cal buffers in sane_close()
199          - compare page counter of small scanners only in non-buffered mode
200          - add back-side gray mirroring code for DR-2580C
201       v28 2009-05-20, MAN
202          - use average instead of min/max for fine offset and gain
203          - rewrite supported resolution list as x and y arrays
204          - merge x and y resolution options into single option
205          - move scan params into two new structs, s->u and s->s
206          - sane_get_parameters() just returns values from s->u
207          - don't call wait_scanner() in object_position()
208          - don't call ssm_*() from option handler
209          - refactor sane_start()
210          - read_from_buffer() can workaround missing res, modes and cropping
211          - set most DR-2xxx machines to use the read_from_buffer workarounds
212          - set default threshold to 90
213          - add option for button #3 of some machines
214          - don't eject paper during init
215          - add DR-2010 quirks
216          - switch counter to HARD_SELECT, not SOFT
217       v29 2009-06-01, MAN
218          - split coarse and fine cal to run independently
219          - add side option
220          - reset scan params to user request if calibration fails
221          - better handling of sane_cancel
222          - better handling of errors during sane_start and sane_read
223       v30 2009-06-17, MAN
224          - add fine cal support for machines with internal buffer (2050/2080)
225          - support fixed-width machines that require even bytes per scanline
226          - pad end of scan with gray if scanner stops prematurely
227          - better handling of errors during calibration
228          - cleanup canceling debug messages
229          - remove old cancel() prototype
230          - small sleep before clearing usb halt condition
231       v31 2009-06-29, MAN
232          - reduce default buffer size to 2 megs
233       v32 2009-07-21, MAN
234          - crop/resample image data before buffering, not after
235          - shink image buffers to size of output image, not input
236          - correct some debug message
237          - better handling of EOF
238          - add intermediate param struct to existing user and scan versions
239       v33 2009-07-23, MAN
240          - add software brightness/contrast for dumb scanners
241          - add blocking mode to allow full-page manipulation options to run
242          - add swdespeck option and support code
243          - add swdeskew and swcrop options (disabled)
244       v34 2009-07-28, MAN
245          - add simplified Hough transform based deskewing code
246          - add extremity detecting cropping code
247          - use per-model background color to fill corners after deskew
248          - request and chop extra scanlines instead of rounding down
249          - remove padding dumb scanners add to top of front side
250          - sane_get_params uses intermediate struct instead of user struct
251          - if scanner stops, clone the last line until the end of buffer
252          - reset some intermediate params between duplex sides
253       v35 2010-02-09, MAN (SANE 1.0.21)
254          - cleanup #includes and copyright
255          - add SANE_I18N to static strings
256          - don't fail if scsi buffer is too small
257       v36 2011-01-03, MAN
258          - initial support for DR-3080 and DR-5060
259          - add code to clamp scan width to an arbitrary byte width boundary
260          - add code to prevent setting of brightness/threshold/contrast
261          - don't send dropout color command on non-color scanners
262          - initial support for DR-7090C
263          - update credits
264       v37 2011-01-26, MAN (SANE 1.0.22)
265          - don't center window when using flatbed
266          - improve request sense error messages
267          - enable flatbed for all known models
268       v38 2011-07-06, MAN
269 	 - initial support for DR-5020
270 	 - use ppl_mod instead of Bpl_mod, apply to all modes
271 	 - invert logic of read_panel tracking
272 	 - add ability to disable read_panel()
273 	 - automatically disable read/send_panel if unsupported
274       v39 2011-11-01, MAN
275          - DR-2580C pads the backside of duplex scans
276       v40 2012-11-01, MAN
277          - initial DR-9050C, DR-7550C, DR-6050C and DR-3010C support
278       v41 2013-07-31, MAN (SANE 1.0.24)
279          - initial P-208 and P-215 support
280          - bug fix for calibration of scanners with duplex_offset
281          - allow duplex_offset to be controlled from config file
282       v42 2013-12-09, MAN
283          - initial DR-G1100 support
284          - add support for paper sensors (P-215 & P-208)
285          - add initial support for card reader (P-215)
286          - removed unused var from do_scsi_cmd()
287       v43 2014-03-13, MAN
288          - initial DR-M140 support
289          - add extra_status config and code
290          - split status code into do_usb_status
291          - fix copy_line margin offset
292          - add new color interlacing modes and code
293          - comment out ssm2
294          - add timestamp to do_usb_cmd
295       v44 2014-03-26, MAN
296          - buffermode support for machines with ssm2 command
297          - DR-M140 needs always_op=0
298       v45 2014-03-29, MAN
299          - dropout support for machines with ssm2 command
300          - doublefeed support for machines with ssm2 command
301       v46 2014-04-09, MAN
302          - split debug level 30 into two levels
303          - simplify jpeg ifdefs
304          - add support for DR-M160
305       v47 2014-07-07, MAN
306          - initial DR-G1130 support
307       v48 2014-08-06, MAN
308          - set another unknown byte in buffermode for ssm2
309          - add another gettimeofday call at end of do_usb_cmd
310          - don't print 0 length line in hexdump
311       v49 2015-03-18, MAN
312          - initial support for DR-C125
313       v50 2015-08-23, MAN
314          - DR-C125 adds duplex padding on back side
315          - initial support for DR-C225
316       v51 2015-08-25, MAN (SANE 1.0.25)
317          - DR-C125 does not invert_tly, does need sw_lut
318       v52 2015-11-03, MAN
319          - set can_color=1 by default (recent models don't have 'C' in name)
320          - enable jpeg for DR-6080
321          - add must_downsample and must_fully_buffer
322          - improve dropout option handling
323          - add software dropout implementation for downsampled modes
324       v53 2015-11-06, MAN
325          - replace image processing methods with sanei_magic
326          - add swskip option
327          - reorder geometry group options
328          - use bg_color to fill missing image data
329       v54 2015-11-21, MAN
330          - br_x and br_y locked to page_width/height until changed
331       v55 2016-03-19, MAN
332          - fixed-width scanners were calculating left-side offset incorrectly in color
333          - initial support for DR-F120
334          - rename all DUPLEX_INTERLACE_* to indicate start and end of line
335       v56 2016-08-23, MAN
336          - initial support for P-150
337       v57 2019-02-24, manuarg
338          - complete support for X-10, including hardware cropping
339       v58 2019-11-10, MAN
340          - adjust wait_scanner to set runRS only as a last resort, bug #154
341       v59 2020-09-23, MAN
342          - restructure fine calibration code
343          - initial support for uploading fine calibration payloads
344          - improve DR-C225 support
345       v60 2020-11-28, MAN
346          - add new gray and color interlacing options for DR-C120
347          - initial support for DR-C120 and C130
348          - enable fine calibration for P-208 (per @sashacmc in !546)
349       v61 2021-02-13, MAN
350          - treat DR-P208 like P-208 (#356)
351          - treat DR-P215 like P-215 (#356)
352          - adjust wait_scanner to try one TUR with a long timeout (#142)
353       v62 2021-02-13, MAN
354          - allow config file to set inq and vpd lengths for DR-M1060 (#263)
355          - rewrite do_cmd() timeout handling
356          - remove long timeout TUR from v61 (did not help)
357          - allow config file to set initial tur timeout for DR-X10C (#142)
358       v63 2022-11-18, CQ, MAN
359          - add support for reading the total and roller counters
360       v64 2022-11-18, CQ, MAN
361          - add complete support for imprinters on X10C (#585)
362 
363    SANE FLOW DIAGRAM
364 
365    - sane_init() : initialize backend
366    . - sane_get_devices() : query list of scanner devices
367    . - sane_open() : open a particular scanner device
368    . . - sane_set_io_mode : set blocking mode
369    . . - sane_get_select_fd : get scanner fd
370    . .
371    . . - sane_get_option_descriptor() : get option information
372    . . - sane_control_option() : change option values
373    . . - sane_get_parameters() : returns estimated scan parameters
374    . . - (repeat previous 3 functions)
375    . .
376    . . - sane_start() : start image acquisition
377    . .   - sane_get_parameters() : returns actual scan parameters
378    . .   - sane_read() : read image data (from pipe)
379    . . (sane_read called multiple times; after sane_read returns EOF,
380    . . loop may continue with sane_start which may return a 2nd page
381    . . when doing duplex scans, or load the next page from the ADF)
382    . .
383    . . - sane_cancel() : cancel operation
384    . - sane_close() : close opened scanner device
385    - sane_exit() : terminate use of backend
386 
387 */
388 
389 /*
390  * @@ Section 1 - Init
391  */
392 
393 #include "../include/sane/config.h"
394 
395 #include <string.h> /*memcpy...*/
396 #include <ctype.h> /*isspace*/
397 #include <math.h> /*tan*/
398 #include <unistd.h> /*usleep*/
399 #include <sys/time.h> /*gettimeofday*/
400 #include <time.h> /*localtime*/
401 #include <stdlib.h> /*strtol*/
402 
403 #include "../include/sane/sanei_backend.h"
404 #include "../include/sane/sanei_scsi.h"
405 #include "../include/sane/sanei_usb.h"
406 #include "../include/sane/saneopts.h"
407 #include "../include/sane/sanei_config.h"
408 #include "../include/sane/sanei_magic.h"
409 
410 #include "canon_dr-cmd.h"
411 #include "canon_dr.h"
412 
413 #define DEBUG 1
414 #define BUILD 64
415 
416 /* values for SANE_DEBUG_CANON_DR env var:
417  - errors           5
418  - function trace  10
419  - function detail 15
420  - get/setopt cmds 20
421  - scsi/usb trace  25
422  - scsi/usb writes 30
423  - scsi/usb reads  31
424  - useless noise   35
425 */
426 
427 /* ------------------------------------------------------------------------- */
428 /* if JPEG support is not enabled in sane.h, we setup our own defines */
429 #ifndef SANE_FRAME_JPEG
430 #define SANE_FRAME_JPEG 0x0B
431 #define SANE_JPEG_DISABLED 1
432 #endif
433 /* ------------------------------------------------------------------------- */
434 #define STRING_FLATBED SANE_I18N("Flatbed")
435 #define STRING_ADFFRONT SANE_I18N("ADF Front")
436 #define STRING_ADFBACK SANE_I18N("ADF Back")
437 #define STRING_ADFDUPLEX SANE_I18N("ADF Duplex")
438 #define STRING_CARDFRONT SANE_I18N("Card Front")
439 #define STRING_CARDBACK SANE_I18N("Card Back")
440 #define STRING_CARDDUPLEX SANE_I18N("Card Duplex")
441 
442 #define STRING_LINEART SANE_VALUE_SCAN_MODE_LINEART
443 #define STRING_HALFTONE SANE_VALUE_SCAN_MODE_HALFTONE
444 #define STRING_GRAYSCALE SANE_VALUE_SCAN_MODE_GRAY
445 #define STRING_COLOR SANE_VALUE_SCAN_MODE_COLOR
446 
447 #define STRING_RED SANE_I18N("Red")
448 #define STRING_GREEN SANE_I18N("Green")
449 #define STRING_BLUE SANE_I18N("Blue")
450 #define STRING_EN_RED SANE_I18N("Enhance Red")
451 #define STRING_EN_GREEN SANE_I18N("Enhance Green")
452 #define STRING_EN_BLUE SANE_I18N("Enhance Blue")
453 
454 #define STRING_NONE SANE_I18N("None")
455 #define STRING_JPEG SANE_I18N("JPEG")
456 
457 #define STRING_IMPRINTER_8x12_FONT SANE_I18N("8x12")
458 #define STRING_IMPRINTER_12x12_FONT SANE_I18N("12x12")
459 
460 #define STRING_IMPRINTER_ADDON_BoW SANE_I18N("Black-on-White")
461 #define STRING_IMPRINTER_ADDON_BoI SANE_I18N("Black-on-Image")
462 #define STRING_IMPRINTER_ADDON_WoB SANE_I18N("White-on-Black")
463 
464 /* Also set via config file. */
465 static int global_buffer_size;
466 static int global_buffer_size_default = 2 * 1024 * 1024;
467 static int global_padded_read;
468 static int global_padded_read_default = 0;
469 static int global_extra_status;
470 static int global_extra_status_default = 0;
471 static int global_duplex_offset;
472 static int global_duplex_offset_default = 0;
473 static int global_inquiry_length;
474 static int global_vpd_length;
475 static int global_tur_timeout;
476 static int global_tur_timeout_default = USB_PACKET_TIMEOUT/60; /* half second */
477 static char global_vendor_name[9];
478 static char global_model_name[17];
479 static char global_version_name[5];
480 
481 /*
482  * used by attach* and sane_get_devices
483  * a ptr to a null term array of ptrs to SANE_Device structs
484  * a ptr to a single-linked list of scanner structs
485  */
486 static const SANE_Device **sane_devArray = NULL;
487 static struct scanner *scanner_devList = NULL;
488 
489 /*
490  * @@ Section 2 - SANE & scanner init code
491  */
492 
493 /*
494  * Called by SANE initially.
495  *
496  * From the SANE spec:
497  * This function must be called before any other SANE function can be
498  * called. The behavior of a SANE backend is undefined if this
499  * function is not called first. The version code of the backend is
500  * returned in the value pointed to by version_code. If that pointer
501  * is NULL, no version code is returned. Argument authorize is either
502  * a pointer to a function that is invoked when the backend requires
503  * authentication for a specific resource or NULL if the frontend does
504  * not support authentication.
505  */
506 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback authorize)507 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
508 {
509   (void) authorize;             /* get rid of compiler warning */
510 
511   DBG_INIT ();
512   DBG (10, "sane_init: start\n");
513 
514   if (version_code)
515     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
516 
517   DBG (5, "sane_init: canon_dr backend %d.%d.%d, from %s\n",
518     SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING);
519 
520   DBG (10, "sane_init: finish\n");
521 
522   return SANE_STATUS_GOOD;
523 }
524 
525 /*
526  * Called by SANE to find out about supported devices.
527  *
528  * From the SANE spec:
529  * This function can be used to query the list of devices that are
530  * available. If the function executes successfully, it stores a
531  * pointer to a NULL terminated array of pointers to SANE_Device
532  * structures in *device_list. The returned list is guaranteed to
533  * remain unchanged and valid until (a) another call to this function
534  * is performed or (b) a call to sane_exit() is performed. This
535  * function can be called repeatedly to detect when new devices become
536  * available. If argument local_only is true, only local devices are
537  * returned (devices directly attached to the machine that SANE is
538  * running on). If it is false, the device list includes all remote
539  * devices that are accessible to the SANE library.
540  *
541  * SANE does not require that this function is called before a
542  * sane_open() call is performed. A device name may be specified
543  * explicitly by a user which would make it unnecessary and
544  * undesirable to call this function first.
545  */
546 /*
547  * Read the config file, find scanners with help from sanei_*
548  * and store in global device structs
549  */
550 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)551 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
552 {
553   SANE_Status ret = SANE_STATUS_GOOD;
554   struct scanner * s;
555   struct scanner * prev = NULL;
556   char line[PATH_MAX];
557   const char *lp;
558   FILE *fp;
559   int num_devices=0;
560   int i=0;
561 
562   (void) local_only;            /* get rid of compiler warning */
563 
564   DBG (10, "sane_get_devices: start\n");
565 
566   /* mark all existing scanners as missing, attach_one will remove mark */
567   for (s = scanner_devList; s; s = s->next) {
568     s->missing = 1;
569   }
570 
571   sanei_usb_init();
572 
573   /* reset globals before reading the file */
574   default_globals();
575 
576   fp = sanei_config_open (CANON_DR_CONFIG_FILE);
577 
578   if (fp) {
579 
580       DBG (15, "sane_get_devices: reading config file %s\n",
581         CANON_DR_CONFIG_FILE);
582 
583       while (sanei_config_read (line, PATH_MAX, fp)) {
584 
585           lp = line;
586 
587           /* ignore comments */
588           if (*lp == '#')
589             continue;
590 
591           /* skip empty lines */
592           if (*lp == 0)
593             continue;
594 
595           if (!strncmp ("option", lp, 6) && isspace (lp[6])) {
596 
597               lp += 6;
598               lp = sanei_config_skip_whitespace (lp);
599 
600               /* BUFFERSIZE: > 4K */
601               if (!strncmp (lp, "buffer-size", 11) && isspace (lp[11])) {
602 
603                   int buf;
604                   lp += 11;
605                   lp = sanei_config_skip_whitespace (lp);
606                   buf = atoi (lp);
607 
608                   if (buf < 4096) {
609                     DBG (5, "sane_get_devices: config option \"buffer-size\" "
610                       "(%d) is < 4096, ignoring!\n", buf);
611                     continue;
612                   }
613 
614                   if (buf > global_buffer_size_default) {
615                     DBG (5, "sane_get_devices: config option \"buffer-size\" "
616                       "(%d) is > %d, scanning problems may result\n", buf,
617                       global_buffer_size_default);
618                   }
619 
620                   DBG (15, "sane_get_devices: setting \"buffer-size\" to %d\n",
621                     buf);
622 
623                   global_buffer_size = buf;
624               }
625 
626               /* PADDED READ: we clamp to 0 or 1 */
627               else if (!strncmp (lp, "padded-read", 11) && isspace (lp[11])) {
628 
629                   int buf;
630                   lp += 11;
631                   lp = sanei_config_skip_whitespace (lp);
632                   buf = atoi (lp);
633 
634                   if (buf < 0) {
635                     DBG (5, "sane_get_devices: config option \"padded-read\" "
636                       "(%d) is < 0, ignoring!\n", buf);
637                     continue;
638                   }
639 
640                   if (buf > 1) {
641                     DBG (5, "sane_get_devices: config option \"padded-read\" "
642                       "(%d) is > 1, ignoring!\n", buf);
643                     continue;
644                   }
645 
646                   DBG (15, "sane_get_devices: setting \"padded-read\" to %d\n",
647                     buf);
648 
649                   global_padded_read = buf;
650               }
651 
652               /* EXTRA STATUS: we clamp to 0 or 1 */
653               else if (!strncmp (lp, "extra-status", 12) && isspace (lp[12])) {
654 
655                   int buf;
656                   lp += 12;
657                   lp = sanei_config_skip_whitespace (lp);
658                   buf = atoi (lp);
659 
660                   if (buf < 0) {
661                     DBG (5, "sane_get_devices: config option \"extra-status\" "
662                       "(%d) is < 0, ignoring!\n", buf);
663                     continue;
664                   }
665 
666                   if (buf > 1) {
667                     DBG (5, "sane_get_devices: config option \"extra-status\" "
668                       "(%d) is > 1, ignoring!\n", buf);
669                     continue;
670                   }
671 
672                   DBG (15, "sane_get_devices: setting \"extra-status\" to %d\n",
673                     buf);
674 
675                   global_extra_status = buf;
676               }
677 
678               /* DUPLEXOFFSET: < 2400 */
679               else if (!strncmp (lp, "duplex-offset", 13) && isspace (lp[13])) {
680 
681                   int buf;
682                   lp += 13;
683                   lp = sanei_config_skip_whitespace (lp);
684                   buf = atoi (lp);
685 
686                   if (buf > 2400) {
687                     DBG (5, "sane_get_devices: config option \"duplex-offset\" "
688                       "(%d) is > 2400, ignoring!\n", buf);
689                     continue;
690                   }
691 
692                   if (buf < 0) {
693                     DBG (5, "sane_get_devices: config option \"duplex-offset\" "
694                       "(%d) is < 0, ignoring!\n", buf);
695                     continue;
696                   }
697 
698                   DBG (15, "sane_get_devices: setting \"duplex-offset\" to %d\n",
699                     buf);
700 
701                   global_duplex_offset = buf;
702               }
703 
704               /* INQUIRY_LENGTH: <= 0x30 */
705               else if (!strncmp (lp, "inquiry-length", 14) && isspace (lp[14])) {
706 
707                   int buf;
708                   lp += 14;
709                   lp = sanei_config_skip_whitespace (lp);
710                   buf = (int) strtol (lp,NULL,16);
711 
712                   if (buf > INQUIRY_std_max_len) {
713                     DBG (5, "sane_get_devices: config option \"inquiry-length\" "
714                       "(%#04x) is > %#04x, ignoring!\n", buf, INQUIRY_std_max_len);
715                     continue;
716                   }
717 
718                   if (buf < 0) {
719                     DBG (5, "sane_get_devices: config option \"inquiry-length\" "
720                       "(%#04x) is < 0, ignoring!\n", buf);
721                     continue;
722                   }
723 
724                   DBG (15, "sane_get_devices: setting \"inquiry-length\" to %#04x\n",
725                     buf);
726 
727                   global_inquiry_length = buf;
728               }
729 
730               /* VPD_LENGTH: <= 0x30 */
731               else if (!strncmp (lp, "vpd-length", 10) && isspace (lp[10])) {
732 
733                   int buf;
734                   lp += 10;
735                   lp = sanei_config_skip_whitespace (lp);
736                   buf = (int) strtol (lp,NULL,16);
737 
738                   if (buf > INQUIRY_vpd_max_len) {
739                     DBG (5, "sane_get_devices: config option \"vpd-length\" "
740                       "(%#04x) is > %#04x, ignoring!\n", buf, INQUIRY_vpd_max_len);
741                     continue;
742                   }
743 
744                   if (buf < 0) {
745                     DBG (5, "sane_get_devices: config option \"vpd-length\" "
746                       "(%#04x) is < 0, ignoring!\n", buf);
747                     continue;
748                   }
749 
750                   DBG (15, "sane_get_devices: setting \"vpd-length\" to %#04x\n",
751                     buf);
752 
753                   global_vpd_length = buf;
754               }
755 
756               /* TUR_TIMEOUT <= 60000 */
757               else if (!strncmp (lp, "tur-timeout", 11) && isspace (lp[11])) {
758 
759                   int buf;
760                   lp += 11;
761                   lp = sanei_config_skip_whitespace (lp);
762                   buf = atoi (lp);
763 
764                   if (buf > 60000) {
765                     DBG (5, "sane_get_devices: config option \"tur-timeout\" "
766                       "(%d) is > 60000, ignoring!\n", buf);
767                     continue;
768                   }
769 
770                   if (buf < 0) {
771                     DBG (5, "sane_get_devices: config option \"tur-timeout\" "
772                       "(%d) is < 0, ignoring!\n", buf);
773                     continue;
774                   }
775 
776                   DBG (15, "sane_get_devices: setting \"tur-timeout\" to %d\n",
777                     buf);
778 
779                   global_tur_timeout = buf;
780               }
781 
782               /* VENDOR: we ingest up to 8 bytes */
783               else if (!strncmp (lp, "vendor-name", 11) && isspace (lp[11])) {
784 
785                   lp += 11;
786                   lp = sanei_config_skip_whitespace (lp);
787                   strncpy(global_vendor_name, lp, 8);
788                   global_vendor_name[8] = 0;
789 
790                   DBG (15, "sane_get_devices: setting \"vendor-name\" to %s\n",
791                     global_vendor_name);
792               }
793 
794               /* MODEL: we ingest up to 16 bytes */
795               else if (!strncmp (lp, "model-name", 10) && isspace (lp[10])) {
796 
797                   lp += 10;
798                   lp = sanei_config_skip_whitespace (lp);
799                   strncpy(global_model_name, lp, 16);
800                   global_model_name[16] = 0;
801 
802                   DBG (15, "sane_get_devices: setting \"model-name\" to %s\n",
803                     global_model_name);
804               }
805 
806               /* VERSION: we ingest up to 4 bytes */
807               else if (!strncmp (lp, "version-name", 12) && isspace (lp[12])) {
808 
809                   lp += 12;
810                   lp = sanei_config_skip_whitespace (lp);
811                   strncpy(global_version_name, lp, 4);
812                   global_version_name[4] = 0;
813 
814                   DBG (15, "sane_get_devices: setting \"version-name\" to %s\n",
815                     global_version_name);
816               }
817 
818               else {
819                   DBG (5, "sane_get_devices: config option \"%s\" unrecognized "
820                   "- ignored.\n", lp);
821               }
822           }
823           else if ((strncmp ("usb", lp, 3) == 0) && isspace (lp[3])) {
824               DBG (15, "sane_get_devices: looking for '%s'\n", lp);
825               sanei_usb_attach_matching_devices(lp, attach_one_usb);
826 
827               /* re-default these after reading the usb line */
828               default_globals();
829           }
830           else if ((strncmp ("scsi", lp, 4) == 0) && isspace (lp[4])) {
831               DBG (15, "sane_get_devices: looking for '%s'\n", lp);
832               sanei_config_attach_matching_devices (lp, attach_one_scsi);
833 
834               /* re-default these after reading the scsi line */
835               default_globals();
836           }
837           else{
838               DBG (5, "sane_get_devices: config line \"%s\" unrecognized - "
839               "ignored.\n", lp);
840           }
841       }
842       fclose (fp);
843   }
844 
845   else {
846       DBG (5, "sane_get_devices: missing required config file '%s'!\n",
847         CANON_DR_CONFIG_FILE);
848   }
849 
850   /*delete missing scanners from list*/
851   for (s = scanner_devList; s;) {
852     if(s->missing){
853       DBG (5, "sane_get_devices: missing scanner %s\n",s->device_name);
854 
855       /*splice s out of list by changing pointer in prev to next*/
856       if(prev){
857         prev->next = s->next;
858         free(s);
859         s=prev->next;
860       }
861       /*remove s from head of list, using prev to cache it*/
862       else{
863         prev = s;
864         s = s->next;
865         free(prev);
866 	prev=NULL;
867 
868 	/*reset head to next s*/
869 	scanner_devList = s;
870       }
871     }
872     else{
873       prev = s;
874       s=prev->next;
875     }
876   }
877 
878   for (s = scanner_devList; s; s=s->next) {
879     DBG (15, "sane_get_devices: found scanner %s\n",s->device_name);
880     num_devices++;
881   }
882 
883   DBG (15, "sane_get_devices: found %d scanner(s)\n",num_devices);
884 
885   if (sane_devArray)
886     free (sane_devArray);
887 
888   sane_devArray = calloc (num_devices + 1, sizeof (SANE_Device*));
889   if (!sane_devArray)
890     return SANE_STATUS_NO_MEM;
891 
892   for (s = scanner_devList; s; s=s->next) {
893     sane_devArray[i++] = (SANE_Device *)&s->sane;
894   }
895   sane_devArray[i] = 0;
896 
897   if(device_list){
898       *device_list = sane_devArray;
899   }
900 
901   DBG (10, "sane_get_devices: finish\n");
902 
903   return ret;
904 }
905 
906 /* callbacks used by sane_get_devices */
907 static SANE_Status
attach_one_scsi(const char * device_name)908 attach_one_scsi (const char *device_name)
909 {
910   return attach_one(device_name,CONNECTION_SCSI);
911 }
912 
913 static SANE_Status
attach_one_usb(const char * device_name)914 attach_one_usb (const char *device_name)
915 {
916   return attach_one(device_name,CONNECTION_USB);
917 }
918 
919 /* build the scanner struct and link to global list
920  * unless struct is already loaded, then pretend
921  */
922 static SANE_Status
attach_one(const char * device_name,int connType)923 attach_one (const char *device_name, int connType)
924 {
925   struct scanner *s;
926   int ret;
927 
928   DBG (10, "attach_one: start\n");
929   DBG (15, "attach_one: looking for '%s'\n", device_name);
930 
931   for (s = scanner_devList; s; s = s->next) {
932     if (strcmp (s->device_name, device_name) == 0){
933       DBG (10, "attach_one: already attached!\n");
934       s->missing = 0;
935       return SANE_STATUS_GOOD;
936     }
937   }
938 
939   /* build a scanner struct to hold it */
940   if ((s = calloc (sizeof (*s), 1)) == NULL)
941     return SANE_STATUS_NO_MEM;
942 
943   /* config file settings */
944   s->buffer_size = global_buffer_size;
945   s->padded_read = global_padded_read;
946   s->extra_status = global_extra_status;
947   s->duplex_offset = global_duplex_offset;
948   s->inquiry_length = global_inquiry_length;
949   s->vpd_length = global_vpd_length;
950   s->tur_timeout = global_tur_timeout;
951 
952   /* copy the device name */
953   strcpy (s->device_name, device_name);
954 
955   /* connect the fd */
956   s->connection = connType;
957   s->fd = -1;
958   ret = connect_fd(s);
959   if(ret != SANE_STATUS_GOOD){
960     free (s);
961     return ret;
962   }
963 
964   /* query the device to load its vendor/model/version, */
965   /* if config file doesn't give all three */
966   if ( !strlen(global_vendor_name)
967     || !strlen(global_model_name)
968     || !strlen(global_version_name)
969   ){
970     ret = init_inquire (s);
971     if (ret != SANE_STATUS_GOOD) {
972       disconnect_fd(s);
973       free (s);
974       DBG (5, "attach_one: inquiry failed\n");
975       return ret;
976     }
977   }
978 
979   /* override any inquiry settings with those from config file */
980   if(strlen(global_vendor_name))
981     strcpy(s->vendor_name, global_vendor_name);
982   if(strlen(global_model_name))
983     strcpy(s->model_name, global_model_name);
984   if(strlen(global_version_name))
985     strcpy(s->version_name, global_version_name);
986 
987   /* load detailed specs/capabilities from the device */
988   /* if a model cannot support inquiry vpd, this function will die */
989   ret = init_vpd (s);
990   if (ret != SANE_STATUS_GOOD) {
991     disconnect_fd(s);
992     free (s);
993     DBG (5, "attach_one: vpd failed\n");
994     return ret;
995   }
996 
997   /* clean up the scanner struct based on model */
998   /* this is the big piece of model specific code */
999   ret = init_model (s);
1000   if (ret != SANE_STATUS_GOOD) {
1001     disconnect_fd(s);
1002     free (s);
1003     DBG (5, "attach_one: model failed\n");
1004     return ret;
1005   }
1006 
1007   /* this detects imprinters if they are available */
1008   ret = init_imprinters (s);
1009   if (ret != SANE_STATUS_GOOD) {
1010     DBG (5, "attach_one: errors while trying to detect optional imprinters, continuing\n");
1011   }
1012 
1013   /* enable/read the buttons */
1014   ret = init_panel (s);
1015   if (ret != SANE_STATUS_GOOD) {
1016     disconnect_fd(s);
1017     free (s);
1018     DBG (5, "attach_one: model failed\n");
1019     return ret;
1020   }
1021 
1022   /* enable/read the lifecycle counters */
1023   ret = init_counters (s);
1024   if (ret != SANE_STATUS_GOOD) {
1025     DBG (5, "attach_one: unable to detect lifecycle counters, continuing\n");
1026     return ret;
1027   }
1028 
1029   /* sets SANE option 'values' to good defaults */
1030   ret = init_user (s);
1031   if (ret != SANE_STATUS_GOOD) {
1032     disconnect_fd(s);
1033     free (s);
1034     DBG (5, "attach_one: user failed\n");
1035     return ret;
1036   }
1037 
1038   ret = init_options (s);
1039   if (ret != SANE_STATUS_GOOD) {
1040     disconnect_fd(s);
1041     free (s);
1042     DBG (5, "attach_one: options failed\n");
1043     return ret;
1044   }
1045 
1046   /* load strings into sane_device struct */
1047   s->sane.name = s->device_name;
1048   s->sane.vendor = s->vendor_name;
1049   s->sane.model = s->model_name;
1050   s->sane.type = "scanner";
1051 
1052   /* change name in sane_device struct if scanner has serial number
1053   ret = init_serial (s);
1054   if (ret == SANE_STATUS_GOOD) {
1055     s->sane.name = s->serial_name;
1056   }
1057   else{
1058     DBG (5, "attach_one: serial number unsupported?\n");
1059   }
1060   */
1061 
1062   /* we close the connection, so that another backend can talk to scanner */
1063   disconnect_fd(s);
1064 
1065   /* store this scanner in global vars */
1066   s->next = scanner_devList;
1067   scanner_devList = s;
1068 
1069   DBG (10, "attach_one: finish\n");
1070 
1071   return SANE_STATUS_GOOD;
1072 }
1073 
1074 /*
1075  * connect the fd in the scanner struct
1076  */
1077 static SANE_Status
connect_fd(struct scanner * s)1078 connect_fd (struct scanner *s)
1079 {
1080   SANE_Status ret;
1081   int buffer_size = s->buffer_size;
1082 
1083   DBG (10, "connect_fd: start\n");
1084 
1085   if(s->fd > -1){
1086     DBG (5, "connect_fd: already open\n");
1087     ret = SANE_STATUS_GOOD;
1088   }
1089   else if (s->connection == CONNECTION_USB) {
1090     DBG (15, "connect_fd: opening USB device (%s)\n", s->device_name);
1091     ret = sanei_usb_open (s->device_name, &(s->fd));
1092     if(!ret){
1093       ret = sanei_usb_clear_halt(s->fd);
1094     }
1095   }
1096   else {
1097     DBG (15, "connect_fd: opening SCSI device (%s)\n", s->device_name);
1098     ret = sanei_scsi_open_extended (s->device_name, &(s->fd), sense_handler, s,
1099       &s->buffer_size);
1100     if(!ret && buffer_size != s->buffer_size){
1101       DBG (5, "connect_fd: cannot get requested buffer size (%d/%d)\n",
1102         buffer_size, s->buffer_size);
1103     }
1104   }
1105 
1106   if(ret == SANE_STATUS_GOOD){
1107 
1108     /* first generation usb scanners can get flaky if not closed
1109      * properly after last use. very first commands sent to device
1110      * must be prepared to correct this- see wait_scanner() */
1111     ret = wait_scanner(s);
1112     if (ret != SANE_STATUS_GOOD) {
1113       DBG (5, "connect_fd: could not wait_scanner\n");
1114       disconnect_fd(s);
1115     }
1116 
1117   }
1118   else{
1119     DBG (5, "connect_fd: could not open device: %d\n", ret);
1120   }
1121 
1122   DBG (10, "connect_fd: finish\n");
1123 
1124   return ret;
1125 }
1126 
1127 /*
1128  * This routine will check if a certain device is a Canon scanner
1129  * It also copies interesting data from INQUIRY into the handle structure
1130  */
1131 static SANE_Status
init_inquire(struct scanner * s)1132 init_inquire (struct scanner *s)
1133 {
1134   int i;
1135   SANE_Status ret;
1136 
1137   unsigned char cmd[INQUIRY_len];
1138   size_t cmdLen = INQUIRY_len;
1139 
1140   unsigned char in[INQUIRY_std_max_len];
1141   size_t inLen = s->inquiry_length;
1142 
1143   DBG (10, "init_inquire: start\n");
1144 
1145   memset(cmd,0,cmdLen);
1146   set_SCSI_opcode(cmd, INQUIRY_code);
1147   set_IN_return_size (cmd, inLen);
1148   set_IN_evpd (cmd, 0);
1149   set_IN_page_code (cmd, 0);
1150 
1151   ret = do_cmd (
1152     s, 1, 0,
1153     cmd, cmdLen,
1154     NULL, 0,
1155     in, &inLen
1156   );
1157 
1158   if (ret != SANE_STATUS_GOOD){
1159     DBG (10, "init_inquire: failed: %d\n", ret);
1160     return ret;
1161   }
1162 
1163   if (get_IN_periph_devtype (in) != IN_periph_devtype_scanner){
1164     DBG (5, "The device at '%s' is not a scanner.\n", s->device_name);
1165     return SANE_STATUS_INVAL;
1166   }
1167 
1168   get_IN_vendor (in, s->vendor_name);
1169   get_IN_product (in, s->model_name);
1170   get_IN_version (in, s->version_name);
1171 
1172   s->vendor_name[8] = 0;
1173   s->model_name[16] = 0;
1174   s->version_name[4] = 0;
1175 
1176   /* gobble trailing spaces */
1177   for (i = 7; s->vendor_name[i] == ' ' && i >= 0; i--)
1178     s->vendor_name[i] = 0;
1179   for (i = 15; s->model_name[i] == ' ' && i >= 0; i--)
1180     s->model_name[i] = 0;
1181   for (i = 3; s->version_name[i] == ' ' && i >= 0; i--)
1182     s->version_name[i] = 0;
1183 
1184   /*check for vendor name*/
1185   if (strcmp ("CANON", s->vendor_name)) {
1186     DBG (5, "The device at '%s' is reported to be made by '%s'\n",
1187       s->device_name, s->vendor_name);
1188     DBG (5, "This backend only supports Canon products.\n");
1189     return SANE_STATUS_INVAL;
1190   }
1191 
1192   /*check for model name*/
1193   if (strncmp ("DR", s->model_name, 2)
1194    && strncmp ("CR", s->model_name, 2)
1195    && strncmp ("P-", s->model_name, 2)
1196    && strncmp ("R", s->model_name, 1)
1197   ) {
1198     DBG (5, "The device at '%s' is reported to be a '%s'\n",
1199       s->device_name, s->model_name);
1200     DBG (5, "This backend only supports Canon P-, CR & DR-series products.\n");
1201     return SANE_STATUS_INVAL;
1202   }
1203 
1204   DBG (15, "init_inquire: Found %s scanner %s version %s at %s\n",
1205     s->vendor_name, s->model_name, s->version_name, s->device_name);
1206 
1207   DBG (10, "init_inquire: finish\n");
1208 
1209   return SANE_STATUS_GOOD;
1210 }
1211 
1212 /*
1213  * Use INQUIRY VPD to setup more detail about the scanner
1214  */
1215 static SANE_Status
init_vpd(struct scanner * s)1216 init_vpd (struct scanner *s)
1217 {
1218   SANE_Status ret;
1219 
1220   unsigned char cmd[INQUIRY_len];
1221   size_t cmdLen = INQUIRY_len;
1222 
1223   unsigned char in[INQUIRY_vpd_max_len];
1224   size_t inLen = s->vpd_length;
1225 
1226   DBG (10, "init_vpd: start\n");
1227 
1228   /* get EVPD */
1229   memset(cmd,0,cmdLen);
1230   set_SCSI_opcode(cmd, INQUIRY_code);
1231   set_IN_return_size (cmd, inLen);
1232   set_IN_evpd (cmd, 1);
1233   set_IN_page_code (cmd, 0xf0);
1234 
1235   ret = do_cmd (
1236     s, 1, 0,
1237     cmd, cmdLen,
1238     NULL, 0,
1239     in, &inLen
1240   );
1241 
1242   DBG (15, "init_vpd: length=%0x\n",get_IN_page_length (in));
1243 
1244   /* This scanner supports vital product data.
1245    * Use this data to set dpi-lists etc. */
1246   if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) {
1247 
1248       DBG (15, "standard options\n");
1249 
1250       s->basic_x_res = get_IN_basic_x_res (in);
1251       DBG (15, "  basic x res: %d dpi\n",s->basic_x_res);
1252 
1253       s->basic_y_res = get_IN_basic_y_res (in);
1254       DBG (15, "  basic y res: %d dpi\n",s->basic_y_res);
1255 
1256       s->step_x_res = get_IN_step_x_res (in);
1257       DBG (15, "  step x res: %d dpi\n", s->step_x_res);
1258 
1259       s->step_y_res = get_IN_step_y_res (in);
1260       DBG (15, "  step y res: %d dpi\n", s->step_y_res);
1261 
1262       s->max_x_res = get_IN_max_x_res (in);
1263       DBG (15, "  max x res: %d dpi\n", s->max_x_res);
1264 
1265       s->max_y_res = get_IN_max_y_res (in);
1266       DBG (15, "  max y res: %d dpi\n", s->max_y_res);
1267 
1268       s->min_x_res = get_IN_min_x_res (in);
1269       DBG (15, "  min x res: %d dpi\n", s->min_x_res);
1270 
1271       s->min_y_res = get_IN_min_y_res (in);
1272       DBG (15, "  min y res: %d dpi\n", s->min_y_res);
1273 
1274       /* some scanners list B&W resolutions. */
1275       s->std_res_x[DPI_60] = get_IN_std_res_60 (in);
1276       s->std_res_y[DPI_60] = s->std_res_x[DPI_60];
1277       DBG (15, "  60 dpi: %d\n", s->std_res_x[DPI_60]);
1278 
1279       s->std_res_x[DPI_75] = get_IN_std_res_75 (in);
1280       s->std_res_y[DPI_75] = s->std_res_x[DPI_75];
1281       DBG (15, "  75 dpi: %d\n", s->std_res_x[DPI_75]);
1282 
1283       s->std_res_x[DPI_100] = get_IN_std_res_100 (in);
1284       s->std_res_y[DPI_100] = s->std_res_x[DPI_100];
1285       DBG (15, "  100 dpi: %d\n", s->std_res_x[DPI_100]);
1286 
1287       s->std_res_x[DPI_120] = get_IN_std_res_120 (in);
1288       s->std_res_y[DPI_120] = s->std_res_x[DPI_120];
1289       DBG (15, "  120 dpi: %d\n", s->std_res_x[DPI_120]);
1290 
1291       s->std_res_x[DPI_150] = get_IN_std_res_150 (in);
1292       s->std_res_y[DPI_150] = s->std_res_x[DPI_150];
1293       DBG (15, "  150 dpi: %d\n", s->std_res_x[DPI_150]);
1294 
1295       s->std_res_x[DPI_160] = get_IN_std_res_160 (in);
1296       s->std_res_y[DPI_160] = s->std_res_x[DPI_160];
1297       DBG (15, "  160 dpi: %d\n", s->std_res_x[DPI_160]);
1298 
1299       s->std_res_x[DPI_180] = get_IN_std_res_180 (in);
1300       s->std_res_y[DPI_180] = s->std_res_x[DPI_180];
1301       DBG (15, "  180 dpi: %d\n", s->std_res_x[DPI_180]);
1302 
1303       s->std_res_x[DPI_200] = get_IN_std_res_200 (in);
1304       s->std_res_y[DPI_200] = s->std_res_x[DPI_200];
1305       DBG (15, "  200 dpi: %d\n", s->std_res_x[DPI_200]);
1306 
1307       s->std_res_x[DPI_240] = get_IN_std_res_240 (in);
1308       s->std_res_y[DPI_240] = s->std_res_x[DPI_240];
1309       DBG (15, "  240 dpi: %d\n", s->std_res_x[DPI_240]);
1310 
1311       s->std_res_x[DPI_300] = get_IN_std_res_300 (in);
1312       s->std_res_y[DPI_300] = s->std_res_x[DPI_300];
1313       DBG (15, "  300 dpi: %d\n", s->std_res_x[DPI_300]);
1314 
1315       s->std_res_x[DPI_320] = get_IN_std_res_320 (in);
1316       s->std_res_y[DPI_320] = s->std_res_x[DPI_320];
1317       DBG (15, "  320 dpi: %d\n", s->std_res_x[DPI_320]);
1318 
1319       s->std_res_x[DPI_400] = get_IN_std_res_400 (in);
1320       s->std_res_y[DPI_400] = s->std_res_x[DPI_400];
1321       DBG (15, "  400 dpi: %d\n", s->std_res_x[DPI_400]);
1322 
1323       s->std_res_x[DPI_480] = get_IN_std_res_480 (in);
1324       s->std_res_y[DPI_480] = s->std_res_x[DPI_480];
1325       DBG (15, "  480 dpi: %d\n", s->std_res_x[DPI_480]);
1326 
1327       s->std_res_x[DPI_600] = get_IN_std_res_600 (in);
1328       s->std_res_y[DPI_600] = s->std_res_x[DPI_600];
1329       DBG (15, "  600 dpi: %d\n", s->std_res_x[DPI_600]);
1330 
1331       s->std_res_x[DPI_800] = get_IN_std_res_800 (in);
1332       s->std_res_y[DPI_800] = s->std_res_x[DPI_800];
1333       DBG (15, "  800 dpi: %d\n", s->std_res_x[DPI_800]);
1334 
1335       s->std_res_x[DPI_1200] = get_IN_std_res_1200 (in);
1336       s->std_res_y[DPI_1200] = s->std_res_x[DPI_1200];
1337       DBG (15, "  1200 dpi: %d\n", s->std_res_x[DPI_1200]);
1338 
1339       /* maximum window width and length are reported in basic units.*/
1340       s->max_x = get_IN_window_width(in) * 1200 / s->basic_x_res;
1341       DBG(15, "  max width: %d (%2.2f in)\n",s->max_x,(float)s->max_x/1200);
1342 
1343       s->max_y = get_IN_window_length(in) * 1200 / s->basic_y_res;
1344       DBG(15, "  max length: %d (%2.2f in)\n",s->max_y,(float)s->max_y/1200);
1345 
1346       DBG (15, "  AWD: %d\n", get_IN_awd(in));
1347       DBG (15, "  CE Emphasis: %d\n", get_IN_ce_emphasis(in));
1348       DBG (15, "  C Emphasis: %d\n", get_IN_c_emphasis(in));
1349       DBG (15, "  High quality: %d\n", get_IN_high_quality(in));
1350 
1351       /* known modes FIXME more here? */
1352       s->can_grayscale = get_IN_multilevel (in);
1353       DBG (15, "  grayscale: %d\n", s->can_grayscale);
1354 
1355       s->can_halftone = get_IN_half_tone (in);
1356       DBG (15, "  halftone: %d\n", s->can_halftone);
1357 
1358       s->can_monochrome = get_IN_monochrome (in);
1359       DBG (15, "  monochrome: %d\n", s->can_monochrome);
1360 
1361       s->can_overflow = get_IN_overflow(in);
1362       DBG (15, "  overflow: %d\n", s->can_overflow);
1363   }
1364   /*FIXME no vpd, set some defaults? */
1365   else{
1366     DBG (5, "init_vpd: Your scanner does not support VPD?\n");
1367     DBG (5, "init_vpd: Please contact kitno455 at gmail dot com\n");
1368     DBG (5, "init_vpd: with details of your scanner model.\n");
1369   }
1370 
1371   DBG (10, "init_vpd: finish\n");
1372 
1373   return ret;
1374 }
1375 
1376 /*
1377  * get model specific info that is not in vpd, and correct
1378  * errors in vpd data. struct is already initialized to 0.
1379  */
1380 static SANE_Status
init_model(struct scanner * s)1381 init_model (struct scanner *s)
1382 {
1383 
1384   DBG (10, "init_model: start\n");
1385 
1386   s->reverse_by_mode[MODE_LINEART] = 1;
1387   s->reverse_by_mode[MODE_HALFTONE] = 1;
1388   s->reverse_by_mode[MODE_GRAYSCALE] = 0;
1389   s->reverse_by_mode[MODE_COLOR] = 0;
1390 
1391   s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RGB;
1392   s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RGB;
1393 
1394   s->always_op = 1;
1395   s->has_df = 1;
1396   s->has_btc = 1;
1397   s->has_counter = 1;
1398   s->has_adf = 1;
1399   s->has_duplex = 1;
1400   s->has_buffer = 1;
1401   s->can_read_panel = 1;
1402   s->can_write_panel = 1;
1403   s->has_ssm = 1;
1404 
1405   s->brightness_steps = 255;
1406   s->contrast_steps = 255;
1407   s->threshold_steps = 255;
1408 
1409   s->ppl_mod = 1;
1410   s->bg_color = 0xee;
1411 
1412   /* assume these are same as adf, override below */
1413   s->valid_x = s->max_x;
1414   s->max_x_fb = s->max_x;
1415   s->max_y_fb = s->max_y;
1416 
1417   /* missing from vpd- we will unset these for some machines below */
1418   s->can_color = 1;
1419   s->can_read_lifecycle_counters = 1;
1420 
1421   /* specific settings missing from vpd */
1422   if (strstr (s->model_name,"DR-9080")){
1423     s->has_comp_JPEG = 1;
1424     s->rgb_format = 2;
1425   }
1426 
1427   else if (strstr (s->model_name,"DR-6080")
1428     || strstr (s->model_name,"DR-7580")){
1429     s->has_comp_JPEG = 1;
1430     s->can_color = 0;
1431   }
1432 
1433   else if (strstr (s->model_name,"DR-7090")){
1434     s->has_flatbed = 1;
1435   }
1436 
1437   else if (strstr (s->model_name,"DR-9050")
1438     || strstr (s->model_name,"DR-7550")
1439     || strstr (s->model_name,"DR-6050")
1440     || strstr (s->model_name,"DR-G1100")
1441     || strstr (s->model_name,"DR-G1130")
1442   ){
1443 
1444     /*missing*/
1445     s->std_res_x[DPI_100]=1;
1446     s->std_res_y[DPI_100]=1;
1447     s->std_res_x[DPI_150]=1;
1448     s->std_res_y[DPI_150]=1;
1449     s->std_res_x[DPI_200]=1;
1450     s->std_res_y[DPI_200]=1;
1451     s->std_res_x[DPI_240]=1;
1452     s->std_res_y[DPI_240]=1;
1453     s->std_res_x[DPI_300]=1;
1454     s->std_res_y[DPI_300]=1;
1455     s->std_res_x[DPI_400]=1;
1456     s->std_res_y[DPI_400]=1;
1457     s->std_res_x[DPI_600]=1;
1458     s->std_res_y[DPI_600]=1;
1459 
1460     /*weirdness*/
1461     s->has_ssm = 0;
1462     s->has_ssm2 = 1;
1463   }
1464 
1465   else if (strstr (s->model_name,"DR-4080")
1466     || strstr (s->model_name,"DR-4580")
1467     || strstr (s->model_name,"DR-7080")){
1468     s->has_flatbed = 1;
1469   }
1470 
1471   else if (strstr (s->model_name,"DR-2580")){
1472     s->invert_tly = 1;
1473     s->rgb_format = 1;
1474     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RRGGBB;
1475     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_rRgGbB;
1476     s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_gG;
1477     s->duplex_interlace = DUPLEX_INTERLACE_FBfb;
1478     s->need_ccal = 1;
1479     s->fcal_src = FCAL_SRC_SCAN;
1480     s->fcal_dest = FCAL_DEST_SW;
1481     /*s->duplex_offset = 432; now set in config file*/
1482     s->duplex_offset_side = SIDE_BACK;
1483 
1484     /*lies*/
1485     s->can_halftone=0;
1486     s->can_monochrome=0;
1487   }
1488 
1489   else if (strstr (s->model_name,"DR-2510")
1490    || strstr (s->model_name,"DR-2010")
1491   ){
1492     s->rgb_format = 1;
1493     s->always_op = 0;
1494     s->unknown_byte2 = 0x80;
1495     s->fixed_width = 1;
1496     s->valid_x = 8.5 * 1200;
1497     s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_2510;
1498     s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_2510;
1499     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_2510;
1500     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_2510;
1501     s->duplex_interlace = DUPLEX_INTERLACE_2510;
1502     /*s->duplex_offset = 400; now set in config file*/
1503     s->need_ccal = 1;
1504     s->fcal_src = FCAL_SRC_SCAN;
1505     s->fcal_dest = FCAL_DEST_SW;
1506     s->sw_lut = 1;
1507     /*s->invert_tly = 1;*/
1508 
1509     /*only in Y direction, so we trash them in X*/
1510     s->std_res_x[DPI_100]=0;
1511     s->std_res_x[DPI_150]=0;
1512     s->std_res_x[DPI_200]=0;
1513     s->std_res_x[DPI_240]=0;
1514     s->std_res_x[DPI_400]=0;
1515 
1516     /*lies*/
1517     s->can_halftone=0;
1518     s->can_monochrome=0;
1519   }
1520 
1521   else if (strstr (s->model_name,"R40")
1522   ){
1523 	/* confirmed */
1524     s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_C120;
1525     s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_C120;
1526     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_C120;
1527     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_C120;
1528     s->duplex_interlace = DUPLEX_INTERLACE_2510;
1529     /*s->duplex_offset = 320; now set in config file*/
1530     s->fixed_width = 1;
1531     s->need_ccal = 1;
1532     s->fcal_src = FCAL_SRC_SCAN;
1533     s->fcal_dest = FCAL_DEST_SW;
1534     s->rgb_format = 1;
1535     s->sw_lut = 1;
1536 
1537     /*only in Y direction, so we trash them in X*/
1538     s->std_res_x[DPI_100]=0;
1539     s->std_res_x[DPI_150]=0;
1540     s->std_res_x[DPI_200]=0;
1541     s->std_res_x[DPI_240]=0;
1542     s->std_res_x[DPI_400]=0;
1543 
1544     /* suspected settings */
1545     s->ccal_version = 3;
1546     s->has_df_ultra = 1;
1547   }
1548 
1549   /* copied from 2510, possibly incorrect */
1550   else if (strstr (s->model_name,"DR-3010")){
1551     s->rgb_format = 1;
1552     s->always_op = 0;
1553     s->unknown_byte2 = 0x80;
1554     s->fixed_width = 1;
1555     s->valid_x = 8.5 * 1200;
1556     s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_2510;
1557     s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_2510;
1558     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_2510;
1559     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_2510;
1560     s->duplex_interlace = DUPLEX_INTERLACE_2510;
1561     /*s->duplex_offset = 400; now set in config file*/
1562     s->need_ccal = 1;
1563     s->fcal_src = FCAL_SRC_SCAN;
1564     s->fcal_dest = FCAL_DEST_SW;
1565     s->sw_lut = 1;
1566     s->invert_tly = 1;
1567 
1568     /*only in Y direction, so we trash them in X*/
1569     s->std_res_x[DPI_100]=0;
1570     s->std_res_x[DPI_150]=0;
1571     s->std_res_x[DPI_200]=0;
1572     s->std_res_x[DPI_240]=0;
1573     s->std_res_x[DPI_400]=0;
1574 
1575     /*lies*/
1576     s->can_halftone=0;
1577     s->can_monochrome=0;
1578   }
1579 
1580   else if (strstr (s->model_name,"DR-2050")
1581    || strstr (s->model_name,"DR-2080")){
1582     s->can_write_panel = 0;
1583     s->has_df = 0;
1584     s->fixed_width = 1;
1585     s->even_Bpl = 1;
1586     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RRGGBB;
1587     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RRGGBB;
1588     s->duplex_interlace = DUPLEX_INTERLACE_FBfb;
1589     s->fcal_src = FCAL_SRC_HW;
1590     s->fcal_dest = FCAL_DEST_SW;
1591     s->bg_color = 0x08;
1592     /*s->duplex_offset = 840; now set in config file*/
1593     s->sw_lut = 1;
1594 
1595     /*lies*/
1596     s->can_halftone=0;
1597     s->can_monochrome=0;
1598   }
1599 
1600   else if (strstr (s->model_name,"DR-3080")){
1601     s->can_write_panel = 0;
1602     s->has_df = 0;
1603     s->has_btc = 0;
1604   }
1605 
1606   else if (strstr (s->model_name,"DR-5060F")){
1607     s->can_write_panel = 0;
1608     s->has_df = 0;
1609     s->has_btc = 0;
1610     s->ppl_mod = 32;
1611     s->reverse_by_mode[MODE_LINEART] = 0;
1612     s->reverse_by_mode[MODE_HALFTONE] = 0;
1613     s->can_color = 0;
1614   }
1615 
1616   else if (strstr (s->model_name,"DR-5020")){
1617     s->can_read_panel = 0;
1618     s->can_write_panel = 0;
1619     s->has_df = 0;
1620     s->has_btc = 0;
1621     s->ppl_mod = 32;
1622     s->reverse_by_mode[MODE_LINEART] = 0;
1623     s->reverse_by_mode[MODE_HALFTONE] = 0;
1624     s->can_color = 0;
1625   }
1626 
1627   /* all copied from P-215 */
1628   else if (strstr (s->model_name, "P-150")) {
1629     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_rRgGbB;
1630     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RRGGBB;
1631     s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_gG;
1632     s->duplex_interlace = DUPLEX_INTERLACE_FBfb;
1633     s->need_ccal = 1;
1634     s->invert_tly = 1;
1635     s->unknown_byte2 = 0x88;
1636     s->rgb_format = 1;
1637     s->has_ssm_pay_head_len = 1;
1638     s->ppl_mod = 8;
1639     s->ccal_version = 3;
1640     s->can_read_sensors = 1;
1641     s->has_card = 1;
1642   }
1643 
1644   else if (strstr (s->model_name, "P-208")
1645    || strstr (s->model_name,"DR-P208")){
1646     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RRGGBB;
1647     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_rRgGbB;
1648     s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_gG;
1649     s->duplex_interlace = DUPLEX_INTERLACE_FBfb;
1650     s->need_ccal = 1;
1651     s->fcal_src = FCAL_SRC_SCAN;
1652     s->fcal_dest = FCAL_DEST_SW;
1653     s->invert_tly = 1;
1654     s->unknown_byte2 = 0x88;
1655     s->rgb_format = 1;
1656     s->has_ssm_pay_head_len = 1;
1657     s->ppl_mod = 8;
1658     s->ccal_version = 3;
1659     s->can_read_sensors = 1;
1660   }
1661 
1662   else if (strstr (s->model_name, "P-215")
1663    || strstr (s->model_name,"DR-P215")){
1664     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_rRgGbB;
1665     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RRGGBB;
1666     s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_gG;
1667     s->duplex_interlace = DUPLEX_INTERLACE_FBfb;
1668     s->need_ccal = 1;
1669     s->invert_tly = 1;
1670     s->unknown_byte2 = 0x88;
1671     s->rgb_format = 1;
1672     s->has_ssm_pay_head_len = 1;
1673     s->ppl_mod = 8;
1674     s->ccal_version = 3;
1675     s->can_read_sensors = 1;
1676     s->has_card = 1;
1677   }
1678 
1679   else if (strstr (s->model_name,"DR-M160")){
1680 
1681     /*missing*/
1682     s->std_res_x[DPI_100]=1;
1683     s->std_res_y[DPI_100]=1;
1684     s->std_res_x[DPI_150]=1;
1685     s->std_res_y[DPI_150]=1;
1686     s->std_res_x[DPI_200]=1;
1687     s->std_res_y[DPI_200]=1;
1688     s->std_res_x[DPI_300]=1;
1689     s->std_res_y[DPI_300]=1;
1690     s->std_res_x[DPI_400]=1;
1691     s->std_res_y[DPI_400]=1;
1692     s->std_res_x[DPI_600]=1;
1693     s->std_res_y[DPI_600]=1;
1694 
1695     s->has_comp_JPEG = 1;
1696     s->rgb_format = 1;
1697     s->has_df_ultra = 1;
1698 
1699     s->color_inter_by_res[DPI_100] = COLOR_INTERLACE_GBR;
1700     s->color_inter_by_res[DPI_150] = COLOR_INTERLACE_GBR;
1701     s->color_inter_by_res[DPI_200] = COLOR_INTERLACE_BRG;
1702     s->color_inter_by_res[DPI_400] = COLOR_INTERLACE_GBR;
1703 
1704     /*weirdness*/
1705     s->always_op = 0;
1706     s->fixed_width = 1;
1707     s->invert_tly = 1;
1708     s->can_write_panel = 0;
1709     s->has_ssm = 0;
1710     s->has_ssm2 = 1;
1711     s->duplex_interlace = DUPLEX_INTERLACE_FfBb;
1712     s->duplex_offset_side = SIDE_FRONT;
1713 
1714     /*lies*/
1715     s->can_halftone=0;
1716     s->can_monochrome=0;
1717   }
1718 
1719   else if (strstr (s->model_name,"DR-M140")){
1720 
1721     /*missing*/
1722     s->std_res_x[DPI_100]=1;
1723     s->std_res_y[DPI_100]=1;
1724     s->std_res_x[DPI_150]=1;
1725     s->std_res_y[DPI_150]=1;
1726     s->std_res_x[DPI_200]=1;
1727     s->std_res_y[DPI_200]=1;
1728     s->std_res_x[DPI_300]=1;
1729     s->std_res_y[DPI_300]=1;
1730     s->std_res_x[DPI_400]=1;
1731     s->std_res_y[DPI_400]=1;
1732     s->std_res_x[DPI_600]=1;
1733     s->std_res_y[DPI_600]=1;
1734 
1735     s->has_comp_JPEG = 1;
1736     s->rgb_format = 1;
1737     s->has_df_ultra = 1;
1738 
1739     s->color_inter_by_res[DPI_100] = COLOR_INTERLACE_GBR;
1740     s->color_inter_by_res[DPI_150] = COLOR_INTERLACE_GBR;
1741     s->color_inter_by_res[DPI_200] = COLOR_INTERLACE_BRG;
1742     s->color_inter_by_res[DPI_400] = COLOR_INTERLACE_GBR;
1743 
1744     /*weirdness*/
1745     s->always_op = 0;
1746     s->fixed_width = 1;
1747     s->invert_tly = 1;
1748     s->can_write_panel = 0;
1749     s->has_ssm = 0;
1750     s->has_ssm2 = 1;
1751     s->duplex_interlace = DUPLEX_INTERLACE_FfBb;
1752     s->duplex_offset_side = SIDE_BACK;
1753 
1754     /*lies*/
1755     s->can_halftone=0;
1756     s->can_monochrome=0;
1757   }
1758 
1759   else if (strstr (s->model_name,"DR-C120")
1760     || strstr (s->model_name,"DR-C130")
1761   ){
1762 
1763     /*confirmed settings*/
1764     s->need_ccal = 1;
1765     s->ccal_version = 3;
1766 
1767     s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_C120;
1768     s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_C120;
1769     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_C120;
1770     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_C120;
1771     s->duplex_interlace = DUPLEX_INTERLACE_2510;
1772     s->duplex_offset_side = SIDE_BACK;
1773     s->unknown_byte2 = 0x88;
1774     s->fcal_src = FCAL_SRC_SCAN;
1775     s->fcal_dest = FCAL_DEST_SW;
1776     s->sw_lut = 1;
1777     s->rgb_format = 1;
1778     /*s->duplex_offset = 400; now set in config file*/
1779 
1780     /*only in Y direction, so we trash them in X*/
1781     s->std_res_x[DPI_100]=0;
1782     s->std_res_x[DPI_150]=0;
1783     s->std_res_x[DPI_200]=0;
1784     s->std_res_x[DPI_240]=0;
1785     s->std_res_x[DPI_400]=0;
1786 
1787     /*suspected settings*/
1788     s->always_op = 0;
1789     s->fixed_width = 1;
1790     s->valid_x = 8.5 * 1200;
1791   }
1792   else if (strstr (s->model_name,"DR-C125")){
1793 
1794     /*confirmed settings*/
1795     s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_2510;
1796     s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_2510;
1797     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_2510;
1798     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_2510;
1799     s->duplex_interlace = DUPLEX_INTERLACE_2510;
1800     s->duplex_offset_side = SIDE_BACK;
1801     s->unknown_byte2 = 0x88;
1802     s->need_ccal = 1;
1803     s->ccal_version = 3;
1804     s->fcal_src = FCAL_SRC_SCAN;
1805     s->fcal_dest = FCAL_DEST_SW;
1806     s->sw_lut = 1;
1807     s->rgb_format = 1;
1808     /*s->duplex_offset = 400; now set in config file*/
1809 
1810     /*only in Y direction, so we trash them in X*/
1811     s->std_res_x[DPI_100]=0;
1812     s->std_res_x[DPI_150]=0;
1813     s->std_res_x[DPI_200]=0;
1814     s->std_res_x[DPI_240]=0;
1815     s->std_res_x[DPI_400]=0;
1816 
1817     /*suspected settings*/
1818     s->always_op = 0;
1819     s->fixed_width = 1;
1820     s->valid_x = 8.5 * 1200;
1821   }
1822 
1823   else if (strstr (s->model_name,"DR-C225")){
1824 
1825     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RRGGBB;
1826     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RRGGBB;
1827     s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_gG;
1828     s->duplex_interlace = DUPLEX_INTERLACE_PER_CHANNEL;
1829 
1830     s->unknown_byte2 = 0x88;
1831     s->need_ccal = 1;
1832     s->ccal_version = 3;
1833     s->fcal_src = FCAL_SRC_SCAN;
1834     s->fcal_dest = FCAL_DEST_HW;
1835     s->invert_tly = 1;
1836     s->rgb_format = 1;
1837     /*s->duplex_offset = 400; now set in config file*/
1838 
1839     /*only in Y direction, so we trash them in X*/
1840     s->std_res_x[DPI_100]=0;
1841     s->std_res_x[DPI_150]=0;
1842     s->std_res_x[DPI_200]=0;
1843     s->std_res_x[DPI_240]=0;
1844     s->std_res_x[DPI_400]=0;
1845 
1846     /*suspected settings*/
1847     s->always_op = 0;
1848     s->fixed_width = 1;
1849     s->valid_x = 8.5 * 1200;
1850   }
1851 
1852   else if (strstr (s->model_name,"DR-F120")){
1853     /* TODO items:
1854      * * has_rif = 0 ? is this correct
1855      * * has_comp_JPEG = 0 ? is this correct
1856      * * need_ccal = need_fcal = need_fcal_buffer = ccal_version = 0 ? is this correct
1857      */
1858 
1859     /* Required for USB coms */
1860     s->has_ssm = 0;
1861     s->has_ssm2 = 1;
1862 
1863     /*missing*/
1864     s->std_res_x[DPI_100] = 1;
1865     s->std_res_y[DPI_100] = 1;
1866     // DPI_150 not supported
1867     s->std_res_x[DPI_200] = 1;
1868     s->std_res_y[DPI_200] = 1;
1869     s->std_res_x[DPI_300] = 1;
1870     s->std_res_y[DPI_300] = 1;
1871     // DPI_400 not supported
1872     s->std_res_x[DPI_600]= 1;
1873     s->std_res_y[DPI_600] = 1;
1874     // DPI_1200 not supported
1875     // NOTE: This scanner supports higher resolutions
1876     // in the Y direction, but 600 is maximum in X
1877 
1878     // This is true however only the ADF is ever selected in hardware
1879     // FIXME: What extra option is needed to select this in the USB comms
1880     s->has_flatbed = 1;
1881 
1882     /* duplex */
1883     s->duplex_interlace = DUPLEX_INTERLACE_fFBb;
1884     s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_GBR;
1885     s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_GBR;
1886     s->color_inter_by_res[DPI_100] = COLOR_INTERLACE_RGB;
1887     s->color_inter_by_res[DPI_600] = COLOR_INTERLACE_RGB;
1888     s->duplex_offset_side = SIDE_BACK;
1889 
1890     /* weirdness */
1891     s->fixed_width = 1;
1892 
1893     /* lies */
1894     s->can_halftone = 0;
1895   }
1896 
1897   else if (strstr (s->model_name,"DR-X10C")){
1898     int i = 0;
1899 
1900     /* Required for USB coms */
1901     s->has_ssm = 0;
1902     s->has_ssm2 = 1;
1903 
1904     /* missing */
1905     s->std_res_x[DPI_100]=1;
1906     s->std_res_y[DPI_100]=1;
1907     s->std_res_x[DPI_150]=1;
1908     s->std_res_y[DPI_150]=1;
1909     s->std_res_x[DPI_200]=1;
1910     s->std_res_y[DPI_200]=1;
1911     s->std_res_x[DPI_240]=1;
1912     s->std_res_y[DPI_240]=1;
1913     s->std_res_x[DPI_300]=1;
1914     s->std_res_y[DPI_300]=1;
1915     s->std_res_x[DPI_400]=1;
1916     s->std_res_y[DPI_400]=1;
1917     s->std_res_x[DPI_600]=1;
1918     s->std_res_y[DPI_600]=1;
1919 
1920     s->has_hwcrop = 1;
1921 
1922     /*valid horizontal offsets for post-imprinter*/
1923     s->post_imprinter_h_offset_list[++i] = 21;
1924     s->post_imprinter_h_offset_list[++i] = 35;
1925     s->post_imprinter_h_offset_list[++i] = 47;
1926     s->post_imprinter_h_offset_list[++i] = 59;
1927     s->post_imprinter_h_offset_list[++i] = 72;
1928     s->post_imprinter_h_offset_list[++i] = 99;
1929     s->post_imprinter_h_offset_list[++i] = 114;
1930     s->post_imprinter_h_offset_list[++i] = 143;
1931     s->post_imprinter_h_offset_list[++i] = 155;
1932     s->post_imprinter_h_offset_list[++i] = 167;
1933     s->post_imprinter_h_offset_list[++i] = 196;
1934     s->post_imprinter_h_offset_list[++i] = 211;
1935     s->post_imprinter_h_offset_list[++i] = 239;
1936     s->post_imprinter_h_offset_list[++i] = 251;
1937     s->post_imprinter_h_offset_list[++i] = 263;
1938     s->post_imprinter_h_offset_list[++i] = 275;
1939     s->post_imprinter_h_offset_list[++i] = 289;
1940     s->post_imprinter_h_offset_list[0] = i;
1941 
1942     i = 0;
1943     /*valid horizontal offsets for pre-imprinter*/
1944     s->pre_imprinter_h_offset_list[++i] = 14;
1945     s->pre_imprinter_h_offset_list[++i] = 28;
1946     s->pre_imprinter_h_offset_list[++i] = 41;
1947     s->pre_imprinter_h_offset_list[++i] = 53;
1948     s->pre_imprinter_h_offset_list[++i] = 65;
1949     s->pre_imprinter_h_offset_list[++i] = 106;
1950     s->pre_imprinter_h_offset_list[0] = i;
1951 
1952     /*valid vertical offsets for imprinters*/
1953     s->imprinter_v_offset_range.min = 0;
1954     s->imprinter_v_offset_range.max = 500;
1955     s->imprinter_v_offset_range.quant = 1;
1956 
1957     i = 0;
1958     /*valid font angles for imprinters*/
1959     s->imprinter_font_angle_list[++i] = 0;
1960     s->imprinter_font_angle_list[++i] = 90;
1961     s->imprinter_font_angle_list[++i] = 180;
1962     s->imprinter_font_angle_list[++i] = 270;
1963     s->imprinter_font_angle_list[0] = i;
1964 
1965     i = 0;
1966     s->imprint_font_size_list[i++] = STRING_IMPRINTER_8x12_FONT;
1967     s->imprint_font_size_list[i++] = STRING_IMPRINTER_12x12_FONT;
1968     s->imprint_font_size_list[i] = NULL;
1969 
1970     i = 0;
1971     s->imprint_addon_mode_list[i++] = STRING_IMPRINTER_ADDON_BoI;
1972     s->imprint_addon_mode_list[i++] = STRING_IMPRINTER_ADDON_BoW;
1973     s->imprint_addon_mode_list[i++] = STRING_IMPRINTER_ADDON_WoB;
1974     s->imprint_addon_mode_list[i++] = STRING_NONE;
1975     s->imprint_addon_mode_list[i] = NULL;
1976   }
1977 
1978   DBG (10, "init_model: finish\n");
1979 
1980   return SANE_STATUS_GOOD;
1981 }
1982 
1983 /*
1984  * try to detect imprinters.
1985  */
1986 static SANE_Status
init_imprinters(struct scanner * s)1987 init_imprinters (struct scanner *s)
1988 {
1989   SANE_Status ret = SANE_STATUS_GOOD;
1990 
1991   s->has_pre_imprinter = 0;
1992   s->has_post_imprinter = 0;
1993 
1994   ret = detect_imprinter(s,R_PRE_IMPRINTER);
1995   if(ret != SANE_STATUS_GOOD){
1996     return ret;
1997   }
1998 
1999   ret = detect_imprinter(s,R_POST_IMPRINTER);
2000   if(ret != SANE_STATUS_GOOD){
2001     return ret;
2002   }
2003 
2004   return ret;
2005 }
2006 
2007 /*
2008  * This function enables the buttons and preloads the current panel values
2009  */
2010 static SANE_Status
init_panel(struct scanner * s)2011 init_panel (struct scanner *s)
2012 {
2013   SANE_Status ret = SANE_STATUS_GOOD;
2014 
2015   DBG (10, "init_panel: start\n");
2016 
2017   ret = read_panel(s,0);
2018   if(ret){
2019     DBG (5, "init_panel: disabling read_panel\n");
2020     s->can_read_panel = 0;
2021     ret = SANE_STATUS_GOOD;
2022   }
2023 
2024   s->panel_enable_led = 1;
2025   s->panel_counter = 0;
2026   ret = send_panel(s);
2027   if(ret){
2028     DBG (5, "init_panel: disabling send_panel\n");
2029     s->can_write_panel = 0;
2030     ret = SANE_STATUS_GOOD;
2031   }
2032 
2033   DBG (10, "init_panel: finish\n");
2034 
2035   return ret;
2036 }
2037 
2038 /*
2039  * This function disables the lifecycle counters if not available
2040  */
2041 static SANE_Status
init_counters(struct scanner * s)2042 init_counters (struct scanner *s)
2043 {
2044   SANE_Status ret = SANE_STATUS_GOOD;
2045 
2046   DBG (10, "init_counters: start\n");
2047 
2048   ret = read_counters(s);
2049   if(ret){
2050     DBG (5, "init_counters: disabling lifecycle counters\n");
2051     s->can_read_lifecycle_counters = 0;
2052     return ret;
2053   }
2054 
2055   DBG (10, "init_counters: finish\n");
2056 
2057   return ret;
2058 }
2059 
2060 /*
2061  * set good default user values.
2062  * struct is already initialized to 0.
2063  */
2064 static SANE_Status
init_user(struct scanner * s)2065 init_user (struct scanner *s)
2066 {
2067 
2068   DBG (10, "init_user: start\n");
2069 
2070   /* source */
2071   if(s->has_flatbed)
2072     s->u.source = SOURCE_FLATBED;
2073   else if(s->has_adf)
2074     s->u.source = SOURCE_ADF_FRONT;
2075   else if(s->has_card)
2076     s->u.source = SOURCE_CARD_FRONT;
2077 
2078   /* scan mode */
2079   if(s->can_monochrome)
2080     s->u.mode=MODE_LINEART;
2081   else if(s->can_halftone)
2082     s->u.mode=MODE_HALFTONE;
2083   else if(s->can_grayscale)
2084     s->u.mode=MODE_GRAYSCALE;
2085   else if(s->can_color)
2086     s->u.mode=MODE_COLOR;
2087 
2088   /*x and y res*/
2089   s->u.dpi_x = s->basic_x_res;
2090   s->u.dpi_y = s->basic_x_res;
2091 
2092   /* page width US-Letter */
2093   s->u.page_x = 8.5 * 1200;
2094   if(s->u.page_x > s->valid_x){
2095     s->u.page_x = s->valid_x;
2096   }
2097 
2098   /* page height US-Letter */
2099   s->u.page_y = 11 * 1200;
2100   if(s->u.page_y > s->max_y){
2101     s->u.page_y = s->max_y;
2102   }
2103 
2104   /* bottom-right x */
2105   s->u.br_x = s->u.page_x;
2106 
2107   /* bottom-right y */
2108   s->u.br_y = s->u.page_y;
2109 
2110   s->threshold = 90;
2111   s->compress_arg = 50;
2112 
2113   s->pre_imprint.h_offset = 65;
2114   s->post_imprint.h_offset = 155;
2115   s->post_imprint_addon_mode = ADDON_BoI;
2116 
2117   DBG (10, "init_user: finish\n");
2118 
2119   return SANE_STATUS_GOOD;
2120 }
2121 
2122 /*
2123  * This function presets the "option" array to blank
2124  */
2125 static SANE_Status
init_options(struct scanner * s)2126 init_options (struct scanner *s)
2127 {
2128   int i;
2129 
2130   DBG (10, "init_options: start\n");
2131 
2132   memset (s->opt, 0, sizeof (s->opt));
2133   for (i = 0; i < NUM_OPTIONS; ++i) {
2134       s->opt[i].name = "filler";
2135       s->opt[i].size = sizeof (SANE_Word);
2136       s->opt[i].cap = SANE_CAP_INACTIVE;
2137   }
2138 
2139   /* go ahead and setup the first opt, because
2140    * frontend may call control_option on it
2141    * before calling get_option_descriptor
2142    */
2143   s->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS;
2144   s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
2145   s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
2146   s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
2147   s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
2148 
2149   DBG (10, "init_options: finish\n");
2150 
2151   return SANE_STATUS_GOOD;
2152 }
2153 
2154 /*
2155  * From the SANE spec:
2156  * This function is used to establish a connection to a particular
2157  * device. The name of the device to be opened is passed in argument
2158  * name. If the call completes successfully, a handle for the device
2159  * is returned in *h. As a special case, specifying a zero-length
2160  * string as the device requests opening the first available device
2161  * (if there is such a device).
2162  */
2163 SANE_Status
sane_open(SANE_String_Const name,SANE_Handle * handle)2164 sane_open (SANE_String_Const name, SANE_Handle * handle)
2165 {
2166   struct scanner *dev = NULL;
2167   struct scanner *s = NULL;
2168   SANE_Status ret;
2169 
2170   DBG (10, "sane_open: start\n");
2171 
2172   if(scanner_devList){
2173     DBG (15, "sane_open: searching currently attached scanners\n");
2174   }
2175   else{
2176     DBG (15, "sane_open: no scanners currently attached, attaching\n");
2177 
2178     ret = sane_get_devices(NULL,0);
2179     if(ret != SANE_STATUS_GOOD){
2180       return ret;
2181     }
2182   }
2183 
2184   if(name[0] == 0){
2185     DBG (15, "sane_open: no device requested, using default\n");
2186     s = scanner_devList;
2187   }
2188   else{
2189     DBG (15, "sane_open: device %s requested\n", name);
2190 
2191     for (dev = scanner_devList; dev; dev = dev->next) {
2192       if (strcmp (dev->sane.name, name) == 0
2193        || strcmp (dev->device_name, name) == 0) { /*always allow sanei devname*/
2194         s = dev;
2195         break;
2196       }
2197     }
2198   }
2199 
2200   if (!s) {
2201     DBG (5, "sane_open: no device found\n");
2202     return SANE_STATUS_INVAL;
2203   }
2204 
2205   DBG (15, "sane_open: device %s found\n", s->sane.name);
2206 
2207   *handle = s;
2208 
2209   /* connect the fd so we can talk to scanner */
2210   ret = connect_fd(s);
2211   if(ret != SANE_STATUS_GOOD){
2212     return ret;
2213   }
2214 
2215   DBG (10, "sane_open: finish\n");
2216 
2217   return SANE_STATUS_GOOD;
2218 }
2219 
2220 /*
2221  * @@ Section 3 - SANE Options functions
2222  */
2223 
2224 /*
2225  * Returns the options we know.
2226  *
2227  * From the SANE spec:
2228  * This function is used to access option descriptors. The function
2229  * returns the option descriptor for option number n of the device
2230  * represented by handle h. Option number 0 is guaranteed to be a
2231  * valid option. Its value is an integer that specifies the number of
2232  * options that are available for device handle h (the count includes
2233  * option 0). If n is not a valid option index, the function returns
2234  * NULL. The returned option descriptor is guaranteed to remain valid
2235  * (and at the returned address) until the device is closed.
2236  */
2237 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)2238 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
2239 {
2240   struct scanner *s = handle;
2241   int i;
2242   SANE_Option_Descriptor *opt = &s->opt[option];
2243 
2244   DBG (20, "sane_get_option_descriptor: %d\n", option);
2245 
2246   if ((unsigned) option >= NUM_OPTIONS)
2247     return NULL;
2248 
2249   /* "Mode" group -------------------------------------------------------- */
2250   if(option==OPT_STANDARD_GROUP){
2251     opt->name = SANE_NAME_STANDARD;
2252     opt->title = SANE_TITLE_STANDARD;
2253     opt->desc = SANE_DESC_STANDARD;
2254     opt->type = SANE_TYPE_GROUP;
2255     opt->constraint_type = SANE_CONSTRAINT_NONE;
2256   }
2257 
2258   /* source */
2259   if(option==OPT_SOURCE){
2260     i=0;
2261     if(s->has_flatbed){
2262       s->source_list[i++]=STRING_FLATBED;
2263     }
2264     if(s->has_adf){
2265       s->source_list[i++]=STRING_ADFFRONT;
2266 
2267       if(s->has_back){
2268         s->source_list[i++]=STRING_ADFBACK;
2269       }
2270       if(s->has_duplex){
2271         s->source_list[i++]=STRING_ADFDUPLEX;
2272       }
2273     }
2274     if(s->has_card){
2275       s->source_list[i++]=STRING_CARDFRONT;
2276 
2277       if(s->has_back){
2278         s->source_list[i++]=STRING_CARDBACK;
2279       }
2280       if(s->has_duplex){
2281         s->source_list[i++]=STRING_CARDDUPLEX;
2282       }
2283     }
2284     s->source_list[i]=NULL;
2285 
2286     opt->name = SANE_NAME_SCAN_SOURCE;
2287     opt->title = SANE_TITLE_SCAN_SOURCE;
2288     opt->desc = SANE_DESC_SCAN_SOURCE;
2289     opt->type = SANE_TYPE_STRING;
2290     opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
2291     opt->constraint.string_list = s->source_list;
2292     opt->size = maxStringSize (opt->constraint.string_list);
2293     opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2294   }
2295 
2296   /* scan mode */
2297   if(option==OPT_MODE){
2298     i=0;
2299     if(s->can_monochrome || s->can_grayscale || s->can_color){
2300       s->mode_list[i++]=STRING_LINEART;
2301     }
2302     if(s->can_halftone){
2303       s->mode_list[i++]=STRING_HALFTONE;
2304     }
2305     if(s->can_grayscale || s->can_color){
2306       s->mode_list[i++]=STRING_GRAYSCALE;
2307     }
2308     if(s->can_color){
2309       s->mode_list[i++]=STRING_COLOR;
2310     }
2311     s->mode_list[i]=NULL;
2312 
2313     opt->name = SANE_NAME_SCAN_MODE;
2314     opt->title = SANE_TITLE_SCAN_MODE;
2315     opt->desc = SANE_DESC_SCAN_MODE;
2316     opt->type = SANE_TYPE_STRING;
2317     opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
2318     opt->constraint.string_list = s->mode_list;
2319     opt->size = maxStringSize (opt->constraint.string_list);
2320     opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2321   }
2322 
2323   /* resolution */
2324   /* some scanners only support fixed res
2325    * build a list of possible choices */
2326   /* we actually only look at the y resolution choices,
2327    * and interpolate the image data as required for limited x resolutions */
2328   if(option==OPT_RES){
2329     i=0;
2330     if(s->std_res_y[DPI_60] && s->max_y_res >= 60 && s->min_y_res <= 60){
2331       s->res_list[++i] = 60;
2332     }
2333     if(s->std_res_y[DPI_75] && s->max_y_res >= 75 && s->min_y_res <= 75){
2334       s->res_list[++i] = 75;
2335     }
2336     if(s->std_res_y[DPI_100] && s->max_y_res >= 100 && s->min_y_res <= 100){
2337       s->res_list[++i] = 100;
2338     }
2339     if(s->std_res_y[DPI_120] && s->max_y_res >= 120 && s->min_y_res <= 120){
2340       s->res_list[++i] = 120;
2341     }
2342     if(s->std_res_y[DPI_150] && s->max_y_res >= 150 && s->min_y_res <= 150){
2343       s->res_list[++i] = 150;
2344     }
2345     if(s->std_res_y[DPI_160] && s->max_y_res >= 160 && s->min_y_res <= 160){
2346       s->res_list[++i] = 160;
2347     }
2348     if(s->std_res_y[DPI_180] && s->max_y_res >= 180 && s->min_y_res <= 180){
2349       s->res_list[++i] = 180;
2350     }
2351     if(s->std_res_y[DPI_200] && s->max_y_res >= 200 && s->min_y_res <= 200){
2352       s->res_list[++i] = 200;
2353     }
2354     if(s->std_res_y[DPI_240] && s->max_y_res >= 240 && s->min_y_res <= 240){
2355       s->res_list[++i] = 240;
2356     }
2357     if(s->std_res_y[DPI_300] && s->max_y_res >= 300 && s->min_y_res <= 300){
2358       s->res_list[++i] = 300;
2359     }
2360     if(s->std_res_y[DPI_320] && s->max_y_res >= 320 && s->min_y_res <= 320){
2361       s->res_list[++i] = 320;
2362     }
2363     if(s->std_res_y[DPI_400] && s->max_y_res >= 400 && s->min_y_res <= 400){
2364       s->res_list[++i] = 400;
2365     }
2366     if(s->std_res_y[DPI_480] && s->max_y_res >= 480 && s->min_y_res <= 480){
2367       s->res_list[++i] = 480;
2368     }
2369     if(s->std_res_y[DPI_600] && s->max_y_res >= 600 && s->min_y_res <= 600){
2370       s->res_list[++i] = 600;
2371     }
2372     if(s->std_res_y[DPI_800] && s->max_y_res >= 800 && s->min_y_res <= 800){
2373       s->res_list[++i] = 800;
2374     }
2375     if(s->std_res_y[DPI_1200] && s->max_y_res >= 1200 && s->min_y_res <= 1200){
2376       s->res_list[++i] = 1200;
2377     }
2378     s->res_list[0] = i;
2379 
2380     opt->name = SANE_NAME_SCAN_RESOLUTION;
2381     opt->title = SANE_TITLE_SCAN_RESOLUTION;
2382     opt->desc = SANE_DESC_SCAN_RESOLUTION;
2383     opt->type = SANE_TYPE_INT;
2384     opt->unit = SANE_UNIT_DPI;
2385     opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2386 
2387     if(s->step_y_res){
2388       s->res_range.min = s->min_y_res;
2389       s->res_range.max = s->max_y_res;
2390       s->res_range.quant = s->step_y_res;
2391       opt->constraint_type = SANE_CONSTRAINT_RANGE;
2392       opt->constraint.range = &s->res_range;
2393     }
2394     else{
2395       opt->constraint_type = SANE_CONSTRAINT_WORD_LIST;
2396       opt->constraint.word_list = s->res_list;
2397     }
2398   }
2399 
2400   /* "Geometry" group ---------------------------------------------------- */
2401   if(option==OPT_GEOMETRY_GROUP){
2402     opt->name = SANE_NAME_GEOMETRY;
2403     opt->title = SANE_TITLE_GEOMETRY;
2404     opt->desc = SANE_DESC_GEOMETRY;
2405     opt->type = SANE_TYPE_GROUP;
2406     opt->constraint_type = SANE_CONSTRAINT_NONE;
2407   }
2408 
2409   /* top-left x */
2410   if(option==OPT_TL_X){
2411     /* values stored in 1200 dpi units */
2412     /* must be converted to MM for sane */
2413     s->tl_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x);
2414     s->tl_x_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_width(s));
2415     s->tl_x_range.quant = MM_PER_UNIT_FIX;
2416 
2417     opt->name = SANE_NAME_SCAN_TL_X;
2418     opt->title = SANE_TITLE_SCAN_TL_X;
2419     opt->desc = SANE_DESC_SCAN_TL_X;
2420     opt->type = SANE_TYPE_FIXED;
2421     opt->unit = SANE_UNIT_MM;
2422     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2423     opt->constraint.range = &(s->tl_x_range);
2424     opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2425   }
2426 
2427   /* top-left y */
2428   if(option==OPT_TL_Y){
2429     /* values stored in 1200 dpi units */
2430     /* must be converted to MM for sane */
2431     s->tl_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y);
2432     s->tl_y_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_height(s));
2433     s->tl_y_range.quant = MM_PER_UNIT_FIX;
2434 
2435     opt->name = SANE_NAME_SCAN_TL_Y;
2436     opt->title = SANE_TITLE_SCAN_TL_Y;
2437     opt->desc = SANE_DESC_SCAN_TL_Y;
2438     opt->type = SANE_TYPE_FIXED;
2439     opt->unit = SANE_UNIT_MM;
2440     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2441     opt->constraint.range = &(s->tl_y_range);
2442     opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2443   }
2444 
2445   /* bottom-right x */
2446   if(option==OPT_BR_X){
2447     /* values stored in 1200 dpi units */
2448     /* must be converted to MM for sane */
2449     s->br_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x);
2450     s->br_x_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_width(s));
2451     s->br_x_range.quant = MM_PER_UNIT_FIX;
2452 
2453     opt->name = SANE_NAME_SCAN_BR_X;
2454     opt->title = SANE_TITLE_SCAN_BR_X;
2455     opt->desc = SANE_DESC_SCAN_BR_X;
2456     opt->type = SANE_TYPE_FIXED;
2457     opt->unit = SANE_UNIT_MM;
2458     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2459     opt->constraint.range = &(s->br_x_range);
2460     opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2461   }
2462 
2463   /* bottom-right y */
2464   if(option==OPT_BR_Y){
2465     /* values stored in 1200 dpi units */
2466     /* must be converted to MM for sane */
2467     s->br_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y);
2468     s->br_y_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_height(s));
2469     s->br_y_range.quant = MM_PER_UNIT_FIX;
2470 
2471     opt->name = SANE_NAME_SCAN_BR_Y;
2472     opt->title = SANE_TITLE_SCAN_BR_Y;
2473     opt->desc = SANE_DESC_SCAN_BR_Y;
2474     opt->type = SANE_TYPE_FIXED;
2475     opt->unit = SANE_UNIT_MM;
2476     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2477     opt->constraint.range = &(s->br_y_range);
2478     opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2479   }
2480 
2481   /* page width */
2482   if(option==OPT_PAGE_WIDTH){
2483     /* values stored in 1200 dpi units */
2484     /* must be converted to MM for sane */
2485     s->paper_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x);
2486     s->paper_x_range.max = SCANNER_UNIT_TO_FIXED_MM(s->valid_x);
2487     s->paper_x_range.quant = MM_PER_UNIT_FIX;
2488 
2489     opt->name = SANE_NAME_PAGE_WIDTH;
2490     opt->title = SANE_TITLE_PAGE_WIDTH;
2491     opt->desc = SANE_DESC_PAGE_WIDTH;
2492     opt->type = SANE_TYPE_FIXED;
2493     opt->unit = SANE_UNIT_MM;
2494     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2495     opt->constraint.range = &s->paper_x_range;
2496 
2497     if(s->has_adf || s->has_card){
2498       opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2499       if(s->u.source == SOURCE_FLATBED){
2500         opt->cap |= SANE_CAP_INACTIVE;
2501       }
2502     }
2503     else{
2504       opt->cap = SANE_CAP_INACTIVE;
2505     }
2506   }
2507 
2508   /* page height */
2509   if(option==OPT_PAGE_HEIGHT){
2510     /* values stored in 1200 dpi units */
2511     /* must be converted to MM for sane */
2512     s->paper_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y);
2513     s->paper_y_range.max = SCANNER_UNIT_TO_FIXED_MM(s->max_y);
2514     s->paper_y_range.quant = MM_PER_UNIT_FIX;
2515 
2516     opt->name = SANE_NAME_PAGE_HEIGHT;
2517     opt->title = SANE_TITLE_PAGE_HEIGHT;
2518     opt->desc = SANE_DESC_PAGE_HEIGHT;
2519     opt->type = SANE_TYPE_FIXED;
2520     opt->unit = SANE_UNIT_MM;
2521     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2522     opt->constraint.range = &s->paper_y_range;
2523 
2524     if(s->has_adf || s->has_card){
2525       opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2526       if(s->u.source == SOURCE_FLATBED){
2527         opt->cap |= SANE_CAP_INACTIVE;
2528       }
2529     }
2530     else{
2531       opt->cap = SANE_CAP_INACTIVE;
2532     }
2533   }
2534 
2535   /* "Enhancement" group ------------------------------------------------- */
2536   if(option==OPT_ENHANCEMENT_GROUP){
2537     opt->name = SANE_NAME_ENHANCEMENT;
2538     opt->title = SANE_TITLE_ENHANCEMENT;
2539     opt->desc = SANE_DESC_ENHANCEMENT;
2540     opt->type = SANE_TYPE_GROUP;
2541     opt->constraint_type = SANE_CONSTRAINT_NONE;
2542   }
2543 
2544   /* brightness */
2545   if(option==OPT_BRIGHTNESS){
2546     opt->name = SANE_NAME_BRIGHTNESS;
2547     opt->title = SANE_TITLE_BRIGHTNESS;
2548     opt->desc = SANE_DESC_BRIGHTNESS;
2549     opt->type = SANE_TYPE_INT;
2550     opt->unit = SANE_UNIT_NONE;
2551     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2552     opt->constraint.range = &s->brightness_range;
2553     s->brightness_range.quant=1;
2554 
2555     /* some have hardware brightness (always 0 to 255?) */
2556     /* some use LUT or GT (-127 to +127)*/
2557     if (s->brightness_steps){
2558       s->brightness_range.min=-127;
2559       s->brightness_range.max=127;
2560       opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2561     }
2562     else{
2563       opt->cap = SANE_CAP_INACTIVE;
2564     }
2565   }
2566 
2567   /* contrast */
2568   if(option==OPT_CONTRAST){
2569     opt->name = SANE_NAME_CONTRAST;
2570     opt->title = SANE_TITLE_CONTRAST;
2571     opt->desc = SANE_DESC_CONTRAST;
2572     opt->type = SANE_TYPE_INT;
2573     opt->unit = SANE_UNIT_NONE;
2574     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2575     opt->constraint.range = &s->contrast_range;
2576     s->contrast_range.quant=1;
2577 
2578     /* some have hardware contrast (always 0 to 255?) */
2579     /* some use LUT or GT (-127 to +127)*/
2580     if (s->contrast_steps){
2581       s->contrast_range.min=-127;
2582       s->contrast_range.max=127;
2583       opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2584     }
2585     else {
2586       opt->cap = SANE_CAP_INACTIVE;
2587     }
2588   }
2589 
2590   /*threshold*/
2591   if(option==OPT_THRESHOLD){
2592     opt->name = SANE_NAME_THRESHOLD;
2593     opt->title = SANE_TITLE_THRESHOLD;
2594     opt->desc = SANE_DESC_THRESHOLD;
2595     opt->type = SANE_TYPE_INT;
2596     opt->unit = SANE_UNIT_NONE;
2597     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2598     opt->constraint.range = &s->threshold_range;
2599     s->threshold_range.min=0;
2600     s->threshold_range.max=s->threshold_steps;
2601     s->threshold_range.quant=1;
2602 
2603     if (s->threshold_steps){
2604       opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2605       if(s->u.mode != MODE_LINEART){
2606         opt->cap |= SANE_CAP_INACTIVE;
2607       }
2608     }
2609     else {
2610       opt->cap = SANE_CAP_INACTIVE;
2611     }
2612   }
2613 
2614   if(option==OPT_RIF){
2615     opt->name = "rif";
2616     opt->title = "RIF";
2617     opt->desc = "Reverse image format";
2618     opt->type = SANE_TYPE_BOOL;
2619     opt->unit = SANE_UNIT_NONE;
2620     if (s->has_rif)
2621       opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2622     else
2623       opt->cap = SANE_CAP_INACTIVE;
2624   }
2625 
2626   /* "Advanced" group ------------------------------------------------------ */
2627   if(option==OPT_ADVANCED_GROUP){
2628     opt->name = SANE_NAME_ADVANCED;
2629     opt->title = SANE_TITLE_ADVANCED;
2630     opt->desc = SANE_DESC_ADVANCED;
2631     opt->type = SANE_TYPE_GROUP;
2632     opt->constraint_type = SANE_CONSTRAINT_NONE;
2633   }
2634 
2635   /*image compression*/
2636   if(option==OPT_COMPRESS){
2637     i=0;
2638     s->compress_list[i++]=STRING_NONE;
2639 
2640     if(s->has_comp_JPEG){
2641 #ifndef SANE_JPEG_DISABLED
2642       s->compress_list[i++]=STRING_JPEG;
2643 #endif
2644     }
2645 
2646     s->compress_list[i]=NULL;
2647 
2648     opt->name = "compression";
2649     opt->title = "Compression";
2650     opt->desc = "Enable compressed data. May crash your front-end program";
2651     opt->type = SANE_TYPE_STRING;
2652     opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
2653     opt->constraint.string_list = s->compress_list;
2654     opt->size = maxStringSize (opt->constraint.string_list);
2655 
2656     if (i > 1){
2657       opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2658       if ( must_downsample(s) || s->s.mode < MODE_GRAYSCALE ){
2659         opt->cap |= SANE_CAP_INACTIVE;
2660       }
2661     }
2662     else
2663       opt->cap = SANE_CAP_INACTIVE;
2664   }
2665 
2666   /*image compression arg*/
2667   if(option==OPT_COMPRESS_ARG){
2668 
2669     opt->name = "compression-arg";
2670     opt->title = "Compression argument";
2671     opt->desc = "Level of JPEG compression. 1 is small file, 100 is large file.";
2672     opt->type = SANE_TYPE_INT;
2673     opt->unit = SANE_UNIT_NONE;
2674     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2675     opt->constraint.range = &s->compress_arg_range;
2676     s->compress_arg_range.quant=1;
2677 
2678     if(s->has_comp_JPEG){
2679       s->compress_arg_range.min=0;
2680       s->compress_arg_range.max=100;
2681       opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2682 
2683       if(s->compress != COMP_JPEG){
2684         opt->cap |= SANE_CAP_INACTIVE;
2685       }
2686     }
2687     else
2688       opt->cap = SANE_CAP_INACTIVE;
2689   }
2690 
2691   /*double feed by length*/
2692   if(option==OPT_DF_LENGTH){
2693     opt->name = "df-length";
2694     opt->title = "DF by length";
2695     opt->desc = "Detect double feeds by comparing document lengths";
2696     opt->type = SANE_TYPE_BOOL;
2697     opt->unit = SANE_UNIT_NONE;
2698     opt->constraint_type = SANE_CONSTRAINT_NONE;
2699 
2700     if (1)
2701      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2702     else
2703      opt->cap = SANE_CAP_INACTIVE;
2704   }
2705 
2706   /*double feed by thickness */
2707   if(option==OPT_DF_THICKNESS){
2708 
2709     opt->name = "df-thickness";
2710     opt->title = "DF by thickness";
2711     opt->desc = "Detect double feeds using thickness sensor";
2712     opt->type = SANE_TYPE_BOOL;
2713     opt->unit = SANE_UNIT_NONE;
2714     opt->constraint_type = SANE_CONSTRAINT_NONE;
2715 
2716     if (1){
2717      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2718     }
2719     else
2720      opt->cap = SANE_CAP_INACTIVE;
2721   }
2722 
2723   /*deskew by roller*/
2724   if(option==OPT_ROLLERDESKEW){
2725     opt->name = "rollerdeskew";
2726     opt->title = "Roller deskew";
2727     opt->desc = "Request scanner to correct skewed pages mechanically";
2728     opt->type = SANE_TYPE_BOOL;
2729     if (1)
2730      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2731     else
2732      opt->cap = SANE_CAP_INACTIVE;
2733   }
2734 
2735   /*deskew by software*/
2736   if(option==OPT_SWDESKEW){
2737     opt->name = "swdeskew";
2738     opt->title = "Software deskew";
2739     opt->desc = "Request driver to rotate skewed pages digitally";
2740     opt->type = SANE_TYPE_BOOL;
2741     if (1)
2742      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2743     else
2744      opt->cap = SANE_CAP_INACTIVE;
2745   }
2746 
2747   /*software despeckle radius*/
2748   if(option==OPT_SWDESPECK){
2749 
2750     opt->name = "swdespeck";
2751     opt->title = "Software despeckle diameter";
2752     opt->desc = "Maximum diameter of lone dots to remove from scan";
2753     opt->type = SANE_TYPE_INT;
2754     opt->unit = SANE_UNIT_NONE;
2755     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2756     opt->constraint.range = &s->swdespeck_range;
2757     s->swdespeck_range.quant=1;
2758 
2759     if(1){
2760       s->swdespeck_range.min=0;
2761       s->swdespeck_range.max=9;
2762       opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2763     }
2764     else
2765       opt->cap = SANE_CAP_INACTIVE;
2766   }
2767 
2768   /*crop by software*/
2769   if(option==OPT_SWCROP){
2770     opt->name = "swcrop";
2771     opt->title = "Software crop";
2772     opt->desc = "Request driver to remove border from pages digitally";
2773     opt->type = SANE_TYPE_BOOL;
2774     if (1)
2775      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2776     else
2777      opt->cap = SANE_CAP_INACTIVE;
2778   }
2779 
2780   /* Software blank page skip */
2781   if(option==OPT_SWSKIP){
2782 
2783     opt->name = "swskip";
2784     opt->title = SANE_I18N ("Software blank skip percentage");
2785     opt->desc = SANE_I18N("Request driver to discard pages with low percentage of dark pixels");
2786     opt->type = SANE_TYPE_FIXED;
2787     opt->unit = SANE_UNIT_PERCENT;
2788     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2789     opt->constraint.range = &s->swskip_range;
2790 
2791     s->swskip_range.quant=SANE_FIX(0.10001);
2792     s->swskip_range.min=SANE_FIX(0);
2793     s->swskip_range.max=SANE_FIX(100);
2794 
2795     opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2796   }
2797 
2798   /*staple detection*/
2799   if(option==OPT_STAPLEDETECT){
2800     opt->name = "stapledetect";
2801     opt->title = "Staple detect";
2802     opt->desc = "Request scanner to halt if stapled pages are detected";
2803     opt->type = SANE_TYPE_BOOL;
2804     if (1)
2805      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2806     else
2807      opt->cap = SANE_CAP_INACTIVE;
2808   }
2809 
2810   /*dropout color front*/
2811   if(option==OPT_DROPOUT_COLOR_F){
2812     s->do_color_list[0] = STRING_NONE;
2813     s->do_color_list[1] = STRING_RED;
2814     s->do_color_list[2] = STRING_GREEN;
2815     s->do_color_list[3] = STRING_BLUE;
2816     s->do_color_list[4] = STRING_EN_RED;
2817     s->do_color_list[5] = STRING_EN_GREEN;
2818     s->do_color_list[6] = STRING_EN_BLUE;
2819     s->do_color_list[7] = NULL;
2820 
2821     opt->name = "dropout-front";
2822     opt->title = "Dropout color front";
2823     opt->desc = "One-pass scanners use only one color during gray or binary scanning, useful for colored paper or ink";
2824     opt->type = SANE_TYPE_STRING;
2825     opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
2826     opt->constraint.string_list = s->do_color_list;
2827     opt->size = maxStringSize (opt->constraint.string_list);
2828 
2829     if (1){
2830       opt->cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT|SANE_CAP_ADVANCED;
2831       if(s->u.mode == MODE_COLOR)
2832         opt->cap |= SANE_CAP_INACTIVE;
2833     }
2834     else
2835       opt->cap = SANE_CAP_INACTIVE;
2836   }
2837 
2838   /*dropout color back*/
2839   if(option==OPT_DROPOUT_COLOR_B){
2840     s->do_color_list[0] = STRING_NONE;
2841     s->do_color_list[1] = STRING_RED;
2842     s->do_color_list[2] = STRING_GREEN;
2843     s->do_color_list[3] = STRING_BLUE;
2844     s->do_color_list[4] = STRING_EN_RED;
2845     s->do_color_list[5] = STRING_EN_GREEN;
2846     s->do_color_list[6] = STRING_EN_BLUE;
2847     s->do_color_list[7] = NULL;
2848 
2849     opt->name = "dropout-back";
2850     opt->title = "Dropout color back";
2851     opt->desc = "One-pass scanners use only one color during gray or binary scanning, useful for colored paper or ink";
2852     opt->type = SANE_TYPE_STRING;
2853     opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
2854     opt->constraint.string_list = s->do_color_list;
2855     opt->size = maxStringSize (opt->constraint.string_list);
2856 
2857     if (1){
2858       opt->cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT|SANE_CAP_ADVANCED;
2859       if(s->u.mode == MODE_COLOR)
2860         opt->cap |= SANE_CAP_INACTIVE;
2861     }
2862     else
2863       opt->cap = SANE_CAP_INACTIVE;
2864   }
2865 
2866   /*buffer mode*/
2867   if(option==OPT_BUFFERMODE){
2868     opt->name = "buffermode";
2869     opt->title = "Buffer mode";
2870     opt->desc = "Request scanner to read pages async into internal memory";
2871     opt->type = SANE_TYPE_BOOL;
2872     if (s->has_buffer)
2873      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2874     else
2875      opt->cap = SANE_CAP_INACTIVE;
2876   }
2877 
2878   if(option==OPT_SIDE){
2879     opt->name = "side";
2880     opt->title = "Duplex side";
2881     opt->desc = "Tells which side (0=front, 1=back) of a duplex scan the next call to sane_read will return.";
2882     opt->type = SANE_TYPE_BOOL;
2883     opt->unit = SANE_UNIT_NONE;
2884     opt->size = sizeof(SANE_Word);
2885     opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2886     opt->constraint_type = SANE_CONSTRAINT_NONE;
2887   }
2888 
2889   /*hardware crop*/
2890   if(option==OPT_HW_CROP){
2891     opt->name = "hwcrop";
2892     opt->title = "Hardware crop";
2893     opt->desc = "Request scanner to crop image automatically";
2894     opt->type = SANE_TYPE_BOOL;
2895     if (s->has_hwcrop)
2896      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2897     else
2898      opt->cap = SANE_CAP_INACTIVE;
2899   }
2900 
2901   /* "Imprinter" group --------------------------------------------------- */
2902   if(option==OPT_IMPRINT_GROUP){
2903     opt->name = "imprinter-options";
2904     opt->title = SANE_I18N ("Imprinter Options");
2905     opt->desc = SANE_I18N ("Controls for imprinter units");
2906     opt->type = SANE_TYPE_GROUP;
2907     opt->constraint_type = SANE_CONSTRAINT_NONE;
2908 
2909     /*flaming hack to get scanimage to hide group*/
2910     if ( !(s->has_pre_imprinter || s->has_post_imprinter) )
2911       opt->type = SANE_TYPE_BOOL;
2912   }
2913 
2914   if(option==OPT_PRE_IMPRINT_SPECSTRING){
2915     opt->name = "pre-imprint-string";
2916     opt->title = "Pre-Imprinter string";
2917     opt->desc = "String specifier for the pre-imprinter text";
2918     opt->type = SANE_TYPE_STRING;
2919     opt->size = IMPRINT_SPECSTRING_LEN;
2920     if (s->has_pre_imprinter)
2921      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2922     else
2923      opt->cap = SANE_CAP_INACTIVE;
2924   }
2925 
2926   if(option==OPT_PRE_IMPRINT_H_OFFSET){
2927     opt->name = "pre-imprint-h-offset";
2928     opt->title = "Pre-Imprinter horizontal offset";
2929     opt->desc = "Integer specifying the horizontal positioning of the pre-imprinter";
2930     opt->type = SANE_TYPE_INT;
2931     opt->unit = SANE_UNIT_MM;
2932     opt->size = sizeof(SANE_Word);
2933     opt->constraint_type = SANE_CONSTRAINT_WORD_LIST;
2934     opt->constraint.word_list = s->pre_imprinter_h_offset_list;
2935     if (s->has_pre_imprinter)
2936      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2937     else
2938      opt->cap = SANE_CAP_INACTIVE;
2939   }
2940 
2941   if(option==OPT_PRE_IMPRINT_V_OFFSET){
2942     opt->name = "pre-imprint-v-offset";
2943     opt->title = "Pre-Imprinter vertical offset";
2944     opt->desc = "Integer specifying the vertical positioning of the pre-imprinter";
2945     opt->type = SANE_TYPE_INT;
2946     opt->unit = SANE_UNIT_MM;
2947     opt->size = sizeof(SANE_Word);
2948     opt->constraint_type = SANE_CONSTRAINT_RANGE;
2949     opt->constraint.range = &s->imprinter_v_offset_range;
2950     if (s->has_pre_imprinter)
2951      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2952     else
2953      opt->cap = SANE_CAP_INACTIVE;
2954   }
2955 
2956   if(option==OPT_PRE_IMPRINT_FONT_SIZE){
2957     opt->name = "pre-imprint-font-size";
2958     opt->title = "Pre-Imprinter font size";
2959     opt->desc = "Integer specifying the pre-imprint font size";
2960     opt->type = SANE_TYPE_STRING;
2961     opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
2962     opt->constraint.string_list = s->imprint_font_size_list;
2963     opt->size = maxStringSize (opt->constraint.string_list);
2964     if (s->has_pre_imprinter)
2965      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2966     else
2967      opt->cap = SANE_CAP_INACTIVE;
2968   }
2969 
2970   if(option==OPT_PRE_IMPRINT_FONT_ROT){
2971     opt->name = "pre-imprint-font-rot";
2972     opt->title = "Pre-Imprinter font rotation";
2973     opt->desc = "Integer specifying the pre-imprint font rotation";
2974     opt->type = SANE_TYPE_INT;
2975     opt->unit = SANE_UNIT_NONE;
2976     opt->size = sizeof(SANE_Word);
2977     opt->constraint_type = SANE_CONSTRAINT_WORD_LIST;
2978     opt->constraint.word_list = s->imprinter_font_angle_list;
2979     if (s->has_pre_imprinter)
2980      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2981     else
2982      opt->cap = SANE_CAP_INACTIVE;
2983   }
2984 
2985   if(option==OPT_PRE_IMPRINT_SPACING){
2986     opt->name = "pre-imprint-spacing";
2987     opt->title = "Pre-Imprinter spacing";
2988     opt->desc = "Enables the pre-imprint extra spacing";
2989     opt->type = SANE_TYPE_BOOL;
2990     if (s->has_pre_imprinter)
2991      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
2992     else
2993      opt->cap = SANE_CAP_INACTIVE;
2994   }
2995 
2996   if(option==OPT_POST_IMPRINT_SPECSTRING){
2997     opt->name = "post-imprint-string";
2998     opt->title = "Post-Imprinter string";
2999     opt->desc = "String specifier for the post-imprinter text";
3000     opt->type = SANE_TYPE_STRING;
3001     opt->size = IMPRINT_SPECSTRING_LEN;
3002     if (s->has_post_imprinter)
3003      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3004     else
3005      opt->cap = SANE_CAP_INACTIVE;
3006   }
3007 
3008   if(option==OPT_POST_IMPRINT_H_OFFSET){
3009     opt->name = "post-imprint-h-offset";
3010     opt->title = "Post-Imprinter horizontal offset";
3011     opt->desc = "Integer specifying the horizontal positioning of the post-imprinter";
3012     opt->type = SANE_TYPE_INT;
3013     opt->unit = SANE_UNIT_MM;
3014     opt->size = sizeof(SANE_Word);
3015     opt->constraint_type = SANE_CONSTRAINT_WORD_LIST;
3016     opt->constraint.word_list = s->post_imprinter_h_offset_list;
3017     if (s->has_post_imprinter)
3018      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3019     else
3020      opt->cap = SANE_CAP_INACTIVE;
3021   }
3022 
3023   if(option==OPT_POST_IMPRINT_V_OFFSET){
3024     opt->name = "post-imprint-v-offset";
3025     opt->title = "Post-Imprinter vertical offset";
3026     opt->desc = "Integer specifying the vertical positioning of the post-imprinter";
3027     opt->type = SANE_TYPE_INT;
3028     opt->unit = SANE_UNIT_MM;
3029     opt->size = sizeof(SANE_Word);
3030     opt->constraint_type = SANE_CONSTRAINT_RANGE;
3031     opt->constraint.range = &s->imprinter_v_offset_range;
3032     if (s->has_post_imprinter)
3033      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3034     else
3035      opt->cap = SANE_CAP_INACTIVE;
3036   }
3037 
3038   if(option==OPT_POST_IMPRINT_FONT_SIZE){
3039     opt->name = "post-imprint-font-size";
3040     opt->title = "Post-Imprinter font size";
3041     opt->desc = "Integer specifying the post-imprint font size";
3042     opt->type = SANE_TYPE_STRING;
3043     opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3044     opt->constraint.string_list = s->imprint_font_size_list;
3045     opt->size = maxStringSize (opt->constraint.string_list);
3046     if (s->has_post_imprinter)
3047      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3048     else
3049      opt->cap = SANE_CAP_INACTIVE;
3050   }
3051 
3052   if(option==OPT_POST_IMPRINT_FONT_ROT){
3053     opt->name = "post-imprint-font-rot";
3054     opt->title = "Post-Imprinter font rotation";
3055     opt->desc = "Integer specifying the post-imprint font rotation";
3056     opt->type = SANE_TYPE_INT;
3057     opt->unit = SANE_UNIT_NONE;
3058     opt->size = sizeof(SANE_Word);
3059     opt->constraint_type = SANE_CONSTRAINT_WORD_LIST;
3060     opt->constraint.word_list = s->imprinter_font_angle_list;
3061     if (s->has_post_imprinter)
3062      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3063     else
3064      opt->cap = SANE_CAP_INACTIVE;
3065   }
3066 
3067   if(option==OPT_POST_IMPRINT_SPACING){
3068     opt->name = "post-imprint-spacing";
3069     opt->title = "Post-Imprinter spacing";
3070     opt->desc = "Enables the post-imprint extra spacing";
3071     opt->type = SANE_TYPE_BOOL;
3072     if (s->has_post_imprinter)
3073      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3074     else
3075      opt->cap = SANE_CAP_INACTIVE;
3076   }
3077 
3078   if(option==OPT_POST_IMPRINT_ADDON_MODE){
3079     opt->name = "post-imprint-addon-mode";
3080     opt->title = "Post-Imprinter addon mode";
3081     opt->desc = "Integer specifying the type of post-imprint addon rendered in the scanned image";
3082     opt->type = SANE_TYPE_STRING;
3083     opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
3084     opt->constraint.string_list = s->imprint_addon_mode_list;
3085     opt->size = maxStringSize (opt->constraint.string_list);
3086     if (s->has_post_imprinter)
3087      opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
3088     else
3089      opt->cap = SANE_CAP_INACTIVE;
3090   }
3091 
3092   /* "Sensor" group ------------------------------------------------------ */
3093   if(option==OPT_SENSOR_GROUP){
3094     opt->name = SANE_NAME_SENSORS;
3095     opt->title = SANE_TITLE_SENSORS;
3096     opt->desc = SANE_DESC_SENSORS;
3097     opt->type = SANE_TYPE_GROUP;
3098     opt->constraint_type = SANE_CONSTRAINT_NONE;
3099   }
3100 
3101   if(option==OPT_START){
3102     opt->name = "start";
3103     opt->title = "Start/1 button";
3104     opt->desc = "Big green or small 1 button";
3105     opt->type = SANE_TYPE_BOOL;
3106     opt->unit = SANE_UNIT_NONE;
3107     opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
3108     if(!s->can_read_panel)
3109       opt->cap = SANE_CAP_INACTIVE;
3110   }
3111 
3112   if(option==OPT_STOP){
3113     opt->name = "stop";
3114     opt->title = "Stop/2 button";
3115     opt->desc = "Small orange or small 2 button";
3116     opt->type = SANE_TYPE_BOOL;
3117     opt->unit = SANE_UNIT_NONE;
3118     opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
3119     if(!s->can_read_panel)
3120       opt->cap = SANE_CAP_INACTIVE;
3121   }
3122 
3123   if(option==OPT_BUTT3){
3124     opt->name = "button-3";
3125     opt->title = "3 button";
3126     opt->desc = "Small 3 button";
3127     opt->type = SANE_TYPE_BOOL;
3128     opt->unit = SANE_UNIT_NONE;
3129     opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
3130     if(!s->can_read_panel)
3131       opt->cap = SANE_CAP_INACTIVE;
3132   }
3133 
3134   if(option==OPT_NEWFILE){
3135     opt->name = "newfile";
3136     opt->title = "New File button";
3137     opt->desc = "New File button";
3138     opt->type = SANE_TYPE_BOOL;
3139     opt->unit = SANE_UNIT_NONE;
3140     opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
3141     if(!s->can_read_panel)
3142       opt->cap = SANE_CAP_INACTIVE;
3143   }
3144 
3145   if(option==OPT_COUNTONLY){
3146     opt->name = "countonly";
3147     opt->title = "Count Only button";
3148     opt->desc = "Count Only button";
3149     opt->type = SANE_TYPE_BOOL;
3150     opt->unit = SANE_UNIT_NONE;
3151     opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
3152     if(!s->can_read_panel)
3153       opt->cap = SANE_CAP_INACTIVE;
3154   }
3155 
3156   if(option==OPT_BYPASSMODE){
3157     opt->name = "bypassmode";
3158     opt->title = "Bypass Mode button";
3159     opt->desc = "Bypass Mode button";
3160     opt->type = SANE_TYPE_BOOL;
3161     opt->unit = SANE_UNIT_NONE;
3162     opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
3163     if(!s->can_read_panel)
3164       opt->cap = SANE_CAP_INACTIVE;
3165   }
3166 
3167   if(option==OPT_COUNTER){
3168     opt->name = "counter";
3169     opt->title = "Counter";
3170     opt->desc = "Scan counter";
3171     opt->type = SANE_TYPE_INT;
3172     opt->unit = SANE_UNIT_NONE;
3173     opt->constraint_type = SANE_CONSTRAINT_RANGE;
3174     opt->constraint.range = &s->counter_range;
3175     s->counter_range.min=0;
3176     s->counter_range.max=500;
3177     s->counter_range.quant=1;
3178 
3179     if (s->can_read_panel && s->has_counter)
3180      opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
3181     else
3182       opt->cap = SANE_CAP_INACTIVE;
3183   }
3184 
3185   if(option==OPT_ROLLERCOUNTER){
3186     opt->name = "roller-counter";
3187     opt->title = "Roller Counter";
3188     opt->desc = "Scans since last roller replacement";
3189     opt->type = SANE_TYPE_INT;
3190     opt->unit = SANE_UNIT_NONE;
3191     opt->constraint_type = SANE_CONSTRAINT_NONE;
3192 
3193     if (s->can_read_lifecycle_counters)
3194       opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
3195     else
3196       opt->cap = SANE_CAP_INACTIVE;
3197   }
3198 
3199   if(option==OPT_TOTALCOUNTER){
3200     opt->name = "total-counter";
3201     opt->title = "Total Counter";
3202     opt->desc = "Total scan count of the device";
3203     opt->type = SANE_TYPE_INT;
3204     opt->unit = SANE_UNIT_NONE;
3205     opt->constraint_type = SANE_CONSTRAINT_NONE;
3206 
3207     if (s->can_read_lifecycle_counters)
3208       opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
3209     else
3210       opt->cap = SANE_CAP_INACTIVE;
3211   }
3212 
3213   if(option==OPT_ADF_LOADED){
3214     opt->name = "adf-loaded";
3215     opt->title = "ADF Loaded";
3216     opt->desc = "Paper available in ADF input hopper";
3217     opt->type = SANE_TYPE_BOOL;
3218     opt->unit = SANE_UNIT_NONE;
3219     opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
3220     if(!s->can_read_sensors)
3221       opt->cap = SANE_CAP_INACTIVE;
3222   }
3223 
3224   if(option==OPT_CARD_LOADED){
3225     opt->name = "card-loaded";
3226     opt->title = "Card Loaded";
3227     opt->desc = "Paper available in card reader";
3228     opt->type = SANE_TYPE_BOOL;
3229     opt->unit = SANE_UNIT_NONE;
3230     opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
3231     if(!s->can_read_sensors || !s->has_card)
3232       opt->cap = SANE_CAP_INACTIVE;
3233   }
3234 
3235   return opt;
3236 }
3237 
3238 /**
3239  * Gets or sets an option value.
3240  *
3241  * From the SANE spec:
3242  * This function is used to set or inquire the current value of option
3243  * number n of the device represented by handle h. The manner in which
3244  * the option is controlled is specified by parameter action. The
3245  * possible values of this parameter are described in more detail
3246  * below.  The value of the option is passed through argument val. It
3247  * is a pointer to the memory that holds the option value. The memory
3248  * area pointed to by v must be big enough to hold the entire option
3249  * value (determined by member size in the corresponding option
3250  * descriptor).
3251  *
3252  * The only exception to this rule is that when setting the value of a
3253  * string option, the string pointed to by argument v may be shorter
3254  * since the backend will stop reading the option value upon
3255  * encountering the first NUL terminator in the string. If argument i
3256  * is not NULL, the value of *i will be set to provide details on how
3257  * well the request has been met.
3258  */
3259 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)3260 sane_control_option (SANE_Handle handle, SANE_Int option,
3261                      SANE_Action action, void *val, SANE_Int * info)
3262 {
3263   struct scanner *s = (struct scanner *) handle;
3264   SANE_Int dummy = 0;
3265   SANE_Status ret = SANE_STATUS_GOOD;
3266 
3267   /* Make sure that all those statements involving *info cannot break (better
3268    * than having to do "if (info) ..." everywhere!)
3269    */
3270   if (info == 0)
3271     info = &dummy;
3272 
3273   if (option >= NUM_OPTIONS) {
3274     DBG (5, "sane_control_option: %d too big\n", option);
3275     return SANE_STATUS_INVAL;
3276   }
3277 
3278   if (!SANE_OPTION_IS_ACTIVE (s->opt[option].cap)) {
3279     DBG (5, "sane_control_option: %d inactive\n", option);
3280     return SANE_STATUS_INVAL;
3281   }
3282 
3283   /*
3284    * SANE_ACTION_GET_VALUE: We have to find out the current setting and
3285    * return it in a human-readable form (often, text).
3286    */
3287   if (action == SANE_ACTION_GET_VALUE) {
3288       SANE_Word * val_p = (SANE_Word *) val;
3289 
3290       DBG (20, "sane_control_option: get value for '%s' (%d)\n", s->opt[option].name,option);
3291 
3292       switch (option) {
3293 
3294         case OPT_NUM_OPTS:
3295           *val_p = NUM_OPTIONS;
3296           return SANE_STATUS_GOOD;
3297 
3298         case OPT_SOURCE:
3299           if(s->u.source == SOURCE_FLATBED){
3300             strcpy (val, STRING_FLATBED);
3301           }
3302           else if(s->u.source == SOURCE_ADF_FRONT){
3303             strcpy (val, STRING_ADFFRONT);
3304           }
3305           else if(s->u.source == SOURCE_ADF_BACK){
3306             strcpy (val, STRING_ADFBACK);
3307           }
3308           else if(s->u.source == SOURCE_ADF_DUPLEX){
3309             strcpy (val, STRING_ADFDUPLEX);
3310           }
3311           else if(s->u.source == SOURCE_CARD_FRONT){
3312             strcpy (val, STRING_CARDFRONT);
3313           }
3314           else if(s->u.source == SOURCE_CARD_BACK){
3315             strcpy (val, STRING_CARDBACK);
3316           }
3317           else if(s->u.source == SOURCE_CARD_DUPLEX){
3318             strcpy (val, STRING_CARDDUPLEX);
3319           }
3320           return SANE_STATUS_GOOD;
3321 
3322         case OPT_MODE:
3323           if(s->u.mode == MODE_LINEART){
3324             strcpy (val, STRING_LINEART);
3325           }
3326           else if(s->u.mode == MODE_HALFTONE){
3327             strcpy (val, STRING_HALFTONE);
3328           }
3329           else if(s->u.mode == MODE_GRAYSCALE){
3330             strcpy (val, STRING_GRAYSCALE);
3331           }
3332           else if(s->u.mode == MODE_COLOR){
3333             strcpy (val, STRING_COLOR);
3334           }
3335           return SANE_STATUS_GOOD;
3336 
3337         case OPT_RES:
3338           *val_p = s->u.dpi_x;
3339           return SANE_STATUS_GOOD;
3340 
3341         case OPT_TL_X:
3342           *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.tl_x);
3343           return SANE_STATUS_GOOD;
3344 
3345         case OPT_TL_Y:
3346           *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.tl_y);
3347           return SANE_STATUS_GOOD;
3348 
3349         case OPT_BR_X:
3350           *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.br_x);
3351           return SANE_STATUS_GOOD;
3352 
3353         case OPT_BR_Y:
3354           *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.br_y);
3355           return SANE_STATUS_GOOD;
3356 
3357         case OPT_PAGE_WIDTH:
3358           *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.page_x);
3359           return SANE_STATUS_GOOD;
3360 
3361         case OPT_PAGE_HEIGHT:
3362           *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u.page_y);
3363           return SANE_STATUS_GOOD;
3364 
3365         case OPT_BRIGHTNESS:
3366           *val_p = s->brightness;
3367           return SANE_STATUS_GOOD;
3368 
3369         case OPT_CONTRAST:
3370           *val_p = s->contrast;
3371           return SANE_STATUS_GOOD;
3372 
3373         case OPT_THRESHOLD:
3374           *val_p = s->threshold;
3375           return SANE_STATUS_GOOD;
3376 
3377         case OPT_RIF:
3378           *val_p = s->rif;
3379           return SANE_STATUS_GOOD;
3380 
3381         /* Advanced Group */
3382         case OPT_COMPRESS:
3383           if(s->compress == COMP_JPEG){
3384             strcpy (val, STRING_JPEG);
3385           }
3386           else{
3387             strcpy (val, STRING_NONE);
3388           }
3389           return SANE_STATUS_GOOD;
3390 
3391         case OPT_COMPRESS_ARG:
3392           *val_p = s->compress_arg;
3393           return SANE_STATUS_GOOD;
3394 
3395         case OPT_DF_LENGTH:
3396           *val_p = s->df_length;
3397           return SANE_STATUS_GOOD;
3398 
3399         case OPT_DF_THICKNESS:
3400           *val_p = s->df_thickness;
3401           return SANE_STATUS_GOOD;
3402 
3403         case OPT_ROLLERDESKEW:
3404           *val_p = s->rollerdeskew;
3405           return SANE_STATUS_GOOD;
3406 
3407         case OPT_SWDESKEW:
3408           *val_p = s->swdeskew;
3409           return SANE_STATUS_GOOD;
3410 
3411         case OPT_SWDESPECK:
3412           *val_p = s->swdespeck;
3413           return SANE_STATUS_GOOD;
3414 
3415         case OPT_SWCROP:
3416           *val_p = s->swcrop;
3417           return SANE_STATUS_GOOD;
3418 
3419         case OPT_SWSKIP:
3420           *val_p = SANE_FIX(s->swskip);
3421           return SANE_STATUS_GOOD;
3422 
3423         case OPT_STAPLEDETECT:
3424           *val_p = s->stapledetect;
3425           return SANE_STATUS_GOOD;
3426 
3427         case OPT_DROPOUT_COLOR_F:
3428           switch (s->dropout_color[SIDE_FRONT]) {
3429             case COLOR_NONE:
3430               strcpy (val, STRING_NONE);
3431               break;
3432             case COLOR_RED:
3433               strcpy (val, STRING_RED);
3434               break;
3435             case COLOR_GREEN:
3436               strcpy (val, STRING_GREEN);
3437               break;
3438             case COLOR_BLUE:
3439               strcpy (val, STRING_BLUE);
3440               break;
3441             case COLOR_EN_RED:
3442               strcpy (val, STRING_EN_RED);
3443               break;
3444             case COLOR_EN_GREEN:
3445               strcpy (val, STRING_EN_GREEN);
3446               break;
3447             case COLOR_EN_BLUE:
3448               strcpy (val, STRING_EN_BLUE);
3449               break;
3450           }
3451           return SANE_STATUS_GOOD;
3452 
3453         case OPT_DROPOUT_COLOR_B:
3454           switch (s->dropout_color[SIDE_BACK]) {
3455             case COLOR_NONE:
3456               strcpy (val, STRING_NONE);
3457               break;
3458             case COLOR_RED:
3459               strcpy (val, STRING_RED);
3460               break;
3461             case COLOR_GREEN:
3462               strcpy (val, STRING_GREEN);
3463               break;
3464             case COLOR_BLUE:
3465               strcpy (val, STRING_BLUE);
3466               break;
3467             case COLOR_EN_RED:
3468               strcpy (val, STRING_EN_RED);
3469               break;
3470             case COLOR_EN_GREEN:
3471               strcpy (val, STRING_EN_GREEN);
3472               break;
3473             case COLOR_EN_BLUE:
3474               strcpy (val, STRING_EN_BLUE);
3475               break;
3476           }
3477           return SANE_STATUS_GOOD;
3478 
3479         case OPT_BUFFERMODE:
3480           *val_p = s->buffermode;
3481           return SANE_STATUS_GOOD;
3482 
3483         case OPT_SIDE:
3484           *val_p = s->side;
3485           return SANE_STATUS_GOOD;
3486 
3487         case OPT_HW_CROP:
3488           *val_p = s->hwcrop;
3489           return SANE_STATUS_GOOD;
3490 
3491         case OPT_PRE_IMPRINT_SPECSTRING:
3492           strcpy(val, s->pre_imprint.specstring);
3493           return SANE_STATUS_GOOD;
3494 
3495         case OPT_PRE_IMPRINT_H_OFFSET:
3496           *val_p = s->pre_imprint.h_offset;
3497           return SANE_STATUS_GOOD;
3498 
3499         case OPT_PRE_IMPRINT_V_OFFSET:
3500           *val_p = s->pre_imprint.v_offset;
3501           return SANE_STATUS_GOOD;
3502 
3503         case OPT_PRE_IMPRINT_FONT_SIZE:
3504           switch (s->pre_imprint.font_size){
3505             case IMPRINTER_12x12_FONT:
3506               strcpy(val, STRING_IMPRINTER_12x12_FONT);
3507               break;
3508 
3509             case IMPRINTER_8x12_FONT:
3510               strcpy(val, STRING_IMPRINTER_8x12_FONT);
3511               break;
3512           }
3513           return SANE_STATUS_GOOD;
3514 
3515         case OPT_PRE_IMPRINT_FONT_ROT:
3516           switch (s->pre_imprint.font_rot){
3517             case IMPRINTER_0_FONT_ROT:
3518               *val_p = 0;
3519               break;
3520 
3521             case IMPRINTER_90_FONT_ROT:
3522               *val_p = 90;
3523               break;
3524 
3525             case IMPRINTER_180_FONT_ROT:
3526               *val_p = 180;
3527               break;
3528 
3529             case IMPRINTER_270_FONT_ROT:
3530               *val_p = 270;
3531               break;
3532           }
3533           return SANE_STATUS_GOOD;
3534 
3535         case OPT_PRE_IMPRINT_SPACING:
3536           *val_p = s->pre_imprint.spacing;
3537           return SANE_STATUS_GOOD;
3538 
3539         case OPT_POST_IMPRINT_SPECSTRING:
3540           strcpy(val, s->post_imprint.specstring);
3541           return SANE_STATUS_GOOD;
3542 
3543         case OPT_POST_IMPRINT_H_OFFSET:
3544           *val_p = s->post_imprint.h_offset;
3545           return SANE_STATUS_GOOD;
3546 
3547         case OPT_POST_IMPRINT_V_OFFSET:
3548           *val_p = s->post_imprint.v_offset;
3549           return SANE_STATUS_GOOD;
3550 
3551         case OPT_POST_IMPRINT_FONT_SIZE:
3552           switch (s->post_imprint.font_size){
3553             case IMPRINTER_12x12_FONT:
3554               strcpy(val, STRING_IMPRINTER_12x12_FONT);
3555               break;
3556 
3557             case IMPRINTER_8x12_FONT:
3558               strcpy(val, STRING_IMPRINTER_8x12_FONT);
3559               break;
3560           }
3561           return SANE_STATUS_GOOD;
3562 
3563         case OPT_POST_IMPRINT_FONT_ROT:
3564           switch (s->post_imprint.font_rot){
3565             case IMPRINTER_0_FONT_ROT:
3566               *val_p = 0;
3567               break;
3568 
3569             case IMPRINTER_90_FONT_ROT:
3570               *val_p = 90;
3571               break;
3572 
3573             case IMPRINTER_180_FONT_ROT:
3574               *val_p = 180;
3575               break;
3576 
3577             case IMPRINTER_270_FONT_ROT:
3578               *val_p = 270;
3579               break;
3580           }
3581           return SANE_STATUS_GOOD;
3582 
3583         case OPT_POST_IMPRINT_SPACING:
3584           *val_p = s->post_imprint.spacing;
3585           return SANE_STATUS_GOOD;
3586 
3587         case OPT_POST_IMPRINT_ADDON_MODE:
3588           switch (s->post_imprint_addon_mode){
3589             case ADDON_BoW:
3590               strcpy(val, STRING_IMPRINTER_ADDON_BoW);
3591               break;
3592 
3593             case ADDON_BoI:
3594               strcpy(val, STRING_IMPRINTER_ADDON_BoI);
3595               break;
3596 
3597             case ADDON_WoB:
3598               strcpy(val, STRING_IMPRINTER_ADDON_WoB);
3599               break;
3600 
3601             case ADDON_DISABLED:
3602               strcpy(val, STRING_NONE);
3603               break;
3604           }
3605           return SANE_STATUS_GOOD;
3606 
3607         /* Sensor Group */
3608         case OPT_START:
3609           ret = read_panel(s,OPT_START);
3610           *val_p = s->panel_start;
3611           return ret;
3612 
3613         case OPT_STOP:
3614           ret = read_panel(s,OPT_STOP);
3615           *val_p = s->panel_stop;
3616           return ret;
3617 
3618         case OPT_BUTT3:
3619           ret = read_panel(s,OPT_BUTT3);
3620           *val_p = s->panel_butt3;
3621           return ret;
3622 
3623         case OPT_NEWFILE:
3624           ret = read_panel(s,OPT_NEWFILE);
3625           *val_p = s->panel_new_file;
3626           return ret;
3627 
3628         case OPT_COUNTONLY:
3629           ret = read_panel(s,OPT_COUNTONLY);
3630           *val_p = s->panel_count_only;
3631           return ret;
3632 
3633         case OPT_BYPASSMODE:
3634           ret = read_panel(s,OPT_BYPASSMODE);
3635           *val_p = s->panel_bypass_mode;
3636           return ret;
3637 
3638         case OPT_COUNTER:
3639           ret = read_panel(s,OPT_COUNTER);
3640           *val_p = s->panel_counter;
3641           return ret;
3642 
3643         case OPT_ROLLERCOUNTER:
3644           ret = read_counters(s);
3645           *val_p = s->roller_counter;
3646           return ret;
3647 
3648         case OPT_TOTALCOUNTER:
3649           ret = read_counters(s);
3650           *val_p = s->total_counter;
3651           return ret;
3652 
3653         case OPT_ADF_LOADED:
3654           ret = read_sensors(s,OPT_ADF_LOADED);
3655           *val_p = s->sensor_adf_loaded;
3656           return ret;
3657 
3658         case OPT_CARD_LOADED:
3659           ret = read_sensors(s,OPT_CARD_LOADED);
3660           *val_p = s->sensor_card_loaded;
3661           return ret;
3662       }
3663   }
3664   else if (action == SANE_ACTION_SET_VALUE) {
3665       int tmp;
3666       SANE_Word val_c;
3667       SANE_Status status;
3668 
3669       DBG (20, "sane_control_option: set value for '%s' (%d)\n", s->opt[option].name,option);
3670 
3671       if ( s->started ) {
3672         DBG (5, "sane_control_option: can't set, device busy\n");
3673         return SANE_STATUS_DEVICE_BUSY;
3674       }
3675 
3676       if (!SANE_OPTION_IS_SETTABLE (s->opt[option].cap)) {
3677         DBG (5, "sane_control_option: not settable\n");
3678         return SANE_STATUS_INVAL;
3679       }
3680 
3681       status = sanei_constrain_value (s->opt + option, val, info);
3682       if (status != SANE_STATUS_GOOD) {
3683         DBG (5, "sane_control_option: bad value\n");
3684         return status;
3685       }
3686 
3687       /* may have been changed by constrain, so don't copy until now */
3688       val_c = *(SANE_Word *)val;
3689 
3690       /*
3691        * Note - for those options which can assume one of a list of
3692        * valid values, we can safely assume that they will have
3693        * exactly one of those values because that's what
3694        * sanei_constrain_value does. Hence no "else: invalid" branches
3695        * below.
3696        */
3697       switch (option) {
3698 
3699         /* Mode Group */
3700         case OPT_SOURCE:
3701           if (!strcmp (val, STRING_ADFFRONT)) {
3702             tmp = SOURCE_ADF_FRONT;
3703           }
3704           else if (!strcmp (val, STRING_ADFBACK)) {
3705             tmp = SOURCE_ADF_BACK;
3706           }
3707           else if (!strcmp (val, STRING_ADFDUPLEX)) {
3708             tmp = SOURCE_ADF_DUPLEX;
3709           }
3710           else if (!strcmp (val, STRING_CARDFRONT)) {
3711             tmp = SOURCE_CARD_FRONT;
3712           }
3713           else if (!strcmp (val, STRING_CARDBACK)) {
3714             tmp = SOURCE_CARD_BACK;
3715           }
3716           else if (!strcmp (val, STRING_CARDDUPLEX)) {
3717             tmp = SOURCE_CARD_DUPLEX;
3718           }
3719           else{
3720             tmp = SOURCE_FLATBED;
3721           }
3722 
3723           if (s->u.source == tmp)
3724               return SANE_STATUS_GOOD;
3725 
3726           s->u.source = tmp;
3727 
3728           *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
3729           return SANE_STATUS_GOOD;
3730 
3731         case OPT_MODE:
3732           if (!strcmp (val, STRING_LINEART)) {
3733             tmp = MODE_LINEART;
3734           }
3735           else if (!strcmp (val, STRING_HALFTONE)) {
3736             tmp = MODE_HALFTONE;
3737           }
3738           else if (!strcmp (val, STRING_GRAYSCALE)) {
3739             tmp = MODE_GRAYSCALE;
3740           }
3741           else{
3742             tmp = MODE_COLOR;
3743           }
3744 
3745           if (tmp == s->u.mode)
3746               return SANE_STATUS_GOOD;
3747 
3748           s->u.mode = tmp;
3749 
3750           *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
3751           return SANE_STATUS_GOOD;
3752 
3753         case OPT_RES:
3754 
3755           if (s->u.dpi_x == val_c && s->u.dpi_y == val_c)
3756               return SANE_STATUS_GOOD;
3757 
3758           s->u.dpi_x = val_c;
3759           s->u.dpi_y = val_c;
3760 
3761           *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
3762           return SANE_STATUS_GOOD;
3763 
3764         /* Geometry Group */
3765         case OPT_TL_X:
3766           if (s->u.tl_x == FIXED_MM_TO_SCANNER_UNIT(val_c))
3767               return SANE_STATUS_GOOD;
3768 
3769           s->u.tl_x = FIXED_MM_TO_SCANNER_UNIT(val_c);
3770 
3771           *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
3772           return SANE_STATUS_GOOD;
3773 
3774         case OPT_TL_Y:
3775           if (s->u.tl_y == FIXED_MM_TO_SCANNER_UNIT(val_c))
3776               return SANE_STATUS_GOOD;
3777 
3778           s->u.tl_y = FIXED_MM_TO_SCANNER_UNIT(val_c);
3779 
3780           *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
3781           return SANE_STATUS_GOOD;
3782 
3783         case OPT_BR_X:
3784           if (s->u.br_x == FIXED_MM_TO_SCANNER_UNIT(val_c))
3785               return SANE_STATUS_GOOD;
3786 
3787           s->u.br_x = FIXED_MM_TO_SCANNER_UNIT(val_c);
3788 
3789           *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
3790           return SANE_STATUS_GOOD;
3791 
3792         case OPT_BR_Y:
3793           if (s->u.br_y == FIXED_MM_TO_SCANNER_UNIT(val_c))
3794               return SANE_STATUS_GOOD;
3795 
3796           s->u.br_y = FIXED_MM_TO_SCANNER_UNIT(val_c);
3797 
3798           *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
3799           return SANE_STATUS_GOOD;
3800 
3801         case OPT_PAGE_WIDTH:
3802           if (s->u.page_x == FIXED_MM_TO_SCANNER_UNIT(val_c))
3803               return SANE_STATUS_GOOD;
3804 
3805           /* if full width image, and paper size is changed,
3806              change the image size to match new paper */
3807           if (s->u.tl_x == 0 && s->u.br_x == s->u.page_x){
3808               DBG (20, "sane_control_option: br_x tracking page_width\n");
3809               s->u.br_x = FIXED_MM_TO_SCANNER_UNIT(val_c);
3810               *info |= SANE_INFO_RELOAD_PARAMS;
3811           }
3812 
3813           s->u.page_x = FIXED_MM_TO_SCANNER_UNIT(val_c);
3814 
3815           *info |= SANE_INFO_RELOAD_OPTIONS;
3816           return SANE_STATUS_GOOD;
3817 
3818         case OPT_PAGE_HEIGHT:
3819           if (s->u.page_y == FIXED_MM_TO_SCANNER_UNIT(val_c))
3820               return SANE_STATUS_GOOD;
3821 
3822           /* if full height image, and paper size is changed,
3823              change the image size to match new paper */
3824           if (s->u.tl_y == 0 && s->u.br_y == s->u.page_y){
3825               DBG (20, "sane_control_option: br_y tracking page_height\n");
3826               s->u.br_y = FIXED_MM_TO_SCANNER_UNIT(val_c);
3827               *info |= SANE_INFO_RELOAD_PARAMS;
3828           }
3829 
3830           s->u.page_y = FIXED_MM_TO_SCANNER_UNIT(val_c);
3831 
3832           *info |= SANE_INFO_RELOAD_OPTIONS;
3833           return SANE_STATUS_GOOD;
3834 
3835         /* Enhancement Group */
3836         case OPT_BRIGHTNESS:
3837           s->brightness = val_c;
3838           return SANE_STATUS_GOOD;
3839 
3840         case OPT_CONTRAST:
3841           s->contrast = val_c;
3842           return SANE_STATUS_GOOD;
3843 
3844         case OPT_THRESHOLD:
3845           s->threshold = val_c;
3846           return SANE_STATUS_GOOD;
3847 
3848         case OPT_RIF:
3849           s->rif = val_c;
3850           return SANE_STATUS_GOOD;
3851 
3852         /* Advanced Group */
3853         case OPT_COMPRESS:
3854           if (!strcmp (val, STRING_JPEG)) {
3855             s->compress = COMP_JPEG;
3856           }
3857           else{
3858             s->compress = COMP_NONE;
3859           }
3860           return SANE_STATUS_GOOD;
3861 
3862         case OPT_COMPRESS_ARG:
3863           s->compress_arg = val_c;
3864           return SANE_STATUS_GOOD;
3865 
3866         case OPT_DF_LENGTH:
3867           s->df_length = val_c;
3868           return SANE_STATUS_GOOD;
3869 
3870         case OPT_DF_THICKNESS:
3871           s->df_thickness = val_c;
3872           return SANE_STATUS_GOOD;
3873 
3874         case OPT_ROLLERDESKEW:
3875           s->rollerdeskew = val_c;
3876           return SANE_STATUS_GOOD;
3877 
3878         case OPT_SWDESKEW:
3879           s->swdeskew = val_c;
3880           return SANE_STATUS_GOOD;
3881 
3882         case OPT_SWDESPECK:
3883           s->swdespeck = val_c;
3884           return SANE_STATUS_GOOD;
3885 
3886         case OPT_SWCROP:
3887           s->swcrop = val_c;
3888           return SANE_STATUS_GOOD;
3889 
3890         case OPT_SWSKIP:
3891           s->swskip = SANE_UNFIX(val_c);
3892           return SANE_STATUS_GOOD;
3893 
3894         case OPT_STAPLEDETECT:
3895           s->stapledetect = val_c;
3896           return SANE_STATUS_GOOD;
3897 
3898         case OPT_DROPOUT_COLOR_F:
3899           if (!strcmp(val, STRING_NONE))
3900             s->dropout_color[SIDE_FRONT] = COLOR_NONE;
3901           else if (!strcmp(val, STRING_RED))
3902             s->dropout_color[SIDE_FRONT] = COLOR_RED;
3903           else if (!strcmp(val, STRING_GREEN))
3904             s->dropout_color[SIDE_FRONT] = COLOR_GREEN;
3905           else if (!strcmp(val, STRING_BLUE))
3906             s->dropout_color[SIDE_FRONT] = COLOR_BLUE;
3907           else if (!strcmp(val, STRING_EN_RED))
3908             s->dropout_color[SIDE_FRONT] = COLOR_EN_RED;
3909           else if (!strcmp(val, STRING_EN_GREEN))
3910             s->dropout_color[SIDE_FRONT] = COLOR_EN_GREEN;
3911           else if (!strcmp(val, STRING_EN_BLUE))
3912             s->dropout_color[SIDE_FRONT] = COLOR_EN_BLUE;
3913           return SANE_STATUS_GOOD;
3914 
3915         case OPT_DROPOUT_COLOR_B:
3916           if (!strcmp(val, STRING_NONE))
3917             s->dropout_color[SIDE_BACK] = COLOR_NONE;
3918           else if (!strcmp(val, STRING_RED))
3919             s->dropout_color[SIDE_BACK] = COLOR_RED;
3920           else if (!strcmp(val, STRING_GREEN))
3921             s->dropout_color[SIDE_BACK] = COLOR_GREEN;
3922           else if (!strcmp(val, STRING_BLUE))
3923             s->dropout_color[SIDE_BACK] = COLOR_BLUE;
3924           else if (!strcmp(val, STRING_EN_RED))
3925             s->dropout_color[SIDE_BACK] = COLOR_EN_RED;
3926           else if (!strcmp(val, STRING_EN_GREEN))
3927             s->dropout_color[SIDE_BACK] = COLOR_EN_GREEN;
3928           else if (!strcmp(val, STRING_EN_BLUE))
3929             s->dropout_color[SIDE_BACK] = COLOR_EN_BLUE;
3930           return SANE_STATUS_GOOD;
3931 
3932         case OPT_BUFFERMODE:
3933           s->buffermode = val_c;
3934           return SANE_STATUS_GOOD;
3935 
3936         case OPT_HW_CROP:
3937           s->hwcrop = val_c;
3938           return SANE_STATUS_GOOD;
3939 
3940         case OPT_PRE_IMPRINT_SPECSTRING:
3941           if (strlen(val) < IMPRINT_SPECSTRING_LEN){
3942             strncpy(s->pre_imprint.specstring, val, IMPRINT_SPECSTRING_LEN);
3943             return SANE_STATUS_GOOD;
3944           }
3945           DBG (5, "sane_control_option: pre-imprint spec string '%s' exceed the limit of %d characters\n", (SANE_String)val, IMPRINT_SPECSTRING_LEN);
3946           return SANE_STATUS_INVAL;
3947 
3948         case OPT_PRE_IMPRINT_H_OFFSET:
3949           s->pre_imprint.h_offset = val_c;
3950           return SANE_STATUS_GOOD;
3951 
3952         case OPT_PRE_IMPRINT_V_OFFSET:
3953           s->pre_imprint.v_offset = val_c;
3954           return SANE_STATUS_GOOD;
3955 
3956         case OPT_PRE_IMPRINT_FONT_SIZE:
3957           if (!strcmp (val, STRING_IMPRINTER_12x12_FONT)) {
3958             s->pre_imprint.font_size = IMPRINTER_12x12_FONT;
3959           }
3960           if (!strcmp (val, STRING_IMPRINTER_8x12_FONT)) {
3961             s->pre_imprint.font_size = IMPRINTER_8x12_FONT;
3962           }
3963           return SANE_STATUS_GOOD;
3964 
3965         case OPT_PRE_IMPRINT_FONT_ROT:
3966           switch (val_c){
3967             case 0:
3968               s->pre_imprint.font_rot = IMPRINTER_0_FONT_ROT;
3969               break;
3970 
3971             case 90:
3972               s->pre_imprint.font_rot = IMPRINTER_90_FONT_ROT;
3973               break;
3974 
3975             case 180:
3976               s->pre_imprint.font_rot = IMPRINTER_180_FONT_ROT;
3977               break;
3978 
3979             case 270:
3980               s->pre_imprint.font_rot = IMPRINTER_270_FONT_ROT;
3981               break;
3982           }
3983           return SANE_STATUS_GOOD;
3984 
3985         case OPT_PRE_IMPRINT_SPACING:
3986           s->pre_imprint.spacing = val_c;
3987           return SANE_STATUS_GOOD;
3988 
3989         case OPT_POST_IMPRINT_SPECSTRING:
3990           if (strlen(val) < IMPRINT_SPECSTRING_LEN){
3991             strncpy(s->post_imprint.specstring, val, IMPRINT_SPECSTRING_LEN);
3992             return SANE_STATUS_GOOD;
3993           }
3994           DBG (5, "sane_control_option: post-imprint spec string '%s' exceed the limit of %d characters\n", (SANE_String)val, IMPRINT_SPECSTRING_LEN);
3995           return SANE_STATUS_INVAL;
3996 
3997         case OPT_POST_IMPRINT_H_OFFSET:
3998           s->post_imprint.h_offset = val_c;
3999           return SANE_STATUS_GOOD;
4000 
4001         case OPT_POST_IMPRINT_V_OFFSET:
4002           s->post_imprint.v_offset = val_c;
4003           return SANE_STATUS_GOOD;
4004 
4005         case OPT_POST_IMPRINT_FONT_SIZE:
4006           if (!strcmp (val, STRING_IMPRINTER_12x12_FONT)) {
4007             s->post_imprint.font_size = IMPRINTER_12x12_FONT;
4008           }
4009           if (!strcmp (val, STRING_IMPRINTER_8x12_FONT)) {
4010             s->post_imprint.font_size = IMPRINTER_8x12_FONT;
4011           }
4012           return SANE_STATUS_GOOD;
4013 
4014         case OPT_POST_IMPRINT_FONT_ROT:
4015           switch (val_c){
4016             case 0:
4017               s->post_imprint.font_rot = IMPRINTER_0_FONT_ROT;
4018               break;
4019 
4020             case 90:
4021               s->post_imprint.font_rot = IMPRINTER_90_FONT_ROT;
4022               break;
4023 
4024             case 180:
4025               s->post_imprint.font_rot = IMPRINTER_180_FONT_ROT;
4026               break;
4027 
4028             case 270:
4029               s->post_imprint.font_rot = IMPRINTER_270_FONT_ROT;
4030               break;
4031           }
4032           return SANE_STATUS_GOOD;
4033 
4034         case OPT_POST_IMPRINT_SPACING:
4035           s->post_imprint.spacing = val_c;
4036           return SANE_STATUS_GOOD;
4037 
4038         case OPT_POST_IMPRINT_ADDON_MODE:
4039           if (!strcmp (val, STRING_IMPRINTER_ADDON_BoW)) {
4040             s->post_imprint_addon_mode = ADDON_BoW;
4041           }
4042           if (!strcmp (val, STRING_IMPRINTER_ADDON_BoI)) {
4043             s->post_imprint_addon_mode = ADDON_BoI;
4044           }
4045           if (!strcmp (val, STRING_IMPRINTER_ADDON_WoB)) {
4046             s->post_imprint_addon_mode = ADDON_WoB;
4047           }
4048           if (!strcmp (val, STRING_NONE)) {
4049             s->post_imprint_addon_mode = ADDON_DISABLED;
4050           }
4051           return SANE_STATUS_GOOD;
4052 
4053       }
4054   }                           /* else */
4055 
4056   return SANE_STATUS_INVAL;
4057 }
4058 
4059 static SANE_Status
ssm_buffer(struct scanner * s)4060 ssm_buffer (struct scanner *s)
4061 {
4062   SANE_Status ret = SANE_STATUS_GOOD;
4063 
4064   DBG (10, "ssm_buffer: start\n");
4065 
4066   if(s->has_ssm){
4067 
4068     unsigned char cmd[SET_SCAN_MODE_len];
4069     size_t cmdLen = SET_SCAN_MODE_len;
4070 
4071     unsigned char out[SSM_PAY_len];
4072     size_t outLen = SSM_PAY_len;
4073 
4074     memset(cmd,0,cmdLen);
4075     set_SCSI_opcode(cmd, SET_SCAN_MODE_code);
4076     set_SSM_pf(cmd, 1);
4077     set_SSM_pay_len(cmd, outLen);
4078 
4079     memset(out,0,outLen);
4080     if(s->has_ssm_pay_head_len){
4081       set_SSM_pay_head_len(out, SSM_PAY_HEAD_len);
4082     }
4083     set_SSM_page_code(out, SM_pc_buffer);
4084     set_SSM_page_len(out, SSM_PAGE_len);
4085 
4086     if(s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_CARD_DUPLEX){
4087       set_SSM_BUFF_duplex(out, 1);
4088     }
4089     if(s->s.source == SOURCE_FLATBED){
4090       set_SSM_BUFF_fb(out, 1);
4091     }
4092     else if(s->s.source >= SOURCE_CARD_FRONT){
4093       set_SSM_BUFF_card(out, 1);
4094     }
4095     if(s->buffermode){
4096       set_SSM_BUFF_async(out, 1);
4097     }
4098     if(0){
4099       set_SSM_BUFF_ald(out, 1);
4100     }
4101     if(0){
4102       set_SSM_BUFF_unk(out,1);
4103     }
4104 
4105     ret = do_cmd (
4106         s, 1, 0,
4107         cmd, cmdLen,
4108         out, outLen,
4109         NULL, NULL
4110     );
4111   }
4112 
4113   else if(s->has_ssm2){
4114 
4115     unsigned char cmd[SET_SCAN_MODE2_len];
4116     size_t cmdLen = SET_SCAN_MODE2_len;
4117 
4118     unsigned char out[SSM2_PAY_len];
4119     size_t outLen = SSM2_PAY_len;
4120 
4121     memset(cmd,0,cmdLen);
4122     set_SCSI_opcode(cmd, SET_SCAN_MODE2_code);
4123     set_SSM2_page_code(cmd, SM2_pc_buffer);
4124     set_SSM2_pay_len(cmd, outLen);
4125 
4126     memset(out,0,outLen);
4127     set_SSM2_BUFF_unk(out, !s->buffermode);
4128     set_SSM2_BUFF_unk2(out, 0x40);
4129     set_SSM2_BUFF_sync(out, !s->buffermode);
4130 
4131     ret = do_cmd (
4132         s, 1, 0,
4133         cmd, cmdLen,
4134         out, outLen,
4135         NULL, NULL
4136     );
4137   }
4138 
4139   else{
4140     DBG (10, "ssm_buffer: unsupported\n");
4141   }
4142 
4143   DBG (10, "ssm_buffer: finish\n");
4144 
4145   return ret;
4146 }
4147 
4148 static SANE_Status
ssm_df(struct scanner * s)4149 ssm_df (struct scanner *s)
4150 {
4151   SANE_Status ret = SANE_STATUS_GOOD;
4152 
4153   DBG (10, "ssm_df: start\n");
4154 
4155   if(!s->has_df){
4156     DBG (10, "ssm_df: unsupported, finishing\n");
4157     return ret;
4158   }
4159 
4160   if(s->has_ssm){
4161 
4162     unsigned char cmd[SET_SCAN_MODE_len];
4163     size_t cmdLen = SET_SCAN_MODE_len;
4164 
4165     unsigned char out[SSM_PAY_len];
4166     size_t outLen = SSM_PAY_len;
4167 
4168     memset(cmd,0,cmdLen);
4169     set_SCSI_opcode(cmd, SET_SCAN_MODE_code);
4170     set_SSM_pf(cmd, 1);
4171     set_SSM_pay_len(cmd, outLen);
4172 
4173     memset(out,0,outLen);
4174     if(s->has_ssm_pay_head_len){
4175       set_SSM_pay_head_len(out, SSM_PAY_HEAD_len);
4176     }
4177     set_SSM_page_code(out, SM_pc_df);
4178     set_SSM_page_len(out, SSM_PAGE_len);
4179 
4180     /* deskew by roller */
4181     if(s->rollerdeskew){
4182       set_SSM_DF_deskew_roll(out, 1);
4183     }
4184 
4185     /* staple detection */
4186     if(s->stapledetect){
4187       set_SSM_DF_staple(out, 1);
4188     }
4189 
4190     /* thickness */
4191     if(s->df_thickness){
4192       set_SSM_DF_thick(out, 1);
4193     }
4194 
4195     /* length */
4196     if(s->df_length){
4197       set_SSM_DF_len(out, 1);
4198     }
4199 
4200     ret = do_cmd (
4201         s, 1, 0,
4202         cmd, cmdLen,
4203         out, outLen,
4204         NULL, NULL
4205     );
4206 
4207   }
4208 
4209   else if(s->has_ssm2){
4210 
4211     unsigned char cmd[SET_SCAN_MODE2_len];
4212     size_t cmdLen = SET_SCAN_MODE2_len;
4213 
4214     unsigned char out[SSM2_PAY_len];
4215     size_t outLen = SSM2_PAY_len;
4216 
4217     /* send ultrasonic offsets first */
4218     if(s->df_thickness && s->has_df_ultra){
4219       memset(cmd,0,cmdLen);
4220       set_SCSI_opcode(cmd, SET_SCAN_MODE2_code);
4221       set_SSM2_page_code(cmd, SM2_pc_ultra);
4222       set_SSM2_pay_len(cmd, outLen);
4223 
4224       memset(out,0,outLen);
4225       set_SSM2_ULTRA_top(out, 0);
4226       set_SSM2_ULTRA_bot(out, 0);
4227 
4228       ret = do_cmd (
4229           s, 1, 0,
4230           cmd, cmdLen,
4231           out, outLen,
4232           NULL, NULL
4233       );
4234     }
4235 
4236     memset(cmd,0,cmdLen);
4237     set_SCSI_opcode(cmd, SET_SCAN_MODE2_code);
4238     set_SSM2_page_code(cmd, SM2_pc_df);
4239     set_SSM2_pay_len(cmd, outLen);
4240 
4241     memset(out,0,outLen);
4242 
4243     /* thickness */
4244     if(s->df_thickness){
4245       set_SSM2_DF_thick(out, 1);
4246     }
4247 
4248     /* length */
4249     if(s->df_length){
4250       set_SSM2_DF_len(out, 1);
4251     }
4252 
4253     /* staple detection */
4254     if(s->stapledetect){
4255       set_SSM2_DF_staple(out, 1);
4256     }
4257 
4258     int requires_postimprint = s->has_post_imprinter && (strlen(s->post_imprint.specstring) > 0);
4259     int requires_preimprint = s->has_pre_imprinter && (strlen(s->pre_imprint.specstring) > 0);
4260     if (s->has_post_imprinter)
4261       set_SSM2_DF_post_addon(out, requires_postimprint);
4262     if (requires_postimprint || requires_preimprint){
4263       set_SSM2_DF_imprint(out, 1);
4264     }
4265 
4266     ret = do_cmd (
4267         s, 1, 0,
4268         cmd, cmdLen,
4269         out, outLen,
4270         NULL, NULL
4271     );
4272 
4273   }
4274 
4275   else{
4276     DBG (10, "ssm_df: unsupported\n");
4277   }
4278 
4279   DBG (10, "ssm_df: finish\n");
4280 
4281   return ret;
4282 }
4283 
4284 static SANE_Status
ssm2_hw_enhancement(struct scanner * s)4285 ssm2_hw_enhancement (struct scanner *s)
4286 {
4287   SANE_Status ret = SANE_STATUS_GOOD;
4288 
4289   DBG (10, "ssm2_hw_enhancement: start\n");
4290 
4291   if(s->has_ssm2){
4292     unsigned char cmd[SET_SCAN_MODE2_len];
4293     size_t cmdLen = SET_SCAN_MODE2_len;
4294 
4295     unsigned char out[SSM2_PAY_len];
4296     size_t outLen = SSM2_PAY_len;
4297 
4298     memset(cmd,0,cmdLen);
4299     set_SCSI_opcode(cmd, SET_SCAN_MODE2_code);
4300     set_SSM2_page_code(cmd, SM2_pc_hw_enhancement);
4301     set_SSM2_pay_len(cmd, outLen);
4302 
4303     memset(out,0,outLen);
4304 
4305     if(s->rollerdeskew){
4306       set_SSM2_roller_deskew(out, 1);
4307     }
4308 
4309     if(s->hwcrop){
4310       set_SSM2_hw_crop(out, 1);
4311     }
4312 
4313     ret = do_cmd (
4314         s, 1, 0,
4315         cmd, cmdLen,
4316         out, outLen,
4317         NULL, NULL
4318     );
4319 
4320   }
4321 
4322   else{
4323     DBG (10, "ssm2_hw_enhancement: unsupported\n");
4324   }
4325 
4326   DBG (10, "ssm2_hw_enhancement: finish\n");
4327 
4328   return ret;
4329 }
4330 
4331 static SANE_Status
ssm_do(struct scanner * s)4332 ssm_do (struct scanner *s)
4333 {
4334   SANE_Status ret = SANE_STATUS_GOOD;
4335 
4336  DBG (10, "ssm_do: start\n");
4337 
4338  if(!s->can_color){
4339    DBG (10, "ssm_do: unsupported, finishing\n");
4340    return ret;
4341  }
4342 
4343  if(s->s.mode == MODE_COLOR){
4344    DBG (10, "ssm_do: unneeded, finishing\n");
4345    return ret;
4346  }
4347 
4348  if(s->has_ssm){
4349 
4350     unsigned char cmd[SET_SCAN_MODE_len];
4351     size_t cmdLen = SET_SCAN_MODE_len;
4352 
4353     unsigned char out[SSM_PAY_len];
4354     size_t outLen = SSM_PAY_len;
4355 
4356     memset(cmd,0,cmdLen);
4357     set_SCSI_opcode(cmd, SET_SCAN_MODE_code);
4358     set_SSM_pf(cmd, 1);
4359     set_SSM_pay_len(cmd, outLen);
4360 
4361     memset(out,0,outLen);
4362     if(s->has_ssm_pay_head_len){
4363       set_SSM_pay_head_len(out, SSM_PAY_HEAD_len);
4364     }
4365     set_SSM_page_code(out, SM_pc_dropout);
4366     set_SSM_page_len(out, SSM_PAGE_len);
4367 
4368     set_SSM_DO_unk1(out, 0x03);
4369 
4370     switch(s->dropout_color[SIDE_FRONT]){
4371       case COLOR_RED:
4372         set_SSM_DO_unk2(out, 0x05);
4373         set_SSM_DO_f_do(out,SSM_DO_red);
4374         break;
4375       case COLOR_GREEN:
4376         set_SSM_DO_unk2(out, 0x05);
4377         set_SSM_DO_f_do(out,SSM_DO_green);
4378         break;
4379       case COLOR_BLUE:
4380         set_SSM_DO_unk2(out, 0x05);
4381         set_SSM_DO_f_do(out,SSM_DO_blue);
4382         break;
4383       case COLOR_EN_RED:
4384         set_SSM_DO_unk2(out, 0x05);
4385         set_SSM_DO_f_en(out,SSM_DO_red);
4386         break;
4387       case COLOR_EN_GREEN:
4388         set_SSM_DO_unk2(out, 0x05);
4389         set_SSM_DO_f_en(out,SSM_DO_green);
4390         break;
4391       case COLOR_EN_BLUE:
4392         set_SSM_DO_unk2(out, 0x05);
4393         set_SSM_DO_f_en(out,SSM_DO_blue);
4394         break;
4395     }
4396 
4397     switch(s->dropout_color[SIDE_BACK]){
4398       case COLOR_RED:
4399         set_SSM_DO_unk2(out, 0x05);
4400         set_SSM_DO_b_do(out,SSM_DO_red);
4401         break;
4402       case COLOR_GREEN:
4403         set_SSM_DO_unk2(out, 0x05);
4404         set_SSM_DO_b_do(out,SSM_DO_green);
4405         break;
4406       case COLOR_BLUE:
4407         set_SSM_DO_unk2(out, 0x05);
4408         set_SSM_DO_b_do(out,SSM_DO_blue);
4409         break;
4410       case COLOR_EN_RED:
4411         set_SSM_DO_unk2(out, 0x05);
4412         set_SSM_DO_b_en(out,SSM_DO_red);
4413         break;
4414       case COLOR_EN_GREEN:
4415         set_SSM_DO_unk2(out, 0x05);
4416         set_SSM_DO_b_en(out,SSM_DO_green);
4417         break;
4418       case COLOR_EN_BLUE:
4419         set_SSM_DO_unk2(out, 0x05);
4420         set_SSM_DO_b_en(out,SSM_DO_blue);
4421         break;
4422     }
4423 
4424     ret = do_cmd (
4425         s, 1, 0,
4426         cmd, cmdLen,
4427         out, outLen,
4428         NULL, NULL
4429     );
4430 
4431   }
4432 
4433   else if(s->has_ssm2){
4434 
4435     unsigned char cmd[SET_SCAN_MODE2_len];
4436     size_t cmdLen = SET_SCAN_MODE2_len;
4437 
4438     unsigned char out[SSM2_PAY_len];
4439     size_t outLen = SSM2_PAY_len;
4440 
4441     memset(cmd,0,cmdLen);
4442     set_SCSI_opcode(cmd, SET_SCAN_MODE2_code);
4443     set_SSM2_page_code(cmd, SM2_pc_dropout);
4444     set_SSM2_pay_len(cmd, outLen);
4445 
4446     memset(out,0,outLen);
4447 
4448     switch(s->dropout_color[SIDE_FRONT]){
4449       case COLOR_RED:
4450         set_SSM2_DO_do(out,SSM_DO_red);
4451         break;
4452       case COLOR_GREEN:
4453         set_SSM2_DO_do(out,SSM_DO_green);
4454         break;
4455       case COLOR_BLUE:
4456         set_SSM2_DO_do(out,SSM_DO_blue);
4457         break;
4458       case COLOR_EN_RED:
4459         set_SSM2_DO_en(out,SSM_DO_red);
4460         break;
4461       case COLOR_EN_GREEN:
4462         set_SSM2_DO_en(out,SSM_DO_green);
4463         break;
4464       case COLOR_EN_BLUE:
4465         set_SSM2_DO_en(out,SSM_DO_blue);
4466         break;
4467     }
4468 
4469     ret = do_cmd (
4470         s, 1, 0,
4471         cmd, cmdLen,
4472         out, outLen,
4473         NULL, NULL
4474     );
4475 
4476     if(ret == SANE_STATUS_GOOD &&
4477        (s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_CARD_DUPLEX)){
4478 
4479       memset(cmd,0,cmdLen);
4480       set_SCSI_opcode(cmd, SET_SCAN_MODE2_code);
4481       set_SSM2_page_code(cmd, SM2_pc_dropout);
4482       set_SSM2_DO_side(cmd, SIDE_BACK);
4483       set_SSM2_pay_len(cmd, outLen);
4484 
4485       memset(out,0,outLen);
4486 
4487       switch(s->dropout_color[SIDE_BACK]){
4488         case COLOR_RED:
4489           set_SSM2_DO_do(out,SSM_DO_red);
4490           break;
4491         case COLOR_GREEN:
4492           set_SSM2_DO_do(out,SSM_DO_green);
4493           break;
4494         case COLOR_BLUE:
4495           set_SSM2_DO_do(out,SSM_DO_blue);
4496           break;
4497         case COLOR_EN_RED:
4498           set_SSM2_DO_en(out,SSM_DO_red);
4499           break;
4500         case COLOR_EN_GREEN:
4501           set_SSM2_DO_en(out,SSM_DO_green);
4502           break;
4503         case COLOR_EN_BLUE:
4504           set_SSM2_DO_en(out,SSM_DO_blue);
4505           break;
4506       }
4507 
4508       ret = do_cmd (
4509           s, 1, 0,
4510           cmd, cmdLen,
4511           out, outLen,
4512           NULL, NULL
4513       );
4514     }
4515   }
4516 
4517   else{
4518     DBG (10, "ssm_do: unsupported\n");
4519   }
4520 
4521   DBG (10, "ssm_do: finish\n");
4522 
4523   return ret;
4524 }
4525 
4526 static SANE_Status
read_counters(struct scanner * s)4527 read_counters(struct scanner *s)
4528 {
4529   SANE_Status ret = SANE_STATUS_GOOD;
4530 
4531   unsigned char cmd[READ_len];
4532   size_t cmdLen = READ_len;
4533 
4534   unsigned char in[R_COUNTERS_len];
4535   size_t inLen = R_COUNTERS_len;
4536 
4537   if (!s->can_read_lifecycle_counters){
4538     DBG(10, "read_counters: unsupported\n");
4539     return ret;
4540   }
4541 
4542   DBG(10, "read_counters: start\n");
4543 
4544   memset(cmd,0,cmdLen);
4545   set_SCSI_opcode(cmd, READ_code);
4546   set_R_datatype_code(cmd, SR_datatype_counters);
4547   set_R_xfer_length(cmd, inLen);
4548 
4549   ret = do_cmd(
4550     s, 1, 0,
4551     cmd, cmdLen,
4552     NULL, 0,
4553     in, &inLen
4554   );
4555 
4556   if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF){
4557 
4558     s->total_counter = get_R_COUNTERS_total(in);
4559     s->roller_counter = s->total_counter - get_R_COUNTERS_last_srv(in);
4560 
4561     DBG(10, "read_counters: total counter: %d roller_counter %d \n",s->total_counter,s->roller_counter);
4562     ret = SANE_STATUS_GOOD;
4563   }else{
4564     DBG(10, "read_counters: ERROR: %d\n",ret);
4565   }
4566 
4567   return ret;
4568 }
4569 
4570 static SANE_Status
read_sensors(struct scanner * s,SANE_Int option)4571 read_sensors(struct scanner *s,SANE_Int option)
4572 {
4573   SANE_Status ret=SANE_STATUS_GOOD;
4574 
4575   unsigned char cmd[READ_len];
4576   size_t cmdLen = READ_len;
4577 
4578   unsigned char in[R_SENSORS_len];
4579   size_t inLen = R_SENSORS_len;
4580 
4581   DBG (10, "read_sensors: start %d\n", option);
4582 
4583   if(!s->can_read_sensors){
4584     DBG (10, "read_sensors: unsupported, finishing\n");
4585     return ret;
4586   }
4587 
4588   /* only run this if frontend has already read the last time we got it */
4589   /* or if we don't care for such bookkeeping (private use) */
4590   if (!option || !s->sensors_read[option-OPT_ADF_LOADED]) {
4591 
4592     DBG (15, "read_sensors: running\n");
4593 
4594     memset(cmd,0,cmdLen);
4595     set_SCSI_opcode(cmd, READ_code);
4596     set_R_datatype_code (cmd, SR_datatype_sensors);
4597     set_R_xfer_length (cmd, inLen);
4598 
4599     ret = do_cmd (
4600       s, 1, 0,
4601       cmd, cmdLen,
4602       NULL, 0,
4603       in, &inLen
4604     );
4605 
4606     if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) {
4607       /*set flags indicating there is data to read*/
4608       memset(s->sensors_read,1,sizeof(s->sensors_read));
4609 
4610       s->sensor_adf_loaded = get_R_SENSORS_adf(in);
4611       s->sensor_card_loaded = get_R_SENSORS_card(in);
4612 
4613       ret = SANE_STATUS_GOOD;
4614     }
4615   }
4616 
4617   if(option)
4618     s->sensors_read[option-OPT_ADF_LOADED] = 0;
4619 
4620   DBG (10, "read_sensors: finish\n");
4621 
4622   return ret;
4623 }
4624 
4625 static SANE_Status
read_panel(struct scanner * s,SANE_Int option)4626 read_panel(struct scanner *s,SANE_Int option)
4627 {
4628   SANE_Status ret=SANE_STATUS_GOOD;
4629 
4630   unsigned char cmd[READ_len];
4631   size_t cmdLen = READ_len;
4632 
4633   unsigned char in[R_PANEL_len];
4634   size_t inLen = R_PANEL_len;
4635 
4636   DBG (10, "read_panel: start %d\n", option);
4637 
4638   if(!s->can_read_panel){
4639     DBG (10, "read_panel: unsupported, finishing\n");
4640     return ret;
4641   }
4642 
4643   /* only run this if frontend has already read the last time we got it */
4644   /* or if we don't care for such bookkeeping (private use) */
4645   if (!option || !s->panel_read[option-OPT_START]) {
4646 
4647     DBG (15, "read_panel: running\n");
4648 
4649     memset(cmd,0,cmdLen);
4650     set_SCSI_opcode(cmd, READ_code);
4651     set_R_datatype_code (cmd, SR_datatype_panel);
4652     set_R_xfer_length (cmd, inLen);
4653 
4654     ret = do_cmd (
4655       s, 1, 0,
4656       cmd, cmdLen,
4657       NULL, 0,
4658       in, &inLen
4659     );
4660 
4661     if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) {
4662       /*set flags indicating there is data to read*/
4663       memset(s->panel_read,1,sizeof(s->panel_read));
4664 
4665       s->panel_start = get_R_PANEL_start(in);
4666       s->panel_stop = get_R_PANEL_stop(in);
4667       s->panel_butt3 = get_R_PANEL_butt3(in);
4668       s->panel_new_file = get_R_PANEL_new_file(in);
4669       s->panel_count_only = get_R_PANEL_count_only(in);
4670       s->panel_bypass_mode = get_R_PANEL_bypass_mode(in);
4671       s->panel_enable_led = get_R_PANEL_enable_led(in);
4672       s->panel_counter = get_R_PANEL_counter(in);
4673 
4674       ret = SANE_STATUS_GOOD;
4675     }
4676   }
4677 
4678   if(option)
4679     s->panel_read[option-OPT_START] = 0;
4680 
4681   DBG (10, "read_panel: finish %d\n",s->panel_counter);
4682 
4683   return ret;
4684 }
4685 
4686 static SANE_Status
send_panel(struct scanner * s)4687 send_panel(struct scanner *s)
4688 {
4689     SANE_Status ret=SANE_STATUS_GOOD;
4690 
4691     unsigned char cmd[SEND_len];
4692     size_t cmdLen = SEND_len;
4693 
4694     unsigned char out[S_PANEL_len];
4695     size_t outLen = S_PANEL_len;
4696 
4697     DBG (10, "send_panel: start\n");
4698 
4699     if(!s->can_write_panel){
4700       DBG (10, "send_panel: unsupported, finishing\n");
4701       return ret;
4702     }
4703 
4704     memset(cmd,0,cmdLen);
4705     set_SCSI_opcode(cmd, SEND_code);
4706     set_S_xfer_datatype (cmd, SR_datatype_panel);
4707     set_S_xfer_length (cmd, outLen);
4708 
4709     memset(out,0,outLen);
4710     set_S_PANEL_enable_led(out,s->panel_enable_led);
4711     set_S_PANEL_counter(out,s->panel_counter);
4712 
4713     ret = do_cmd (
4714       s, 1, 0,
4715       cmd, cmdLen,
4716       out, outLen,
4717       NULL, NULL
4718     );
4719 
4720     if (ret == SANE_STATUS_EOF) {
4721         ret = SANE_STATUS_GOOD;
4722     }
4723 
4724     DBG (10, "send_panel: finish %d\n", ret);
4725 
4726     return ret;
4727 }
4728 
4729 /*
4730  * Request the size of the scanned image
4731  */
4732 /* we should really be updating s->s and s->i instead */
4733 static SANE_Status
get_pixelsize(struct scanner * s)4734 get_pixelsize(struct scanner *s)
4735 {
4736   SANE_Status ret = SANE_STATUS_GOOD;
4737 
4738   unsigned char cmd[READ_len];
4739   size_t cmdLen = READ_len;
4740 
4741   unsigned char in[R_PSIZE_len];
4742   size_t inLen = R_PSIZE_len;
4743 
4744   int i = 0;
4745   const int MAX_TRIES = 5;
4746 
4747   DBG (10, "get_pixelsize: start\n");
4748 
4749   if(!s->hwcrop){
4750     DBG (10, "get_pixelsize: unneeded, finishing\n");
4751     return ret;
4752   }
4753 
4754   memset(cmd,0,cmdLen);
4755   set_SCSI_opcode(cmd, READ_code);
4756   set_R_datatype_code(cmd, SR_datatype_pixelsize);
4757   set_R_xfer_lid(cmd, 0x02);
4758   set_R_xfer_length(cmd, inLen);
4759 
4760   /* May need to retry/block until the scanner is done */
4761   for(i=0;i<MAX_TRIES;i++){
4762     ret = do_cmd (
4763         s, 1, 0,
4764         cmd, cmdLen,
4765         NULL, 0,
4766         in, &inLen
4767     );
4768 
4769     if(ret != SANE_STATUS_GOOD){
4770       DBG (10, "get_pixelsize: error reading, status = %d\n", ret);
4771       break;
4772     }
4773 
4774     if(get_R_PSIZE_width(in) > 0 && get_R_PSIZE_length(in) > 0){
4775       DBG (15, "get_pixelsize: w:%d h:%d\n",
4776            get_R_PSIZE_width(in) * s->u.dpi_x / 1200,
4777            get_R_PSIZE_length(in) * s->u.dpi_y / 1200);
4778 
4779       /*
4780        * Round up to byte boundary if needed.
4781        * For 1 bpp the resulting size may not fit in a byte boundary.
4782        */
4783       int remainder = (get_R_PSIZE_width(in) * s->u.dpi_x / 1200) % 8;
4784 
4785       if (s->u.mode < MODE_GRAYSCALE && remainder)
4786       {
4787         int rounded_up = (8 - remainder) + (get_R_PSIZE_width(in) * s->u.dpi_x / 1200);
4788 
4789         s->u.br_x = rounded_up * 1200 / s->u.dpi_x;
4790       }
4791       else{
4792         s->u.br_x = get_R_PSIZE_width(in);
4793       }
4794 
4795       s->u.tl_x = 0;
4796       s->u.br_y = get_R_PSIZE_length(in);
4797       s->u.tl_y = 0;
4798 
4799       s->u.page_x = s->u.br_x;
4800       s->u.page_y = s->u.br_y;
4801 
4802       update_params(s,0);
4803       clean_params(s);
4804       break;
4805     }
4806 
4807     else{
4808       DBG (10, "get_pixelsize: error reading, status = %d w:%d h:%d\n",
4809            ret, get_R_PSIZE_width(in), get_R_PSIZE_length(in));
4810       ret = SANE_STATUS_INVAL;
4811       usleep(1000000);
4812     }
4813   }
4814   DBG (10, "get_pixelsize: finish\n");
4815 
4816   return ret;
4817 }
4818 
4819 /*
4820  * @@ Section 4 - SANE scanning functions
4821  */
4822 /*
4823  * Called by SANE to retrieve information about the type of data
4824  * that the current scan will return.
4825  *
4826  * From the SANE spec:
4827  * This function is used to obtain the current scan parameters. The
4828  * returned parameters are guaranteed to be accurate between the time
4829  * a scan has been started (sane_start() has been called) and the
4830  * completion of that request. Outside of that window, the returned
4831  * values are best-effort estimates of what the parameters will be
4832  * when sane_start() gets invoked.
4833  *
4834  * Calling this function before a scan has actually started allows,
4835  * for example, to get an estimate of how big the scanned image will
4836  * be. The parameters passed to this function are the handle h of the
4837  * device for which the parameters should be obtained and a pointer p
4838  * to a parameter structure.
4839  */
4840 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)4841 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
4842 {
4843     SANE_Status ret = SANE_STATUS_GOOD;
4844     struct scanner *s = (struct scanner *) handle;
4845 
4846     DBG (10, "sane_get_parameters: start\n");
4847 
4848     if(!s->started){
4849       ret = update_params(s,0);
4850       if(ret){
4851         DBG (5, "sane_get_parameters: up error, returning %d\n", ret);
4852         return ret;
4853       }
4854     }
4855 
4856     /* this backend only sends single frame images */
4857     params->last_frame = 1;
4858 
4859     params->format = s->i.format;
4860     params->lines = s->i.height;
4861     params->depth = s->i.bpp;
4862     if(params->depth == 24) params->depth = 8;
4863     params->pixels_per_line = s->i.width;
4864     params->bytes_per_line = s->i.Bpl;
4865 
4866     DBG(15,"sane_get_parameters: x: max=%d, page=%d, gpw=%d, res=%d\n",
4867       s->valid_x, s->i.page_x, get_page_width(s), s->i.dpi_x);
4868 
4869     DBG(15,"sane_get_parameters: y: max=%d, page=%d, gph=%d, res=%d\n",
4870       s->max_y, s->i.page_y, get_page_height(s), s->i.dpi_y);
4871 
4872     DBG(15,"sane_get_parameters: area: tlx=%d, brx=%d, tly=%d, bry=%d\n",
4873       s->i.tl_x, s->i.br_x, s->i.tl_y, s->i.br_y);
4874 
4875     DBG (15, "sane_get_parameters: params: ppl=%d, Bpl=%d, lines=%d\n",
4876       params->pixels_per_line, params->bytes_per_line, params->lines);
4877 
4878     DBG (15, "sane_get_parameters: params: format=%d, depth=%d, last=%d\n",
4879       params->format, params->depth, params->last_frame);
4880 
4881     DBG (10, "sane_get_parameters: finish\n");
4882 
4883     return ret;
4884 }
4885 
4886 SANE_Status
update_params(struct scanner * s,int calib)4887 update_params(struct scanner *s, int calib)
4888 {
4889     SANE_Status ret = SANE_STATUS_GOOD;
4890 
4891     DBG (10, "update_params: start\n");
4892 
4893     s->u.width = (s->u.br_x - s->u.tl_x) * s->u.dpi_x / 1200;
4894     s->u.height = (s->u.br_y - s->u.tl_y) * s->u.dpi_y / 1200;
4895 
4896     if (s->u.mode == MODE_COLOR) {
4897       s->u.format = SANE_FRAME_RGB;
4898       s->u.bpp = 24;
4899     }
4900     else if (s->u.mode == MODE_GRAYSCALE) {
4901       s->u.format = SANE_FRAME_GRAY;
4902       s->u.bpp = 8;
4903     }
4904     else {
4905       s->u.format = SANE_FRAME_GRAY;
4906       s->u.bpp = 1;
4907 
4908       /* round down to byte boundary */
4909       s->u.width -= s->u.width % 8;
4910     }
4911 
4912     /* round down to pixel boundary for some scanners */
4913     s->u.width -= s->u.width % s->ppl_mod;
4914 
4915     /* jpeg requires 8x8 squares */
4916     if(s->compress == COMP_JPEG && s->u.mode >= MODE_GRAYSCALE){
4917       s->u.format = SANE_FRAME_JPEG;
4918       s->u.width -= s->u.width % 8;
4919       s->u.height -= s->u.height % 8;
4920     }
4921 
4922     s->u.Bpl = s->u.width * s->u.bpp / 8;
4923     s->u.valid_Bpl = s->u.Bpl;
4924     s->u.valid_width = s->u.width;
4925 
4926     DBG (15, "update_params: user params: w:%d h:%d m:%d f:%d b:%d\n",
4927       s->u.width, s->u.height, s->u.mode, s->u.format, s->u.bpp);
4928     DBG (15, "update_params: user params: B:%d vB:%d vw:%d\n",
4929       s->u.Bpl, s->u.valid_Bpl, s->u.valid_width);
4930     DBG (15, "update_params: user params: x b:%d t:%d d:%d y b:%d t:%d d:%d\n",
4931       s->u.br_x, s->u.tl_x, s->u.dpi_x, s->u.br_y, s->u.tl_y, s->u.dpi_y);
4932 
4933     /* some scanners are limited in their valid scan params
4934      * make a second version of the params struct, but
4935      * override the user's values with what the scanner can actually do */
4936 
4937     memcpy(&s->s,&s->u,sizeof(struct img_params));
4938 
4939     /*********** missing modes (move up to valid one) **************/
4940     if(s->s.mode == MODE_LINEART && !s->can_monochrome){
4941       s->s.mode = MODE_GRAYSCALE;
4942       s->s.format = SANE_FRAME_GRAY;
4943       s->s.bpp = 8;
4944     }
4945     if(s->s.mode == MODE_GRAYSCALE && !s->can_grayscale){
4946       s->s.mode = MODE_COLOR;
4947       s->s.format = SANE_FRAME_RGB;
4948       s->s.bpp = 24;
4949     }
4950     if(s->s.mode == MODE_COLOR && !s->can_color){
4951       DBG (5, "update_params: no valid mode\n");
4952       return SANE_STATUS_INVAL;
4953     }
4954 
4955     /********** missing resolutions (move up to valid one) *********/
4956     if(!s->step_x_res){
4957       int i;
4958       for(i=0;i<DPI_1200;i++){
4959 
4960         /* this res is smaller or invalid, skip it */
4961         if(s->s.dpi_x > dpi_list[i] || !s->std_res_x[i])
4962           continue;
4963 
4964         /* same & valid res, done */
4965         if(s->s.dpi_x == dpi_list[i])
4966           break;
4967 
4968         /* different & valid res, switch */
4969         s->s.dpi_x = dpi_list[i];
4970         break;
4971       }
4972 
4973       if(i > DPI_1200){
4974         DBG (5, "update_params: no dpi\n");
4975         return SANE_STATUS_INVAL;
4976       }
4977     }
4978 
4979     /*********** weird scan area (increase to valid one) *********/
4980     if(s->fixed_width){
4981       s->s.tl_x = 0;
4982       s->s.br_x = s->max_x;
4983       s->s.page_x = s->max_x;
4984     }
4985 
4986     /*recalculate new params*/
4987     s->s.width = (s->s.br_x - s->s.tl_x) * s->s.dpi_x / 1200;
4988 
4989     /* round down to byte boundary */
4990     if(s->s.mode < MODE_GRAYSCALE){
4991       s->s.width -= s->s.width % 8;
4992     }
4993 
4994     /* round down to pixel boundary for some scanners */
4995     s->s.width -= s->s.width % s->ppl_mod;
4996 
4997     s->s.valid_width = s->s.width;
4998     s->s.valid_Bpl = s->s.valid_width * s->s.bpp / 8;
4999 
5000     /* some machines (DR-2050) require even bytes per scanline */
5001     /* increase width and Bpl, but not valid_width and valid_Bpl */
5002     if(s->even_Bpl && (s->s.width % 2)){
5003       s->s.width++;
5004     }
5005 
5006     s->s.Bpl = s->s.width * s->s.bpp / 8;
5007 
5008     /* figure out how many valid bytes per line (2510 is padded) */
5009     if(s->color_interlace[SIDE_FRONT] == COLOR_INTERLACE_2510){
5010       s->s.valid_Bpl = s->s.Bpl*11/12;
5011       s->s.valid_width = s->s.width*11/12;
5012     }
5013 
5014     /* some scanners need longer scans because front/back is offset */
5015     if((s->u.source == SOURCE_ADF_DUPLEX || s->u.source == SOURCE_CARD_DUPLEX)
5016       && s->duplex_offset && !calib)
5017       s->s.height = (s->u.br_y-s->u.tl_y+s->duplex_offset) * s->u.dpi_y / 1200;
5018 
5019     /* round lines up to even number */
5020     s->s.height += s->s.height % 2;
5021 
5022     DBG (15, "update_params: scan params: w:%d h:%d m:%d f:%d b:%d\n",
5023       s->s.width, s->s.height, s->s.mode, s->s.format, s->s.bpp);
5024     DBG (15, "update_params: scan params: B:%d vB:%d vw:%d\n",
5025       s->s.Bpl, s->s.valid_Bpl, s->s.valid_width);
5026     DBG (15, "update_params: scan params: x b:%d t:%d d:%d y b:%d t:%d d:%d\n",
5027       s->s.br_x, s->s.tl_x, s->s.dpi_x, s->s.br_y, s->s.tl_y, s->s.dpi_y);
5028 
5029     /* make a third (intermediate) version of the params struct,
5030      * currently identical to the user's params. this is what
5031      * we actually will send back to the user (though buffer_xxx
5032      * functions might change these values after this runs) */
5033 
5034     /* calibration code needs the data just as it comes from the scanner */
5035     if(calib)
5036       memcpy(&s->i,&s->s,sizeof(struct img_params));
5037     /* normal scans need the data cleaned for presentation to the user */
5038     else{
5039       memcpy(&s->i,&s->u,sizeof(struct img_params));
5040       /*dumb scanners pad the top of front page in duplex*/
5041       if(s->i.source == SOURCE_ADF_DUPLEX || s->i.source == SOURCE_CARD_DUPLEX)
5042         s->i.skip_lines[s->duplex_offset_side] = s->duplex_offset * s->i.dpi_y / 1200;
5043     }
5044 
5045     DBG (15, "update_params: i params: w:%d h:%d m:%d f:%d b:%d\n",
5046       s->i.width, s->i.height, s->i.mode, s->i.format, s->i.bpp);
5047     DBG (15, "update_params: i params: B:%d vB:%d vw:%d\n",
5048       s->i.Bpl, s->i.valid_Bpl, s->i.valid_width);
5049     DBG (15, "update_params: i params: x b:%d t:%d d:%d y b:%d t:%d d:%d\n",
5050       s->i.br_x, s->i.tl_x, s->i.dpi_x, s->i.br_y, s->i.tl_y, s->i.dpi_y);
5051 
5052     DBG (10, "update_params: finish\n");
5053     return ret;
5054 }
5055 
5056 /* simplify handling cmd SANE_STATUS_EOF as SANE_STATUS_GOOD */
5057 SANE_Status
send_cmd(struct scanner * s,unsigned char * cmd,size_t cmdLen,unsigned char * out,size_t outLen,unsigned char * inBuff,size_t * inLen)5058 send_cmd(struct scanner *s, unsigned char* cmd, size_t cmdLen,
5059                             unsigned char* out, size_t outLen,
5060                             unsigned char * inBuff, size_t * inLen)
5061 {
5062   SANE_Status ret=SANE_STATUS_GOOD;
5063 
5064     ret = do_cmd (
5065       s, 1, 0,
5066       cmd, cmdLen,
5067       out, outLen,
5068       inBuff, inLen
5069     );
5070 
5071     if (ret == SANE_STATUS_EOF) {
5072         ret = SANE_STATUS_GOOD;
5073     }
5074 
5075     return ret;
5076 }
5077 
5078 SANE_Status
send_imprint_positioning(struct scanner * s,int is_postimprint,int enabled)5079 send_imprint_positioning(struct scanner* s, int is_postimprint, int enabled)
5080 {
5081   unsigned char cmd[SET_SCAN_MODE2_len];
5082   size_t cmdLen=SET_SCAN_MODE2_len;
5083 
5084   unsigned char out[SSM2_PAY_len];
5085   size_t outLen=SSM2_PAY_len;
5086 
5087   unsigned char out_prefix[5]={ 0x01, 0x00, 0x60, 0x00, 0x60 };
5088   size_t outPrefixLen=5;
5089 
5090   memset(cmd,0,cmdLen);
5091   set_SCSI_opcode(cmd,SET_SCAN_MODE2_code);
5092   set_SSM2_page_code(cmd,SM2_pc_imprinter_settings);
5093   if (is_postimprint)
5094     set_SSM2_postimprint_cmd(cmd);
5095   set_SSM2_pay_len(cmd,outLen);
5096 
5097   memset(out,0,outLen);
5098   memcpy(out,out_prefix,outPrefixLen);
5099 
5100   int h_offset;
5101   int v_offset;
5102   if (is_postimprint){
5103     if (s->post_imprint_addon_mode != ADDON_DISABLED)
5104       set_SSM2_postimprint_addon(out);
5105     h_offset = s->post_imprint.h_offset;
5106     v_offset = s->post_imprint.v_offset;
5107 
5108     if (enabled)
5109       DBG (10, "send_imprint_positioning: post-imprinter: h_offset: %d v_offset: %d\n",h_offset,v_offset);
5110   }else{
5111     h_offset = s->pre_imprint.h_offset;
5112     v_offset = s->pre_imprint.v_offset;
5113     if (enabled)
5114       DBG (10, "send_imprint_positioning: pre-imprinter: h_offset: %d v_offset: %d\n",h_offset,v_offset);
5115   }
5116   if(!enabled)
5117     h_offset = v_offset = 0;
5118   set_SSM2_imprint_hoffset(out,h_offset);
5119   set_SSM2_imprint_voffset(out,v_offset);
5120 
5121   return send_cmd(s, cmd, cmdLen, out, outLen, NULL, NULL);
5122 }
5123 
5124 SANE_Status
send_imprint_specstring(struct scanner * s,int is_postimprint)5125 send_imprint_specstring(struct scanner* s, int is_postimprint)
5126 {
5127   unsigned char cmd[SET_SCAN_MODE2_len];
5128   size_t cmdLen = SET_SCAN_MODE2_len;
5129 
5130   unsigned char out[SSM2_IMPRINTER_STRING_PAY_len];
5131   size_t outLen = SSM2_IMPRINTER_STRING_PAY_len;
5132 
5133   memset(cmd,0,cmdLen);
5134   set_SCSI_opcode(cmd, SET_SCAN_MODE2_code);
5135   set_SSM2_page_code(cmd, SM2_pc_imprinter_specstring);
5136   if (is_postimprint)
5137     set_SSM2_postimprint_cmd(cmd);
5138   set_SSM2_pay_len(cmd, outLen);
5139 
5140   memset(out,0,outLen);
5141   /* most of these bytes have yet to be identified to specific functionalities,
5142      as they never seem to change under different imprinting mode */
5143   unsigned char out_prefix[32] = {
5144       0x01, 0x00,
5145       0x60, 0x00,
5146       0x60, 0x00,
5147       0x00, 0x00,
5148       0x00, 0x00,
5149       0x00, 0x00,
5150       0x03, 0x00,
5151       0x00, 0x00,
5152       0x01, 0x00,
5153       0x00, 0x00,
5154       0x00, 0x00,
5155       0x00, 0x00,
5156       0x00, 0x00,
5157       0x00, 0x01,
5158       0x04, 0x00,
5159       0x00, 0x00
5160     };
5161   memcpy(out, out_prefix, 32);
5162   if (is_postimprint){
5163     set_SSM2_imprint_fontsize(out, s->post_imprint.font_size);
5164     set_SSM2_imprint_fontrot(out, s->post_imprint.font_rot);
5165     set_SSM2_imprint_spacing(out, s->post_imprint.spacing);
5166     if (s->post_imprint_addon_mode != ADDON_DISABLED)
5167       set_SSM2_imprint_addonmode(out, s->post_imprint_addon_mode);
5168     strcpy((SANE_Char*)(out + 45), (SANE_String_Const) s->post_imprint.specstring);
5169     DBG (10, "send_imprint_specstring: post-imprinter: font size: %d rotation: %d spacing: %d text: '%s' imprint-addon-mode: %d\n",s->post_imprint.font_size,s->post_imprint.font_rot,s->post_imprint.spacing,s->post_imprint.specstring,s->post_imprint_addon_mode);
5170   }else{
5171     set_SSM2_imprint_fontsize(out, s->pre_imprint.font_size);
5172     set_SSM2_imprint_fontrot(out, s->pre_imprint.font_rot);
5173     set_SSM2_imprint_spacing(out, s->pre_imprint.spacing);
5174     strcpy((SANE_Char*)(out + 45), (SANE_String_Const) s->pre_imprint.specstring);
5175     DBG (10, "send_imprint_specstring: pre-imprinter: font size: %d rotation: %d spacing: %d text: '%s'\n",s->pre_imprint.font_size,s->pre_imprint.font_rot,s->pre_imprint.spacing,s->pre_imprint.specstring);
5176   }
5177 
5178   return send_cmd(s, cmd, cmdLen, out, outLen, NULL, NULL);
5179 }
5180 
5181 SANE_Status
send_imprint_date_and_time(struct scanner * s)5182 send_imprint_date_and_time(struct scanner* s)
5183 {
5184   unsigned char cmd[SET_SCAN_MODE2_len];
5185   size_t cmdLen = SET_SCAN_MODE2_len;
5186 
5187   unsigned char out[SSM2_PAY_len];
5188   size_t outLen = SSM2_PAY_len;
5189 
5190   memset(cmd,0,cmdLen);
5191   set_SCSI_opcode(cmd, SET_SCAN_MODE2_code);
5192   set_SSM2_page_code(cmd, SM2_pc_date_time);
5193   set_SSM2_pay_len(cmd, outLen);
5194 
5195   memset(out,0,outLen);
5196 
5197   time_t t = time(NULL);
5198   struct tm tM = *localtime(&t);
5199 
5200   set_SSM2_imprint_year(out, tM.tm_year + 1900);
5201   set_SSM2_imprint_month(out, tM.tm_mon + 1);
5202   set_SSM2_imprint_day(out, tM.tm_mday);
5203   set_SSM2_imprint_hour(out, tM.tm_hour);
5204   set_SSM2_imprint_min(out, tM.tm_min);
5205   set_SSM2_imprint_sec(out, tM.tm_sec);
5206 
5207   return send_cmd(s, cmd, cmdLen, out, outLen, NULL, NULL);
5208 }
5209 
5210 SANE_Status
load_imprinting_settings(struct scanner * s)5211 load_imprinting_settings(struct scanner *s)
5212 {
5213   SANE_Status ret = SANE_STATUS_GOOD;
5214 
5215   int requires_preimprint = (strlen(s->pre_imprint.specstring) > 0);
5216   int requires_postimprint = (strlen(s->post_imprint.specstring) > 0);
5217   int send_date_time = (s->has_pre_imprinter && requires_preimprint) || (s->has_post_imprinter && requires_postimprint);
5218 
5219   if (s->has_pre_imprinter){
5220     ret = send_imprint_positioning(s, 0, requires_preimprint);
5221     DBG(10, "load_imprinting_settings: send_pre_imprint_positioning = %d \n", ret);
5222     if (ret != SANE_STATUS_GOOD)
5223       return ret;
5224     if (requires_preimprint){
5225       ret = send_imprint_specstring(s, 0);
5226       DBG(10, "load_imprinting_settings: send_pre_imprint_specstring = %d \n", ret);
5227       if (ret != SANE_STATUS_GOOD)
5228         return ret;
5229     }
5230   }
5231 
5232   if (s->has_post_imprinter){
5233     ret = send_imprint_positioning(s, 1, requires_postimprint);
5234     DBG(10, "load_imprinting_settings: send_post_imprint_positioning = %d \n", ret);
5235     if (ret != SANE_STATUS_GOOD)
5236       return ret;
5237     if (requires_postimprint){
5238       ret = send_imprint_specstring(s, 1);
5239       DBG(10, "load_imprinting_settings: send_post_imprint_specstring = %d \n", ret);
5240       if (ret != SANE_STATUS_GOOD)
5241         return ret;
5242     }
5243   }
5244 
5245   if (send_date_time){
5246     ret = send_imprint_date_and_time(s);
5247     DBG(10, "load_imprinting_settings: send_imprint_date_and_time = %d \n", ret);
5248   }
5249   return ret;
5250 }
5251 
5252 static SANE_Status
detect_imprinter(struct scanner * s,SANE_Int option)5253 detect_imprinter(struct scanner *s,SANE_Int option)
5254 {
5255   SANE_Status ret = SANE_STATUS_GOOD;
5256 
5257   unsigned char cmd[READ_len];
5258   size_t cmdLen = READ_len;
5259 
5260   unsigned char in[R_IMPRINTER_len];
5261   size_t inLen = R_IMPRINTER_len;
5262 
5263   DBG (10, "detect_imprinter: start %d\n", option);
5264 
5265   memset(cmd,0,cmdLen);
5266   set_SCSI_opcode(cmd, READ_code);
5267   set_R_datatype_code(cmd, SR_datatype_imprinters);
5268   set_R_xfer_uid(cmd, option);
5269   set_R_xfer_length(cmd, inLen);
5270 
5271   ret = do_cmd(
5272     s, 1, 0,
5273     cmd, cmdLen,
5274     NULL, 0,
5275     in, &inLen
5276   );
5277 
5278   if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) {
5279     ret = SANE_STATUS_GOOD;
5280   }
5281 
5282   int imprinter_found = get_R_IMPRINTER_found(in);
5283   const char* imprinter_type = "unknown";
5284   if (option == R_PRE_IMPRINTER){
5285     s->has_pre_imprinter = imprinter_found;
5286     imprinter_type = "pre-imprinter";
5287   }
5288   else if (option == R_POST_IMPRINTER){
5289     s->has_post_imprinter = imprinter_found;
5290     imprinter_type = "post-imprinter";
5291   }
5292 
5293   DBG (10, "detect_imprinter:  type: %s. found status bit: %d \n",imprinter_type,imprinter_found);
5294 
5295   return ret;
5296 }
5297 
5298 /* reset image size parameters after buffer_xxx functions changed them */
5299 SANE_Status
update_i_params(struct scanner * s)5300 update_i_params(struct scanner *s)
5301 {
5302     SANE_Status ret = SANE_STATUS_GOOD;
5303 
5304     DBG (10, "update_i_params: start\n");
5305 
5306     s->i.width = s->u.width;
5307     s->i.Bpl = s->u.Bpl;
5308 
5309     DBG (10, "update_i_params: finish\n");
5310     return ret;
5311 }
5312 
5313 /*
5314  * Called by SANE when a page acquisition operation is to be started.
5315  * commands: set window, object pos, and scan
5316  *
5317  * this will be called between sides of a duplex scan,
5318  * and at the start of each page of an adf batch.
5319  * hence, we spend a lot of time playing with s->started, etc.
5320  */
5321 SANE_Status
sane_start(SANE_Handle handle)5322 sane_start (SANE_Handle handle)
5323 {
5324   struct scanner *s = handle;
5325   SANE_Status ret = SANE_STATUS_GOOD;
5326 
5327   DBG (10, "sane_start: start\n");
5328   DBG (15, "started=%d, side=%d, source=%d\n",
5329     s->started, s->side, s->u.source);
5330 
5331   /* undo any prior sane_cancel calls */
5332   s->cancelled=0;
5333 
5334   /* protect this block from sane_cancel */
5335   s->reading=1;
5336 
5337   /* not finished with current side, error */
5338   if (s->started && !s->u.eof[s->side]) {
5339     DBG(5,"sane_start: previous transfer not finished?");
5340     return SANE_STATUS_INVAL;
5341   }
5342 
5343   /* batch start? inititalize struct and scanner */
5344   if(!s->started){
5345 
5346     /* load side marker */
5347     if(s->u.source == SOURCE_ADF_BACK || s->u.source == SOURCE_CARD_BACK){
5348       s->side = SIDE_BACK;
5349     }
5350     else{
5351       s->side = SIDE_FRONT;
5352     }
5353 
5354     /* eject paper leftover*/
5355     if(object_position (s, SANE_FALSE)){
5356       DBG (5, "sane_start: ERROR: cannot eject page\n");
5357     }
5358 
5359     /* wait for scanner to finish eject */
5360     ret = wait_scanner (s);
5361     if (ret != SANE_STATUS_GOOD) {
5362       DBG (5, "sane_start: ERROR: cannot wait scanner\n");
5363       goto errors;
5364     }
5365 
5366     /* load the brightness/contrast lut with linear slope for calibration */
5367     ret = load_lut (s->lut, 8, 8, 0, 255, 0, 0);
5368     if (ret != SANE_STATUS_GOOD) {
5369       DBG (5, "sane_start: ERROR: cannot load lut\n");
5370       goto errors;
5371     }
5372 
5373     /* AFE cal */
5374     ret = calibrate_AFE(s);
5375     if (ret != SANE_STATUS_GOOD) {
5376       DBG (5, "sane_start: ERROR: cannot cal afe\n");
5377       goto errors;
5378     }
5379 
5380     /* fine cal */
5381     ret = calibrate_fine(s);
5382     if (ret != SANE_STATUS_GOOD) {
5383       DBG (5, "sane_start: ERROR: cannot cal fine\n");
5384       goto errors;
5385     }
5386 
5387     if (s->has_pre_imprinter || s->has_post_imprinter){
5388       ret = load_imprinting_settings(s);
5389       if (ret != SANE_STATUS_GOOD) {
5390         DBG (5, "sane_start: ERROR: invalid imprinting settings\n");
5391         goto errors;
5392       }
5393     }
5394 
5395     /* reset the page counter after calibration */
5396     s->panel_counter = 0;
5397     s->prev_page = 0;
5398     if(send_panel(s)){
5399       DBG (5, "sane_start: ERROR: cannot send panel\n");
5400     }
5401 
5402     /* we should really be updating s->s and s->i instead */
5403     if(s->hwcrop){
5404       s->u.br_x = s->max_x;
5405       s->u.tl_x = 0;
5406       s->u.br_y = s->max_y;
5407       s->u.tl_y = 0;
5408       s->u.page_x = s->max_x;
5409       s->u.page_y = s->max_y;
5410     }
5411 
5412     /* load our own private copy of scan params */
5413     ret = update_params(s,0);
5414     if (ret != SANE_STATUS_GOOD) {
5415       DBG (5, "sane_start: ERROR: cannot update_params\n");
5416       goto errors;
5417     }
5418 
5419     /* set window command */
5420     ret = set_window(s);
5421     if (ret != SANE_STATUS_GOOD) {
5422       DBG (5, "sane_start: ERROR: cannot set window\n");
5423       goto errors;
5424     }
5425 
5426     /* buffer/duplex/ald/fb/card command */
5427     ret = ssm_buffer(s);
5428     if (ret != SANE_STATUS_GOOD) {
5429       DBG (5, "sane_start: ERROR: cannot ssm buffer\n");
5430       goto errors;
5431     }
5432 
5433     /* dropout color command */
5434     ret = ssm_do(s);
5435     if (ret != SANE_STATUS_GOOD) {
5436       DBG (5, "sane_start: ERROR: cannot ssm do\n");
5437       goto errors;
5438     }
5439 
5440     /* double feed detection command */
5441     ret = ssm_df(s);
5442     if (ret != SANE_STATUS_GOOD) {
5443       DBG (5, "sane_start: ERROR: cannot ssm df\n");
5444       goto errors;
5445     }
5446 
5447     ret = ssm2_hw_enhancement(s);
5448     if (ret != SANE_STATUS_GOOD) {
5449       DBG (5, "sane_start: ERROR: cannot ssm2 hw enhancement\n");
5450       goto errors;
5451     }
5452 
5453     /* clean scan params for new scan */
5454     ret = clean_params(s);
5455     if (ret != SANE_STATUS_GOOD) {
5456       DBG (5, "sane_start: ERROR: cannot clean_params\n");
5457       goto errors;
5458     }
5459 
5460     /* make large buffers to hold the images */
5461     ret = image_buffers(s,1);
5462     if (ret != SANE_STATUS_GOOD) {
5463       DBG (5, "sane_start: ERROR: cannot load buffers\n");
5464       goto errors;
5465     }
5466 
5467     /* load the brightness/contrast lut with user choices */
5468     ret = load_lut (s->lut, 8, 8, 0, 255, s->contrast, s->brightness);
5469     if (ret != SANE_STATUS_GOOD) {
5470       DBG (5, "sane_start: ERROR: cannot load lut\n");
5471       goto errors;
5472     }
5473 
5474     /* card reader dislikes op? */
5475     if(s->s.source < SOURCE_CARD_FRONT){
5476       /* grab next page */
5477       ret = object_position (s, SANE_TRUE);
5478       if (ret != SANE_STATUS_GOOD) {
5479         DBG (5, "sane_start: ERROR: cannot load page\n");
5480         goto errors;
5481       }
5482 
5483       /* wait for scanner to finish load */
5484       ret = wait_scanner (s);
5485       if (ret != SANE_STATUS_GOOD) {
5486         DBG (5, "sane_start: ERROR: cannot wait scanner\n");
5487         goto errors;
5488       }
5489     }
5490 
5491     /* start scanning */
5492     ret = start_scan (s,0);
5493     if (ret != SANE_STATUS_GOOD) {
5494       DBG (5, "sane_start: ERROR: cannot start_scan\n");
5495       goto errors;
5496     }
5497 
5498     ret = get_pixelsize(s);
5499     if (ret != SANE_STATUS_GOOD) {
5500       DBG (5, "sane_start: ERROR: cannot get pixel size\n");
5501       goto errors;
5502     }
5503 
5504     s->started = 1;
5505   }
5506 
5507   /* stuff done for subsequent images */
5508   else{
5509 
5510     /* duplex needs to switch sides */
5511     if(s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_CARD_DUPLEX){
5512       s->side = !s->side;
5513     }
5514 
5515     /* reset the intermediate params */
5516     ret = update_i_params(s);
5517     if (ret != SANE_STATUS_GOOD) {
5518       DBG (5, "sane_start: ERROR: cannot update_i_params\n");
5519       goto errors;
5520     }
5521 
5522     /* set clean defaults with new sheet of paper */
5523     /* don't reset the transfer vars on backside of duplex page */
5524     /* otherwise buffered back page will be lost */
5525     /* ingest paper with adf (no-op for fb) */
5526     /* don't call object pos or scan on back side of duplex scan */
5527     if(s->side == SIDE_FRONT || s->s.source == SOURCE_ADF_BACK || s->s.source == SOURCE_CARD_BACK){
5528 
5529       /* clean scan params for new scan */
5530       ret = clean_params(s);
5531       if (ret != SANE_STATUS_GOOD) {
5532         DBG (5, "sane_start: ERROR: cannot clean_params\n");
5533         goto errors;
5534       }
5535 
5536       /* big scanners and small ones in non-buff mode: OP to detect paper */
5537       if(s->always_op || !s->buffermode){
5538         ret = object_position (s, SANE_TRUE);
5539         if (ret != SANE_STATUS_GOOD) {
5540           DBG (5, "sane_start: ERROR: cannot load page\n");
5541           goto errors;
5542         }
5543 
5544         /* user wants unbuffered scans */
5545         /* send scan command */
5546         if(!s->buffermode){
5547           ret = start_scan (s,0);
5548           if (ret != SANE_STATUS_GOOD) {
5549             DBG (5, "sane_start: ERROR: cannot start_scan\n");
5550             goto errors;
5551           }
5552         }
5553       }
5554 
5555       /* small, buffering scanners check for more pages by reading counter */
5556       else{
5557         ret = read_panel (s, OPT_COUNTER);
5558         if (ret != SANE_STATUS_GOOD) {
5559           DBG (5, "sane_start: ERROR: cannot load page\n");
5560           goto errors;
5561         }
5562         if(s->prev_page == s->panel_counter){
5563           DBG (5, "sane_start: same counter (%d) no paper?\n",s->prev_page);
5564           ret = SANE_STATUS_NO_DOCS;
5565           goto errors;
5566         }
5567         DBG (5, "sane_start: diff counter (%d/%d)\n",
5568           s->prev_page,s->panel_counter);
5569       }
5570 
5571       ret = get_pixelsize(s);
5572       if (ret != SANE_STATUS_GOOD) {
5573         DBG (5, "sane_start: ERROR: cannot get pixel size\n");
5574         goto errors;
5575       }
5576     }
5577   }
5578 
5579   /* reset jpeg params on each page */
5580   s->jpeg_stage=JPEG_STAGE_NONE;
5581   s->jpeg_ff_offset=0;
5582 
5583   DBG (15, "started=%d, side=%d, source=%d\n",
5584     s->started, s->side, s->u.source);
5585 
5586   /* certain options require the entire image to
5587    * be collected from the scanner before we can
5588    * tell the user the size of the image. the sane
5589    * API has no way to inform the frontend of this,
5590    * so we block and buffer. yuck */
5591   if(must_fully_buffer(s)){
5592 
5593     /* get image */
5594     while(!s->s.eof[s->side] && !ret){
5595       SANE_Int len = 0;
5596       ret = sane_read((SANE_Handle)s, NULL, 0, &len);
5597     }
5598 
5599     /* check for errors */
5600     if (ret != SANE_STATUS_GOOD) {
5601       DBG (5, "sane_start: ERROR: cannot buffer image\n");
5602       goto errors;
5603     }
5604 
5605     DBG (5, "sane_start: OK: done buffering\n");
5606 
5607     /* finished buffering, adjust image as required */
5608     if(s->swdeskew){
5609       buffer_deskew(s,s->side);
5610     }
5611     if(s->swcrop){
5612       buffer_crop(s,s->side);
5613     }
5614     if(s->swdespeck){
5615       buffer_despeck(s,s->side);
5616     }
5617     if(s->swskip){
5618       /* Skipping means throwing out this image.
5619        * Pretend the user read the whole thing
5620        * and call sane_start again.
5621        * This assumes we are running in batch mode. */
5622       if(buffer_isblank(s,s->side)){
5623         s->u.eof[s->side] = 1;
5624         return sane_start(handle);
5625       }
5626     }
5627   }
5628 
5629   ret = check_for_cancel(s);
5630   s->reading = 0;
5631 
5632   DBG (10, "sane_start: finish %d\n", ret);
5633   return ret;
5634 
5635   errors:
5636     DBG (10, "sane_start: error %d\n", ret);
5637     s->started = 0;
5638     s->cancelled = 0;
5639     s->reading = 0;
5640     return ret;
5641 }
5642 
5643 /*
5644  * cleans params for new scan
5645  */
5646 static SANE_Status
clean_params(struct scanner * s)5647 clean_params (struct scanner *s)
5648 {
5649   SANE_Status ret = SANE_STATUS_GOOD;
5650 
5651   DBG (10, "clean_params: start\n");
5652 
5653   s->u.eof[0]=0;
5654   s->u.eof[1]=0;
5655   s->u.bytes_sent[0]=0;
5656   s->u.bytes_sent[1]=0;
5657   s->u.bytes_tot[0]=0;
5658   s->u.bytes_tot[1]=0;
5659 
5660   s->i.eof[0]=0;
5661   s->i.eof[1]=0;
5662   s->i.bytes_sent[0]=0;
5663   s->i.bytes_sent[1]=0;
5664   s->i.bytes_tot[0]=0;
5665   s->i.bytes_tot[1]=0;
5666 
5667   s->s.eof[0]=0;
5668   s->s.eof[1]=0;
5669   s->s.bytes_sent[0]=0;
5670   s->s.bytes_sent[1]=0;
5671   s->s.bytes_tot[0]=0;
5672   s->s.bytes_tot[1]=0;
5673 
5674   /* store the number of front bytes */
5675   if ( s->u.source != SOURCE_ADF_BACK && s->u.source != SOURCE_CARD_BACK )
5676     s->u.bytes_tot[SIDE_FRONT] = s->u.Bpl * s->u.height;
5677 
5678   if ( s->i.source != SOURCE_ADF_BACK && s->i.source != SOURCE_CARD_BACK )
5679     s->i.bytes_tot[SIDE_FRONT] = s->i.Bpl * s->i.height;
5680 
5681   if ( s->s.source != SOURCE_ADF_BACK && s->s.source != SOURCE_CARD_BACK )
5682     s->s.bytes_tot[SIDE_FRONT] = s->s.Bpl * s->s.height;
5683 
5684   /* store the number of back bytes */
5685   if ( s->u.source == SOURCE_ADF_DUPLEX || s->u.source == SOURCE_ADF_BACK
5686     || s->u.source == SOURCE_CARD_DUPLEX || s->u.source == SOURCE_CARD_BACK )
5687     s->u.bytes_tot[SIDE_BACK] = s->u.Bpl * s->u.height;
5688 
5689   if ( s->i.source == SOURCE_ADF_DUPLEX || s->i.source == SOURCE_ADF_BACK
5690     || s->i.source == SOURCE_CARD_DUPLEX || s->i.source == SOURCE_CARD_BACK )
5691     s->i.bytes_tot[SIDE_BACK] = s->i.Bpl * s->i.height;
5692 
5693   if ( s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_ADF_BACK
5694     || s->s.source == SOURCE_CARD_DUPLEX || s->s.source == SOURCE_CARD_BACK )
5695     s->s.bytes_tot[SIDE_BACK] = s->s.Bpl * s->s.height;
5696 
5697   DBG (10, "clean_params: finish\n");
5698 
5699   return ret;
5700 }
5701 
5702 /*
5703  * frees/callocs buffers to hold the scan data
5704  */
5705 static SANE_Status
image_buffers(struct scanner * s,int setup)5706 image_buffers (struct scanner *s, int setup)
5707 {
5708   SANE_Status ret = SANE_STATUS_GOOD;
5709   int side;
5710 
5711   DBG (10, "image_buffers: start\n");
5712 
5713   for(side=0;side<2;side++){
5714 
5715     /* free current buffer */
5716     if (s->buffers[side]) {
5717       DBG (15, "image_buffers: free buffer %d.\n",side);
5718       free(s->buffers[side]);
5719       s->buffers[side] = NULL;
5720     }
5721 
5722     /* build new buffer if asked */
5723     if(s->i.bytes_tot[side] && setup){
5724       s->buffers[side] = calloc (1,s->i.bytes_tot[side]);
5725       if (!s->buffers[side]) {
5726         DBG (5, "image_buffers: Error, no buffer %d.\n",side);
5727         return SANE_STATUS_NO_MEM;
5728       }
5729     }
5730   }
5731 
5732   DBG (10, "image_buffers: finish\n");
5733 
5734   return ret;
5735 }
5736 
5737 /*
5738  * This routine issues a SCSI SET WINDOW command to the scanner, using the
5739  * values currently in the s->s param structure.
5740  */
5741 static SANE_Status
set_window(struct scanner * s)5742 set_window (struct scanner *s)
5743 {
5744   SANE_Status ret = SANE_STATUS_GOOD;
5745 
5746   /* The command specifies the number of bytes in the data phase
5747    * the data phase has a header, followed by 1 window desc block
5748    * the header specifies the number of bytes in 1 window desc block
5749    */
5750 
5751   unsigned char cmd[SET_WINDOW_len];
5752   size_t cmdLen = SET_WINDOW_len;
5753 
5754   unsigned char out[SW_header_len + SW_desc_len];
5755   size_t outLen = SW_header_len + SW_desc_len;
5756 
5757   unsigned char * header = out;                       /*header*/
5758   unsigned char * desc1 = out + SW_header_len;        /*descriptor*/
5759 
5760   DBG (10, "set_window: start\n");
5761 
5762   /*build the payload*/
5763   memset(out,0,outLen);
5764 
5765   /* set window desc size in header */
5766   set_WPDB_wdblen(header, SW_desc_len);
5767 
5768   /* init the window block */
5769   if (s->s.source == SOURCE_ADF_BACK || s->s.source == SOURCE_CARD_BACK) {
5770     set_WD_wid (desc1, WD_wid_back);
5771   }
5772   else{
5773     set_WD_wid (desc1, WD_wid_front);
5774   }
5775 
5776   set_WD_Xres (desc1, s->s.dpi_x);
5777   set_WD_Yres (desc1, s->s.dpi_y);
5778 
5779   /* some machines need max width */
5780   if(s->fixed_width){
5781     set_WD_ULX (desc1, 0);
5782     set_WD_width (desc1, s->max_x);
5783   }
5784 
5785   /* or they align left */
5786   else if(s->u.source == SOURCE_FLATBED){
5787     set_WD_ULX (desc1, s->s.tl_x);
5788     set_WD_width (desc1, s->s.width * 1200/s->s.dpi_x);
5789   }
5790 
5791   /* or we have to center the window ourselves */
5792   else{
5793     set_WD_ULX (desc1, (s->max_x - s->s.page_x) / 2 + s->s.tl_x);
5794     set_WD_width (desc1, s->s.width * 1200/s->s.dpi_x);
5795   }
5796 
5797   /* some models require that the tly value be inverted? */
5798   if(s->invert_tly)
5799     set_WD_ULY (desc1, ~s->s.tl_y);
5800   else
5801     set_WD_ULY (desc1, s->s.tl_y);
5802 
5803   set_WD_length (desc1, s->s.height * 1200/s->s.dpi_y);
5804 
5805   if(s->has_btc){
5806     /*convert our common -127 to +127 range into HW's range
5807      *FIXME: this code assumes hardware range of 0-255 */
5808     set_WD_brightness (desc1, s->brightness+128);
5809 
5810     set_WD_threshold (desc1, s->threshold);
5811 
5812     /*convert our common -127 to +127 range into HW's range
5813      *FIXME: this code assumes hardware range of 0-255 */
5814     set_WD_contrast (desc1, s->contrast+128);
5815   }
5816 
5817   set_WD_composition (desc1, s->s.mode);
5818 
5819   if(s->s.bpp == 24)
5820     set_WD_bitsperpixel (desc1, 8);
5821   else
5822     set_WD_bitsperpixel (desc1, s->s.bpp);
5823 
5824   if(s->s.mode == MODE_HALFTONE){
5825     /*set_WD_ht_type(desc1, s->ht_type);
5826     set_WD_ht_pattern(desc1, s->ht_pattern);*/
5827   }
5828 
5829   set_WD_rif (desc1, s->rif);
5830   set_WD_rgb(desc1, s->rgb_format);
5831   set_WD_padding(desc1, s->padding);
5832 
5833   /*FIXME: what is this? */
5834   set_WD_reserved2(desc1, s->unknown_byte2);
5835 
5836   set_WD_compress_type(desc1, COMP_NONE);
5837   set_WD_compress_arg(desc1, 0);
5838 
5839   /* some scanners support jpeg image compression, for color/gs only */
5840   if(s->s.format == SANE_FRAME_JPEG){
5841     set_WD_compress_type(desc1, COMP_JPEG);
5842     set_WD_compress_arg(desc1, s->compress_arg);
5843   }
5844 
5845   /*build the command*/
5846   memset(cmd,0,cmdLen);
5847   set_SCSI_opcode(cmd, SET_WINDOW_code);
5848   set_SW_xferlen(cmd, outLen);
5849 
5850   ret = do_cmd (
5851     s, 1, 0,
5852     cmd, cmdLen,
5853     out, outLen,
5854     NULL, NULL
5855   );
5856 
5857   if (!ret && (s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_CARD_DUPLEX)) {
5858       set_WD_wid (desc1, WD_wid_back);
5859       ret = do_cmd (
5860         s, 1, 0,
5861         cmd, cmdLen,
5862         out, outLen,
5863         NULL, NULL
5864       );
5865   }
5866 
5867   DBG (10, "set_window: finish\n");
5868 
5869   return ret;
5870 }
5871 
5872 /*
5873  * Issues the SCSI OBJECT POSITION command if an ADF is in use.
5874  */
5875 static SANE_Status
object_position(struct scanner * s,int i_load)5876 object_position (struct scanner *s, int i_load)
5877 {
5878   SANE_Status ret = SANE_STATUS_GOOD;
5879 
5880   unsigned char cmd[OBJECT_POSITION_len];
5881   size_t cmdLen = OBJECT_POSITION_len;
5882 
5883   DBG (10, "object_position: start\n");
5884 
5885   if (s->u.source == SOURCE_FLATBED) {
5886     DBG (10, "object_position: flatbed no-op\n");
5887     return SANE_STATUS_GOOD;
5888   }
5889 
5890   memset(cmd,0,cmdLen);
5891   set_SCSI_opcode(cmd, OBJECT_POSITION_code);
5892 
5893   if (i_load) {
5894     DBG (15, "object_position: load\n");
5895     set_OP_autofeed (cmd, OP_Feed);
5896   }
5897   else {
5898     DBG (15, "object_position: eject\n");
5899     set_OP_autofeed (cmd, OP_Discharge);
5900   }
5901 
5902   ret = do_cmd (
5903     s, 1, 0,
5904     cmd, cmdLen,
5905     NULL, 0,
5906     NULL, NULL
5907   );
5908   if (ret != SANE_STATUS_GOOD)
5909     return ret;
5910 
5911   DBG (10, "object_position: finish\n");
5912 
5913   return ret;
5914 }
5915 
5916 /*
5917  * Issues SCAN command.
5918  *
5919  * (This doesn't actually read anything, it just tells the scanner
5920  * to start scanning.)
5921  */
5922 static SANE_Status
start_scan(struct scanner * s,int type)5923 start_scan (struct scanner *s, int type)
5924 {
5925   SANE_Status ret = SANE_STATUS_GOOD;
5926 
5927   unsigned char cmd[SCAN_len];
5928   size_t cmdLen = SCAN_len;
5929 
5930   unsigned char out[] = {WD_wid_front, WD_wid_back};
5931   size_t outLen = 2;
5932 
5933   DBG (10, "start_scan: start\n");
5934 
5935   /* calibration scans use 0xff or 0xfe */
5936   if(type){
5937     out[0] = type;
5938     out[1] = type;
5939   }
5940 
5941   if (s->s.source != SOURCE_ADF_DUPLEX && s->s.source != SOURCE_CARD_DUPLEX) {
5942     outLen--;
5943     if(s->s.source == SOURCE_ADF_BACK || s->s.source == SOURCE_CARD_BACK) {
5944       out[0] = WD_wid_back;
5945     }
5946   }
5947 
5948   memset(cmd,0,cmdLen);
5949   set_SCSI_opcode(cmd, SCAN_code);
5950   set_SC_xfer_length (cmd, outLen);
5951 
5952   ret = do_cmd (
5953     s, 1, 0,
5954     cmd, cmdLen,
5955     out, outLen,
5956     NULL, NULL
5957   );
5958 
5959   DBG (10, "start_scan: finish\n");
5960 
5961   return ret;
5962 }
5963 
5964 /*
5965  * Called by SANE to read data.
5966  *
5967  * From the SANE spec:
5968  * This function is used to read image data from the device
5969  * represented by handle h.  Argument buf is a pointer to a memory
5970  * area that is at least maxlen bytes long.  The number of bytes
5971  * returned is stored in *len. A backend must set this to zero when
5972  * the call fails (i.e., when a status other than SANE_STATUS_GOOD is
5973  * returned).
5974  *
5975  * When the call succeeds, the number of bytes returned can be
5976  * anywhere in the range from 0 to maxlen bytes.
5977  */
5978 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)5979 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len)
5980 {
5981   struct scanner *s = (struct scanner *) handle;
5982   SANE_Status ret=SANE_STATUS_GOOD;
5983 
5984   DBG (10, "sane_read: start\n");
5985 
5986   *len=0;
5987 
5988   /* maybe cancelled? */
5989   if(!s->started){
5990     DBG (5, "sane_read: not started, call sane_start\n");
5991     return SANE_STATUS_CANCELLED;
5992   }
5993 
5994   /* sane_start required between sides */
5995   if(s->u.bytes_sent[s->side] == s->i.bytes_tot[s->side]){
5996     s->u.eof[s->side] = 1;
5997     DBG (15, "sane_read: returning eof\n");
5998     return SANE_STATUS_EOF;
5999   }
6000 
6001   s->reading = 1;
6002 
6003   /* double width pnm interlacing */
6004   if((s->s.source == SOURCE_ADF_DUPLEX || s->s.source == SOURCE_CARD_DUPLEX)
6005     && s->s.format <= SANE_FRAME_RGB
6006     && s->duplex_interlace != DUPLEX_INTERLACE_NONE
6007   ){
6008 
6009     /* buffer both sides */
6010     if(!s->s.eof[SIDE_FRONT] || !s->s.eof[SIDE_BACK]){
6011       ret = read_from_scanner_duplex(s, 0);
6012       if(ret){
6013         DBG(5,"sane_read: front returning %d\n",ret);
6014         goto errors;
6015       }
6016       /*read last block, update counter*/
6017       if(s->s.eof[SIDE_FRONT] && s->s.eof[SIDE_BACK]){
6018         s->prev_page++;
6019         DBG(15,"sane_read: duplex counter %d\n",s->prev_page);
6020       }
6021     }
6022   }
6023 
6024   /* simplex or non-alternating duplex */
6025   else{
6026     if(!s->s.eof[s->side]){
6027       ret = read_from_scanner(s, s->side, 0);
6028       if(ret){
6029         DBG(5,"sane_read: side %d returning %d\n",s->side,ret);
6030         goto errors;
6031       }
6032       /*read last block, update counter*/
6033       if(s->s.eof[s->side]){
6034         s->prev_page++;
6035         DBG(15,"sane_read: side %d counter %d\n",s->side,s->prev_page);
6036       }
6037     }
6038   }
6039 
6040   /* copy a block from buffer to frontend */
6041   ret = read_from_buffer(s,buf,max_len,len,s->side);
6042   if(ret)
6043     goto errors;
6044 
6045   ret = check_for_cancel(s);
6046   s->reading = 0;
6047 
6048   DBG (10, "sane_read: finish %d\n", ret);
6049   return ret;
6050 
6051   errors:
6052     DBG (10, "sane_read: error %d\n", ret);
6053     s->reading = 0;
6054     s->cancelled = 0;
6055     s->started = 0;
6056     return ret;
6057 }
6058 
6059 static SANE_Status
read_from_scanner(struct scanner * s,int side,int exact)6060 read_from_scanner(struct scanner *s, int side, int exact)
6061 {
6062   SANE_Status ret=SANE_STATUS_GOOD;
6063 
6064   unsigned char cmd[READ_len];
6065   size_t cmdLen = READ_len;
6066 
6067   unsigned char * in;
6068   size_t inLen = 0;
6069 
6070   size_t bytes = s->buffer_size;
6071   size_t remain = s->s.bytes_tot[side] - s->s.bytes_sent[side];
6072 
6073   DBG (10, "read_from_scanner: start\n");
6074 
6075   /* all requests must end on line boundary */
6076   bytes -= (bytes % s->s.Bpl);
6077 
6078   /* some larger scanners require even bytes per block */
6079   if(bytes % 2){
6080     bytes -= s->s.Bpl;
6081   }
6082 
6083   /* usually (image) we want to read too much data, and get RS */
6084   /* sometimes (calib) we want to do an exact read */
6085   if(exact && bytes > remain){
6086     bytes = remain;
6087   }
6088 
6089   DBG(15, "read_from_scanner: si:%d to:%d rx:%d re:%lu bu:%d pa:%lu ex:%d\n",
6090       side, s->s.bytes_tot[side], s->s.bytes_sent[side],
6091       (unsigned long)remain, s->buffer_size, (unsigned long)bytes, exact);
6092 
6093   inLen = bytes;
6094   in = malloc(inLen);
6095   if(!in){
6096     DBG(5, "read_from_scanner: not enough mem for buffer: %d\n",(int)inLen);
6097     return SANE_STATUS_NO_MEM;
6098   }
6099 
6100   memset(cmd,0,cmdLen);
6101   set_SCSI_opcode(cmd, READ_code);
6102   set_R_datatype_code (cmd, SR_datatype_image);
6103 
6104   set_R_xfer_length (cmd, inLen);
6105 
6106   ret = do_cmd (
6107     s, 1, 0,
6108     cmd, cmdLen,
6109     NULL, 0,
6110     in, &inLen
6111   );
6112 
6113   if (ret == SANE_STATUS_GOOD) {
6114     DBG(15, "read_from_scanner: got GOOD, returning GOOD %lu\n", (unsigned long)inLen);
6115   }
6116   else if (ret == SANE_STATUS_EOF) {
6117     DBG(15, "read_from_scanner: got EOF, finishing %lu\n", (unsigned long)inLen);
6118   }
6119   else if (ret == SANE_STATUS_DEVICE_BUSY) {
6120     DBG(5, "read_from_scanner: got BUSY, returning GOOD\n");
6121     inLen = 0;
6122     ret = SANE_STATUS_GOOD;
6123   }
6124   else {
6125     DBG(5, "read_from_scanner: error reading data block status = %d\n",ret);
6126     inLen = 0;
6127   }
6128 
6129   /* this is jpeg data, we need to fix the missing image size */
6130   if(s->s.format == SANE_FRAME_JPEG){
6131 
6132     /* look for the SOF header near the beginning */
6133     if(s->jpeg_stage == JPEG_STAGE_NONE || s->jpeg_ff_offset < 0x0d){
6134 
6135       size_t i;
6136 
6137       for(i=0;i<inLen;i++){
6138 
6139         /* about to change stage */
6140         if(s->jpeg_stage == JPEG_STAGE_NONE && in[i] == 0xff){
6141           s->jpeg_ff_offset=0;
6142           continue;
6143         }
6144 
6145         s->jpeg_ff_offset++;
6146 
6147         /* last byte was an ff, this byte is SOF */
6148         if(s->jpeg_ff_offset == 1 && in[i] == 0xc0){
6149           s->jpeg_stage = JPEG_STAGE_SOF;
6150           continue;
6151         }
6152 
6153         if(s->jpeg_stage == JPEG_STAGE_SOF){
6154 
6155           /* lines in start of frame, overwrite it */
6156           if(s->jpeg_ff_offset == 5){
6157             in[i] = (s->s.height >> 8) & 0xff;
6158             continue;
6159           }
6160           if(s->jpeg_ff_offset == 6){
6161             in[i] = s->s.height & 0xff;
6162             continue;
6163           }
6164 
6165           /* width in start of frame, overwrite it */
6166           if(s->jpeg_ff_offset == 7){
6167             in[i] = (s->s.width >> 8) & 0xff;
6168             continue;
6169           }
6170           if(s->jpeg_ff_offset == 8){
6171             in[i] = s->s.width & 0xff;
6172             continue;
6173           }
6174         }
6175       }
6176     }
6177   }
6178 
6179   /*scanner may have sent more data than we asked for, chop it*/
6180   if(inLen > remain){
6181     inLen = remain;
6182   }
6183 
6184   /* we've got some data, descramble and store it */
6185   if(inLen){
6186     copy_simplex(s,in,inLen,side);
6187   }
6188 
6189   free(in);
6190 
6191   /* we've read all data, but not eof. clear and pretend */
6192   if(exact && inLen == remain){
6193     DBG (10, "read_from_scanner: exact read, clearing\n");
6194     ret = object_position (s,SANE_FALSE);
6195     if(ret){
6196       return ret;
6197     }
6198     ret = SANE_STATUS_EOF;
6199   }
6200 
6201   if(ret == SANE_STATUS_EOF){
6202 
6203     /* this is jpeg data, we need to change the total size */
6204     if(s->s.format == SANE_FRAME_JPEG){
6205       s->s.bytes_tot[side] = s->s.bytes_sent[side];
6206       s->i.bytes_tot[side] = s->i.bytes_sent[side];
6207       s->u.bytes_tot[side] = s->i.bytes_sent[side];
6208     }
6209 
6210     /* this is non-jpeg data, fill remainder, change rx'd size */
6211     else{
6212       fill_image(s,side);
6213     }
6214 
6215     s->i.eof[side] = 1;
6216     s->s.eof[side] = 1;
6217     ret = SANE_STATUS_GOOD;
6218   }
6219 
6220   DBG(15, "read_from_scanner: sto:%d srx:%d sef:%d uto:%d urx:%d uef:%d\n",
6221     s->s.bytes_tot[side], s->s.bytes_sent[side], s->s.eof[side],
6222     s->u.bytes_tot[side], s->u.bytes_sent[side], s->u.eof[side]);
6223 
6224   DBG (10, "read_from_scanner: finish\n");
6225 
6226   return ret;
6227 }
6228 
6229 /* cheaper scanners interlace duplex scans on a byte basis
6230  * this code requests double width lines from scanner */
6231 static SANE_Status
read_from_scanner_duplex(struct scanner * s,int exact)6232 read_from_scanner_duplex(struct scanner *s,int exact)
6233 {
6234   SANE_Status ret=SANE_STATUS_GOOD;
6235 
6236   unsigned char cmd[READ_len];
6237   size_t cmdLen = READ_len;
6238 
6239   unsigned char * in;
6240   size_t inLen = 0;
6241 
6242   size_t bytes = s->buffer_size;
6243   size_t remain = s->s.bytes_tot[SIDE_FRONT] + s->s.bytes_tot[SIDE_BACK]
6244     - s->s.bytes_sent[SIDE_FRONT] - s->s.bytes_sent[SIDE_BACK];
6245 
6246   DBG (10, "read_from_scanner_duplex: start\n");
6247 
6248   /* all requests must end on WIDE line boundary */
6249   bytes -= (bytes % (s->s.Bpl*2));
6250 
6251   /* usually (image) we want to read too much data, and get RS */
6252   /* sometimes (calib) we want to do an exact read */
6253   if(exact && bytes > remain){
6254     bytes = remain;
6255   }
6256 
6257   DBG(15, "read_from_scanner_duplex: re:%lu bu:%d pa:%lu ex:%d\n",
6258       (unsigned long)remain, s->buffer_size, (unsigned long)bytes, exact);
6259 
6260   inLen = bytes;
6261   in = malloc(inLen);
6262   if(!in){
6263     DBG(5, "read_from_scanner_duplex: not enough mem for buffer: %d\n",
6264       (int)inLen);
6265     return SANE_STATUS_NO_MEM;
6266   }
6267 
6268   memset(cmd,0,cmdLen);
6269   set_SCSI_opcode(cmd, READ_code);
6270   set_R_datatype_code (cmd, SR_datatype_image);
6271 
6272   set_R_xfer_length (cmd, inLen);
6273 
6274   ret = do_cmd (
6275     s, 1, 0,
6276     cmd, cmdLen,
6277     NULL, 0,
6278     in, &inLen
6279   );
6280 
6281   if (ret == SANE_STATUS_GOOD) {
6282     DBG(15, "read_from_scanner_duplex: got GOOD, returning GOOD %lu\n", (unsigned long)inLen);
6283   }
6284   else if (ret == SANE_STATUS_EOF) {
6285     DBG(15, "read_from_scanner_duplex: got EOF, finishing %lu\n", (unsigned long)inLen);
6286   }
6287   else if (ret == SANE_STATUS_DEVICE_BUSY) {
6288     DBG(5, "read_from_scanner_duplex: got BUSY, returning GOOD\n");
6289     inLen = 0;
6290     ret = SANE_STATUS_GOOD;
6291   }
6292   else {
6293     DBG(5, "read_from_scanner_duplex: error reading data block status = %d\n",
6294       ret);
6295     inLen = 0;
6296   }
6297 
6298   /*scanner may have sent more data than we asked for, chop it*/
6299   if(inLen > remain){
6300     inLen = remain;
6301   }
6302 
6303   /* we've got some data, descramble and store it */
6304   if(inLen){
6305     copy_duplex(s,in,inLen);
6306   }
6307 
6308   free(in);
6309 
6310   /* we've read all data, but not eof. clear and pretend */
6311   if(exact && inLen == remain){
6312     DBG (10, "read_from_scanner_duplex: exact read, clearing\n");
6313     ret = object_position (s,SANE_FALSE);
6314     if(ret){
6315       return ret;
6316     }
6317     ret = SANE_STATUS_EOF;
6318   }
6319 
6320   if(ret == SANE_STATUS_EOF){
6321 
6322     /* this is jpeg data, we need to change the total size */
6323     if(s->s.format == SANE_FRAME_JPEG){
6324       s->s.bytes_tot[SIDE_FRONT] = s->s.bytes_sent[SIDE_FRONT];
6325       s->s.bytes_tot[SIDE_BACK] = s->s.bytes_sent[SIDE_BACK];
6326       s->i.bytes_tot[SIDE_FRONT] = s->i.bytes_sent[SIDE_FRONT];
6327       s->i.bytes_tot[SIDE_BACK] = s->i.bytes_sent[SIDE_BACK];
6328       s->u.bytes_tot[SIDE_FRONT] = s->i.bytes_sent[SIDE_FRONT];
6329       s->u.bytes_tot[SIDE_BACK] = s->i.bytes_sent[SIDE_BACK];
6330     }
6331 
6332     /* this is non-jpeg data, fill remainder, change rx'd size */
6333     else{
6334       fill_image(s,SIDE_FRONT);
6335       fill_image(s,SIDE_BACK);
6336     }
6337 
6338     s->i.eof[SIDE_FRONT] = 1;
6339     s->i.eof[SIDE_BACK] = 1;
6340     s->s.eof[SIDE_FRONT] = 1;
6341     s->s.eof[SIDE_BACK] = 1;
6342     ret = SANE_STATUS_GOOD;
6343   }
6344 
6345   DBG (10, "read_from_scanner_duplex: finish\n");
6346 
6347   return ret;
6348 }
6349 
6350 /* these functions copy image data from input buffer to scanner struct
6351  * descrambling it, and putting it in the right side buffer */
6352 /* NOTE: they assume buffer is scanline aligned */
6353 static SANE_Status
copy_simplex(struct scanner * s,unsigned char * buf,int len,int side)6354 copy_simplex(struct scanner *s, unsigned char * buf, int len, int side)
6355 {
6356   SANE_Status ret=SANE_STATUS_GOOD;
6357   int i, j;
6358   int bwidth = s->s.Bpl;
6359   int pwidth = s->s.width;
6360   int t = bwidth/3;
6361   int f = bwidth/4;
6362   int tw = bwidth/12;
6363 
6364   unsigned char * line = NULL;
6365   int line_next = 0;
6366   int inter = get_color_inter(s,side,s->s.dpi_x);
6367 
6368   /* jpeg data should not pass thru this function, so copy and bail out */
6369   if(s->s.format > SANE_FRAME_RGB){
6370     DBG (15, "copy_simplex: jpeg bulk copy\n");
6371     memcpy(s->buffers[side]+s->i.bytes_sent[side], buf, len);
6372     s->i.bytes_sent[side] += len;
6373     s->s.bytes_sent[side] += len;
6374     return ret;
6375   }
6376 
6377   DBG (15, "copy_simplex: per-line copy\n");
6378 
6379   line = malloc(bwidth);
6380   if(!line) return SANE_STATUS_NO_MEM;
6381 
6382   /* ingest each line */
6383   for(i=0; i<len; i+=bwidth){
6384 
6385     int lineNum = s->s.bytes_sent[side] / bwidth;
6386 
6387     /*increment number of bytes rx'd from scanner*/
6388     s->s.bytes_sent[side] += bwidth;
6389 
6390     /*have some padding from scanner to drop*/
6391     if ( lineNum < s->i.skip_lines[side]
6392       || lineNum - s->i.skip_lines[side] >= s->i.height
6393     ){
6394       continue;
6395     }
6396 
6397     line_next = 0;
6398 
6399     if(s->s.format == SANE_FRAME_GRAY){
6400 
6401       switch (s->gray_interlace[side]) {
6402 
6403         /* one line has the following format: ggg...GGG
6404          * where the 'capital' letters are the beginning of the line */
6405         case GRAY_INTERLACE_gG:
6406           DBG (17, "copy_simplex: gray, gG\n");
6407           for (j=bwidth-1; j>=0; j--){
6408             line[line_next++] = buf[i+j];
6409           }
6410           break;
6411 
6412         case GRAY_INTERLACE_2510:
6413           DBG (17, "copy_simplex: gray, 2510\n");
6414 
6415           /* first read head (third byte of every three) */
6416           for(j=bwidth-1;j>=0;j-=3){
6417             line[line_next++] = buf[i+j];
6418           }
6419           /* second read head (first byte of every three) */
6420           for(j=bwidth*3/4-3;j>=0;j-=3){
6421             line[line_next++] = buf[i+j];
6422           }
6423           /* third read head (second byte of every three) */
6424           for(j=bwidth-2;j>=0;j-=3){
6425             line[line_next++] = buf[i+j];
6426           }
6427           /* padding */
6428           for(j=0;j<tw;j++){
6429             line[line_next++] = 0;
6430           }
6431           break;
6432 
6433         case GRAY_INTERLACE_C120:
6434           DBG (17, "copy_simplex: gray, C120\n");
6435 
6436           /* first read head (third byte of every three) */
6437           for(j=bwidth-1;j>=0;j-=3){
6438             line[line_next++] = buf[i+j];
6439           }
6440           /* second read head (first byte of every three) */
6441           for(j=bwidth-3;j>=0;j-=3){
6442             line[line_next++] = buf[i+j];
6443           }
6444           /* third read head (second byte of every three) */
6445           for(j=bwidth-2;j>=0;j-=3){
6446             line[line_next++] = buf[i+j];
6447           }
6448           break;
6449       }
6450     }
6451 
6452     else if (s->s.format == SANE_FRAME_RGB){
6453 
6454       switch (inter) {
6455 
6456         /* scanner returns color data as bgrbgr... */
6457         case COLOR_INTERLACE_BGR:
6458           DBG (17, "copy_simplex: color, BGR\n");
6459           for (j=0; j<pwidth; j++){
6460             line[line_next++] = buf[i+j*3+2];
6461             line[line_next++] = buf[i+j*3+1];
6462             line[line_next++] = buf[i+j*3];
6463           }
6464           break;
6465 
6466         /* scanner returns color data as gbrgbr... */
6467         case COLOR_INTERLACE_GBR:
6468           DBG (17, "copy_simplex: color, GBR\n");
6469           for (j=0; j<pwidth; j++){
6470             line[line_next++] = buf[i+j*3+2];
6471             line[line_next++] = buf[i+j*3];
6472             line[line_next++] = buf[i+j*3+1];
6473           }
6474           break;
6475 
6476         /* scanner returns color data as brgbrg... */
6477         case COLOR_INTERLACE_BRG:
6478           DBG (17, "copy_simplex: color, BRG\n");
6479           for (j=0; j<pwidth; j++){
6480             line[line_next++] = buf[i+j*3+1];
6481             line[line_next++] = buf[i+j*3+2];
6482             line[line_next++] = buf[i+j*3];
6483           }
6484           break;
6485 
6486         /* one line has the following format: RRR...rrrGGG...gggBBB...bbb */
6487         case COLOR_INTERLACE_RRGGBB:
6488           DBG (17, "copy_simplex: color, RRGGBB\n");
6489           for (j=0; j<pwidth; j++){
6490             line[line_next++] = buf[i+j];
6491             line[line_next++] = buf[i+pwidth+j];
6492             line[line_next++] = buf[i+2*pwidth+j];
6493           }
6494           break;
6495 
6496         /* one line has the following format: rrr...RRRggg...GGGbbb...BBB
6497          * where the 'capital' letters are the beginning of the line */
6498         case COLOR_INTERLACE_rRgGbB:
6499           DBG (17, "copy_simplex: color, rRgGbB\n");
6500           for (j=pwidth-1; j>=0; j--){
6501             line[line_next++] = buf[i+j];
6502             line[line_next++] = buf[i+pwidth+j];
6503             line[line_next++] = buf[i+2*pwidth+j];
6504           }
6505           break;
6506 
6507         case COLOR_INTERLACE_2510:
6508           DBG (17, "copy_simplex: color, 2510\n");
6509 
6510           /* first read head (third byte of every three) */
6511           for(j=t-1;j>=0;j-=3){
6512             line[line_next++] = buf[i+j];
6513             line[line_next++] = buf[i+t+j];
6514             line[line_next++] = buf[i+2*t+j];
6515           }
6516           /* second read head (first byte of every three) */
6517           for(j=f-3;j>=0;j-=3){
6518             line[line_next++] = buf[i+j];
6519             line[line_next++] = buf[i+t+j];
6520             line[line_next++] = buf[i+2*t+j];
6521           }
6522           /* third read head (second byte of every three) */
6523           for(j=t-2;j>=0;j-=3){
6524             line[line_next++] = buf[i+j];
6525             line[line_next++] = buf[i+t+j];
6526             line[line_next++] = buf[i+2*t+j];
6527           }
6528           /* padding */
6529           for(j=0;j<tw;j++){
6530             line[line_next++] = 0;
6531           }
6532           break;
6533 
6534         case COLOR_INTERLACE_C120:
6535           DBG (17, "copy_simplex: color, C120\n");
6536 
6537           /* first read head (third byte of every three) */
6538           for(j=t-1;j>=0;j-=3){
6539             line[line_next++] = buf[i+j];
6540             line[line_next++] = buf[i+t+j];
6541             line[line_next++] = buf[i+2*t+j];
6542           }
6543           /* second read head (first byte of every three) */
6544           for(j=t-3;j>=0;j-=3){
6545             line[line_next++] = buf[i+j];
6546             line[line_next++] = buf[i+t+j];
6547             line[line_next++] = buf[i+2*t+j];
6548           }
6549           /* third read head (second byte of every three) */
6550           for(j=t-2;j>=0;j-=3){
6551             line[line_next++] = buf[i+j];
6552             line[line_next++] = buf[i+t+j];
6553             line[line_next++] = buf[i+2*t+j];
6554           }
6555           break;
6556       }
6557     }
6558 
6559     /* nothing sent above? just copy one line of the block */
6560     /* used by uninterlaced gray/color */
6561     if(!line_next){
6562       DBG (17, "copy_simplex: default\n");
6563       memcpy(line+line_next,buf+i,bwidth);
6564       line_next = bwidth;
6565     }
6566 
6567     /* invert image if scanner needs it for this mode */
6568     if(s->reverse_by_mode[s->s.mode]){
6569       for(j=0; j<line_next; j++){
6570         line[j] ^= 0xff;
6571       }
6572     }
6573 
6574     /* apply calibration if we have it */
6575     if(s->f_offset[side]){
6576       DBG (17, "copy_simplex: apply offset\n");
6577       for(j=0; j<s->s.valid_Bpl; j++){
6578         int curr = line[j] - s->f_offset[side][j];
6579         if(curr < 0) curr = 0;
6580         line[j] = curr;
6581       }
6582     }
6583 
6584     if(s->f_gain[side]){
6585       DBG (17, "copy_simplex: apply gain\n");
6586       for(j=0; j<s->s.valid_Bpl; j++){
6587         int curr = line[j] * 240/s->f_gain[side][j];
6588         if(curr > 255) curr = 255;
6589         line[j] = curr;
6590       }
6591     }
6592 
6593     /* apply brightness and contrast if hardware cannot do it */
6594     if(s->sw_lut && (s->s.mode == MODE_COLOR || s->s.mode == MODE_GRAYSCALE)){
6595       DBG (17, "copy_simplex: apply brightness/contrast\n");
6596       for(j=0; j<s->s.valid_Bpl; j++){
6597         line[j] = s->lut[line[j]];
6598       }
6599     }
6600 
6601     /*copy the line into the buffer*/
6602     ret = copy_line(s,line,side);
6603     if(ret){
6604       break;
6605     }
6606   }
6607 
6608   free(line);
6609 
6610   DBG (10, "copy_simplex: finished\n");
6611 
6612   return ret;
6613 }
6614 
6615 /* split the data between two buffers, hand them to copy_simplex()
6616  * assumes that the buffer aligns to a double-wide line boundary */
6617 static SANE_Status
copy_duplex(struct scanner * s,unsigned char * buf,int len)6618 copy_duplex(struct scanner *s, unsigned char * buf, int len)
6619 {
6620   SANE_Status ret=SANE_STATUS_GOOD;
6621   int i,j;
6622   int pwidth = s->s.width;
6623   int bwidth = s->s.Bpl;
6624   int dbwidth = 2*bwidth;
6625   unsigned char * front;
6626   unsigned char * back;
6627   int flen=0, blen=0;
6628 
6629   DBG (10, "copy_duplex: start\n");
6630 
6631   /*split the input into two simplex output buffers*/
6632   front = calloc(1,len/2);
6633   if(!front){
6634     DBG (5, "copy_duplex: no front mem\n");
6635     return SANE_STATUS_NO_MEM;
6636   }
6637   back = calloc(1,len/2);
6638   if(!back){
6639     DBG (5, "copy_duplex: no back mem\n");
6640     free(front);
6641     return SANE_STATUS_NO_MEM;
6642   }
6643 
6644   if(s->duplex_interlace == DUPLEX_INTERLACE_2510){
6645 
6646     DBG (10, "copy_duplex: 2510\n");
6647 
6648     for(i=0; i<len; i+=dbwidth){
6649 
6650       for(j=0;j<dbwidth;j+=6){
6651 
6652         /* we are actually only partially descrambling,
6653          * copy_simplex() does the rest */
6654 
6655         /* front */
6656         /* 2nd head: 2nd byte -> 1st byte */
6657         /* 3rd head: 4th byte -> 2nd byte */
6658         /* 1st head: 5th byte -> 3rd byte */
6659         front[flen++] = buf[i+j+2];
6660         front[flen++] = buf[i+j+4];
6661         front[flen++] = buf[i+j+5];
6662 
6663         /* back */
6664         /* 2nd head: 3rd byte -> 1st byte */
6665         /* 3rd head: 0th byte -> 2nd byte */
6666         /* 1st head: 1st byte -> 3rd byte */
6667         back[blen++] = buf[i+j+3];
6668         back[blen++] = buf[i+j];
6669         back[blen++] = buf[i+j+1];
6670       }
6671     }
6672   }
6673 
6674   /* line is in 6 sections, front red, back red, front green, etc. */
6675   else if(s->duplex_interlace == DUPLEX_INTERLACE_PER_CHANNEL){
6676 
6677     DBG (10, "copy_duplex: per channel\n");
6678 
6679     for(i=0; i<len; i+=dbwidth){
6680       for(j=0;j<3;j++){
6681         memcpy(front+flen,buf+i+j*pwidth*2,pwidth);
6682         flen+=pwidth;
6683         memcpy(back+blen,buf+i+j*pwidth*2+pwidth,pwidth);
6684         blen+=pwidth;
6685       }
6686     }
6687   }
6688 
6689   /* full line of front, then full line of back */
6690   else if(s->duplex_interlace == DUPLEX_INTERLACE_FfBb || s->duplex_interlace == DUPLEX_INTERLACE_fFBb){
6691     for(i=0; i<len; i+=dbwidth){
6692       if(s->duplex_interlace == DUPLEX_INTERLACE_FfBb){
6693         memcpy(front+flen,buf+i,bwidth);
6694       }else{
6695         rmemcpy(front+flen,buf+i,bwidth,3); // only 24bit color is supported
6696       }
6697       flen+=bwidth;
6698       memcpy(back+blen,buf+i+bwidth,bwidth);
6699       blen+=bwidth;
6700     }
6701   }
6702 
6703   /*just alternating bytes, FBfb*/
6704   else {
6705     for(i=0; i<len; i+=2){
6706       front[flen++] = buf[i];
6707       back[blen++] = buf[i+1];
6708     }
6709   }
6710 
6711   copy_simplex(s,front,flen,SIDE_FRONT);
6712   copy_simplex(s,back,blen,SIDE_BACK);
6713 
6714   free(front);
6715   free(back);
6716 
6717   DBG (10, "copy_duplex: finished\n");
6718 
6719   return ret;
6720 }
6721 
6722 /*
6723  * Reverse memcpy designed to mirror a line of data.
6724  * Use stride size to account for the number of bytes per pixel
6725  */
rmemcpy(void * dest,const void * src,size_t count,size_t stride)6726 static void rmemcpy(void* dest, const void* src, size_t count, size_t stride) {
6727   char* dstptr = (char*)dest;
6728   char* srcptr = (char*)src;
6729   srcptr += count;
6730   while (count) {
6731     srcptr -= stride;
6732     memcpy(dstptr, srcptr, stride);
6733     dstptr += stride;
6734     count -= stride;
6735   }
6736 }
6737 
6738 /* downsample a single line from scanner's size to user's size */
6739 /* and copy into final buffer */
6740 static SANE_Status
copy_line(struct scanner * s,unsigned char * buff,int side)6741 copy_line(struct scanner *s, unsigned char * buff, int side)
6742 {
6743   SANE_Status ret=SANE_STATUS_GOOD;
6744   int spwidth = s->s.width;
6745   int sbwidth = s->s.Bpl;
6746   int ibwidth = s->i.Bpl;
6747   unsigned char * line;
6748   int offset = 0;
6749   int i, j;
6750 
6751   DBG (20, "copy_line: start\n");
6752 
6753   /* the 'standard' case: non-stupid scan */
6754   if(s->s.width == s->i.width
6755     && s->s.dpi_x == s->i.dpi_x
6756     && s->s.mode == s->i.mode
6757   ){
6758 
6759     memcpy(s->buffers[side]+s->i.bytes_sent[side], buff, sbwidth);
6760     s->i.bytes_sent[side] += sbwidth;
6761 
6762     DBG (20, "copy_line: finished smart\n");
6763     return ret;
6764   }
6765 
6766   /* the 'corner' case: stupid scan */
6767 
6768   /*setup 24 bit color single line buffer*/
6769   line = malloc(spwidth*3);
6770   if(!line) return SANE_STATUS_NO_MEM;
6771 
6772   /*load single line color buffer*/
6773   switch (s->s.mode) {
6774 
6775     case MODE_COLOR:
6776       if(must_downsample(s) && s->dropout_color[side]){
6777         switch(s->dropout_color[side]){
6778           case COLOR_RED:
6779             for(i=0;i<spwidth;i++)
6780               line[i*3] = line[i*3+1] = line[i*3+2] = buff[i*3];
6781             break;
6782           case COLOR_GREEN:
6783             for(i=0;i<spwidth;i++)
6784               line[i*3] = line[i*3+1] = line[i*3+2] = buff[i*3+1];
6785             break;
6786           case COLOR_BLUE:
6787             for(i=0;i<spwidth;i++)
6788               line[i*3] = line[i*3+1] = line[i*3+2] = buff[i*3+2];
6789             break;
6790           case COLOR_EN_RED:
6791             for(i=0;i<spwidth;i++){
6792               line[i*3] = (buff[i*3+1] + buff[i*3+2])/2;
6793               line[i*3+1] = buff[i*3+1];
6794               line[i*3+2] = buff[i*3+2];
6795             }
6796             break;
6797           case COLOR_EN_GREEN:
6798             for(i=0;i<spwidth;i++){
6799               line[i*3] = buff[i*3];
6800               line[i*3+1] = (buff[i*3] + buff[i*3+2])/2;
6801               line[i*3+2] = buff[i*3+2];
6802             }
6803             break;
6804           case COLOR_EN_BLUE:
6805             for(i=0;i<spwidth;i++){
6806               line[i*3] = buff[i*3];
6807               line[i*3+1] = buff[i*3+1];
6808               line[i*3+2] = (buff[i*3] + buff[i*3+1])/2;
6809             }
6810             break;
6811         }
6812       }
6813       else{
6814         memcpy(line, buff, sbwidth);
6815       }
6816       break;
6817 
6818     case MODE_GRAYSCALE:
6819       for(i=0;i<spwidth;i++){
6820         line[i*3] = line[i*3+1] = line[i*3+2] = buff[i];
6821       }
6822       break;
6823 
6824     default:
6825       for(i=0;i<sbwidth;i++){
6826         unsigned char curr = buff[i];
6827 
6828         line[i*24+0] = line[i*24+1] = line[i*24+2] = ((curr >> 7) & 1) ?0:255;
6829         line[i*24+3] = line[i*24+4] = line[i*24+5] = ((curr >> 6) & 1) ?0:255;
6830         line[i*24+6] = line[i*24+7] = line[i*24+8] = ((curr >> 5) & 1) ?0:255;
6831         line[i*24+9] = line[i*24+10] = line[i*24+11] = ((curr >> 4) & 1) ?0:255;
6832         line[i*24+12] = line[i*24+13] = line[i*24+14] =((curr >> 3) & 1) ?0:255;
6833         line[i*24+15] = line[i*24+16] = line[i*24+17] =((curr >> 2) & 1) ?0:255;
6834         line[i*24+18] = line[i*24+19] = line[i*24+20] =((curr >> 1) & 1) ?0:255;
6835         line[i*24+21] = line[i*24+22] = line[i*24+23] =((curr >> 0) & 1) ?0:255;
6836       }
6837       break;
6838   }
6839 
6840   /* scan is higher res than user wanted, scale it */
6841   /*FIXME: interpolate instead */
6842   if(s->i.dpi_x != s->s.dpi_x){
6843     for(i=0;i<spwidth;i++){
6844       int source = i * s->s.dpi_x/s->i.dpi_x * 3;
6845 
6846       if(source+2 >= spwidth*3)
6847         break;
6848 
6849       line[i*3] = line[source];
6850       line[i*3+1] = line[source+1];
6851       line[i*3+2] = line[source+2];
6852     }
6853   }
6854 
6855   /* scan is wider than user wanted, skip some pixels on left side */
6856   if(s->i.width != s->s.width){
6857     offset = ((s->valid_x-s->i.page_x) / 2 + s->i.tl_x) * s->i.dpi_x/1200;
6858   }
6859 
6860   /* change mode, store line in buffer */
6861   switch (s->i.mode) {
6862 
6863     case MODE_COLOR:
6864       memcpy(s->buffers[side]+s->i.bytes_sent[side], line+(offset*3), ibwidth);
6865       s->i.bytes_sent[side] += ibwidth;
6866       break;
6867 
6868     case MODE_GRAYSCALE:
6869       for(i=0;i<ibwidth;i++){
6870         int source = (offset+i)*3;
6871         s->buffers[side][s->i.bytes_sent[side]++]
6872           = ((int)line[source] + line[source+1] + line[source+2])/3;
6873       }
6874       break;
6875 
6876     default:
6877       /*loop over output bytes*/
6878       for(i=0;i<ibwidth;i++){
6879 
6880         unsigned char curr = 0;
6881         int thresh = s->threshold*3;
6882 
6883         /*loop over output bits*/
6884         for(j=0;j<8;j++){
6885           int source = offset*3 + i*24 + j*3;
6886           if( (line[source] + line[source+1] + line[source+2]) < thresh ){
6887             curr |= 1 << (7-j);
6888           }
6889         }
6890 
6891         s->buffers[side][s->i.bytes_sent[side]++] = curr;
6892       }
6893       break;
6894   }
6895 
6896   free(line);
6897 
6898   DBG (20, "copy_line: finish stupid\n");
6899 
6900   return ret;
6901 }
6902 
6903 static SANE_Status
read_from_buffer(struct scanner * s,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len,int side)6904 read_from_buffer(struct scanner *s, SANE_Byte * buf, SANE_Int max_len,
6905   SANE_Int * len, int side)
6906 {
6907   SANE_Status ret=SANE_STATUS_GOOD;
6908   int bytes = max_len;
6909   int remain = s->i.bytes_sent[side] - s->u.bytes_sent[side];
6910 
6911   DBG (10, "read_from_buffer: start\n");
6912 
6913   /* figure out the max amount to transfer */
6914   if(bytes > remain)
6915     bytes = remain;
6916 
6917   *len = bytes;
6918 
6919   /*FIXME this needs to timeout eventually */
6920   if(!bytes){
6921     DBG(5,"read_from_buffer: nothing to do\n");
6922     return SANE_STATUS_GOOD;
6923   }
6924 
6925   DBG(15, "read_from_buffer: si:%d to:%d tx:%d bu:%d pa:%d\n", side,
6926     s->i.bytes_tot[side], s->u.bytes_sent[side], max_len, bytes);
6927 
6928   /* copy to caller */
6929   memcpy(buf,s->buffers[side]+s->u.bytes_sent[side],bytes);
6930   s->u.bytes_sent[side] += bytes;
6931 
6932   DBG (10, "read_from_buffer: finished\n");
6933 
6934   return ret;
6935 }
6936 
6937 /* fill remainder of buffer with background if scanner stops early */
6938 static SANE_Status
fill_image(struct scanner * s,int side)6939 fill_image(struct scanner *s,int side)
6940 {
6941   SANE_Status ret=SANE_STATUS_GOOD;
6942 
6943   unsigned char bg_color = calc_bg_color(s);
6944   int fill_bytes = s->i.bytes_tot[side]-s->i.bytes_sent[side];
6945 
6946   if(!fill_bytes){
6947     return ret;
6948   }
6949 
6950   DBG (15, "fill_image: side:%d bytes:%d bg_color:%02x\n", side, fill_bytes, bg_color);
6951 
6952   /* fill the rest with bg_color */
6953   memset(s->buffers[side]+s->i.bytes_sent[side],bg_color,fill_bytes);
6954 
6955   /* pretend we got all the data from scanner */
6956   s->i.bytes_sent[side] = s->i.bytes_tot[side];
6957   s->s.bytes_sent[side] = s->s.bytes_tot[side];
6958 
6959   return ret;
6960 }
6961 
6962 /* return the bg color based on scanner settings */
6963 static unsigned char
calc_bg_color(struct scanner * s)6964 calc_bg_color(struct scanner *s)
6965 {
6966   unsigned char bg_color = s->lut[s->bg_color];
6967 
6968   if(s->u.mode <= MODE_HALFTONE)
6969     bg_color = (bg_color<s->threshold)?0xff:0x00;
6970 
6971   return bg_color;
6972 }
6973 
6974 /*
6975  * @@ Section 5 - calibration functions
6976  */
6977 
6978 #if 0
6979 static SANE_Status
6980 foo_AFE(struct scanner *s)
6981 {
6982   SANE_Status ret = SANE_STATUS_GOOD;
6983 
6984   unsigned char cmd[] = {
6985     0x3b, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00
6986   };
6987   size_t cmdLen = 12;
6988 
6989   unsigned char in[4];
6990   size_t inLen = 4;
6991 
6992   DBG (10, "foo_AFE: start\n");
6993 
6994   ret = do_cmd (
6995     s, 1, 0,
6996     cmd, cmdLen,
6997     NULL, 0,
6998     in, &inLen
6999   );
7000   if (ret != SANE_STATUS_GOOD)
7001     return ret;
7002 
7003   DBG (10, "foo_AFE: finish\n");
7004 
7005   return ret;
7006 }
7007 #endif
7008 
7009 /*
7010  * makes several scans, adjusts coarse calibration
7011  */
7012 static SANE_Status
calibrate_AFE(struct scanner * s)7013 calibrate_AFE (struct scanner *s)
7014 {
7015   SANE_Status ret = SANE_STATUS_GOOD;
7016   int i, j, k;
7017   int min, max;
7018   int lines = 8;
7019 
7020   /*buffer these for later*/
7021   int old_tl_y = s->u.tl_y;
7022   int old_br_y = s->u.br_y;
7023   int old_mode = s->u.mode;
7024   int old_source = s->u.source;
7025 
7026   DBG (10, "calibrate_AFE: start\n");
7027 
7028   if(!s->need_ccal){
7029     DBG (10, "calibrate_AFE: not required\n");
7030     return ret;
7031   }
7032 
7033   /* always cal with a short scan in duplex color */
7034   s->u.tl_y = 0;
7035   s->u.br_y = lines * 1200 / s->u.dpi_y;
7036   s->u.mode = MODE_COLOR;
7037   s->u.source = SOURCE_ADF_DUPLEX;
7038 
7039   /* load our own private copy of scan params */
7040   ret = update_params(s,1);
7041   if (ret != SANE_STATUS_GOOD) {
7042     DBG (5, "calibrate_AFE: ERROR: cannot update_params\n");
7043     goto cleanup;
7044   }
7045 
7046   if(s->c_res == s->s.dpi_x && s->c_mode == s->s.mode){
7047     DBG (10, "calibrate_AFE: already done\n");
7048     goto cleanup;
7049   }
7050 
7051   /* clean scan params for new scan */
7052   ret = clean_params(s);
7053   if (ret != SANE_STATUS_GOOD) {
7054     DBG (5, "calibrate_AFE: ERROR: cannot clean_params\n");
7055     goto cleanup;
7056   }
7057 
7058   /* make buffers to hold the images */
7059   ret = image_buffers(s,1);
7060   if (ret != SANE_STATUS_GOOD) {
7061     DBG (5, "calibrate_AFE: ERROR: cannot load buffers\n");
7062     goto cleanup;
7063   }
7064 
7065   /*blast the existing fine cal data so reading code won't apply it*/
7066   ret = offset_buffers(s,0);
7067   ret = gain_buffers(s,0);
7068 
7069   /* need to tell it we want duplex */
7070   ret = ssm_buffer(s);
7071   if (ret != SANE_STATUS_GOOD) {
7072     DBG (5, "calibrate_AFE: ERROR: cannot ssm buffer\n");
7073     goto cleanup;
7074   }
7075 
7076   /* set window command */
7077   ret = set_window(s);
7078   if (ret != SANE_STATUS_GOOD) {
7079     DBG (5, "calibrate_AFE: ERROR: cannot set window\n");
7080     goto cleanup;
7081   }
7082 
7083   /* first pass (black offset), lamp off, no offset/gain/exposure */
7084   DBG (15, "calibrate_AFE: offset\n");
7085 
7086   /* blast all the existing coarse cal data */
7087   for(i=0;i<2;i++){
7088     s->c_gain[i]   = 1;
7089     s->c_offset[i] = 1;
7090     for(j=0;j<3;j++){
7091       s->c_exposure[i][j] = 0;
7092     }
7093   }
7094 
7095   ret = write_AFE(s);
7096   if (ret != SANE_STATUS_GOOD) {
7097     DBG (5, "calibrate_AFE: ERROR: cannot write afe\n");
7098     goto cleanup;
7099   }
7100 
7101   ret = calibration_scan(s,0xff);
7102   if (ret != SANE_STATUS_GOOD) {
7103     DBG (5, "calibrate_AFE: ERROR: cannot make offset cal scan\n");
7104     goto cleanup;
7105   }
7106 
7107   for(i=0;i<2;i++){
7108     min = 255;
7109     for(j=0; j<s->s.valid_Bpl; j++){
7110       if(s->buffers[i][j] < min)
7111         min = s->buffers[i][j];
7112     }
7113     s->c_offset[i] = min*3-2;
7114     DBG (15, "calibrate_AFE: offset %d %d %02x\n", i, min, s->c_offset[i]);
7115   }
7116 
7117   /*handle second pass (per channel exposure), lamp on, overexposed*/
7118   DBG (15, "calibrate_AFE: exposure\n");
7119   for(i=0;i<2;i++){
7120     for(j=0; j<3; j++){
7121       s->c_exposure[i][j] = 0x320;
7122     }
7123   }
7124 
7125   ret = write_AFE(s);
7126   if (ret != SANE_STATUS_GOOD) {
7127     DBG (5, "calibrate_AFE: ERROR: cannot write afe\n");
7128     goto cleanup;
7129   }
7130 
7131   ret = calibration_scan(s,0xfe);
7132   if (ret != SANE_STATUS_GOOD) {
7133     DBG (5, "calibrate_AFE: ERROR: cannot make exposure cal scan\n");
7134     goto cleanup;
7135   }
7136 
7137   for(i=0;i<2;i++){ /*sides*/
7138     for(j=0;j<3;j++){ /*channels*/
7139       max = 0;
7140       for(k=j; k<s->s.valid_Bpl; k+=3){ /*bytes*/
7141         if(s->buffers[i][k] > max)
7142           max = s->buffers[i][k];
7143       }
7144 
7145       /*generally we reduce the exposure (smaller number) */
7146       if(old_mode == MODE_COLOR)
7147         s->c_exposure[i][j] = s->c_exposure[i][j] * 102/max;
7148       else
7149         s->c_exposure[i][j] = s->c_exposure[i][j] * 64/max;
7150 
7151       DBG (15, "calibrate_AFE: exp %d %d %d %02x\n", i, j, max,
7152         s->c_exposure[i][j]);
7153     }
7154   }
7155 
7156   /*handle third pass (gain), lamp on with current offset/exposure */
7157   DBG (15, "calibrate_AFE: gain\n");
7158 
7159   ret = write_AFE(s);
7160   if (ret != SANE_STATUS_GOOD) {
7161     DBG (5, "calibrate_AFE: ERROR: cannot write afe\n");
7162     goto cleanup;
7163   }
7164 
7165   ret = calibration_scan(s,0xfe);
7166   if (ret != SANE_STATUS_GOOD) {
7167     DBG (5, "calibrate_AFE: ERROR: cannot make gain cal scan\n");
7168     goto cleanup;
7169   }
7170 
7171   for(i=0;i<2;i++){
7172     max = 0;
7173     for(j=0; j<s->s.valid_Bpl; j++){
7174       if(s->buffers[i][j] > max)
7175         max = s->buffers[i][j];
7176     }
7177 
7178     if(old_mode == MODE_COLOR)
7179       s->c_gain[i] = (250-max)*4/5;
7180     else
7181       s->c_gain[i] = (125-max)*4/5;
7182 
7183     if(s->c_gain[i] < 1)
7184       s->c_gain[i] = 1;
7185 
7186     DBG (15, "calibrate_AFE: gain %d %d %02x\n", i, max, s->c_gain[i]);
7187   }
7188 
7189   /*handle fourth pass (offset again), lamp off*/
7190 #if 0
7191   DBG (15, "calibrate_AFE: offset2\n");
7192 
7193   ret = write_AFE(s);
7194   if (ret != SANE_STATUS_GOOD) {
7195     DBG (5, "calibrate_AFE: ERROR: cannot write afe\n");
7196     goto cleanup;
7197   }
7198 
7199   ret = calibration_scan(s,0xff);
7200   if (ret != SANE_STATUS_GOOD) {
7201     DBG (5, "calibrate_AFE: ERROR: cannot make offset2 cal scan\n");
7202     goto cleanup;
7203   }
7204 
7205   for(i=0;i<2;i++){
7206     min = 255;
7207     for(j=0; j<s->s.valid_Bpl; j++){
7208       if(s->buffers[i][j] < min)
7209         min = s->buffers[i][j];
7210     }
7211     /*s->c_offset[i] += min*3-2;*/
7212     DBG (15, "calibrate_AFE: offset2 %d %d %02x\n", i, min, s->c_offset[i]);
7213   }
7214 #endif
7215 
7216   /*send final afe params to scanner*/
7217   ret = write_AFE(s);
7218   if (ret != SANE_STATUS_GOOD) {
7219     DBG (5, "calibrate_AFE: ERROR: cannot write afe\n");
7220     goto cleanup;
7221   }
7222 
7223   /* log current cal type */
7224   s->c_res = s->s.dpi_x;
7225   s->c_mode = s->s.mode;
7226 
7227   cleanup:
7228 
7229   /* recover user settings */
7230   s->u.tl_y = old_tl_y;
7231   s->u.br_y = old_br_y;
7232   s->u.mode = old_mode;
7233   s->u.source = old_source;
7234 
7235   DBG (10, "calibrate_AFE: finish %d\n",ret);
7236 
7237   return ret;
7238 }
7239 
7240 /*
7241  * fine calibration produces a per-cell offset and gain value,
7242  * which is then used to adjust the output from the scanner.
7243  * There is quite a bit of variation here, with different models
7244  * needing different types/amounts of help from the software.
7245  *
7246  * This function is a common entry point for all variations.
7247  */
7248 static SANE_Status
calibrate_fine(struct scanner * s)7249 calibrate_fine (struct scanner *s)
7250 {
7251   SANE_Status ret = SANE_STATUS_GOOD;
7252 
7253   DBG (10, "calibrate_fine: start\n");
7254 
7255   if(s->fcal_src == FCAL_SRC_NONE || s->fcal_dest == FCAL_DEST_NONE){
7256     DBG (10, "calibrate_fine: not required\n");
7257     goto cleanup;
7258   }
7259 
7260   /* don't recalibrate if we've already done it with these params */
7261   if(s->f_res == s->s.dpi_x && s->f_mode == s->s.mode){
7262     DBG (10, "calibrate_fine: already done\n");
7263     goto cleanup;
7264   }
7265 
7266   /* get calibration data from scanner memory */
7267   if(s->fcal_src == FCAL_SRC_HW){
7268     ret = calibrate_fine_src_hw(s);
7269     if (ret != SANE_STATUS_GOOD)
7270       goto cleanup;
7271   }
7272 
7273   /* get calibration data by making scans */
7274   if(s->fcal_src == FCAL_SRC_SCAN){
7275     ret = calibrate_fine_src_scan(s);
7276     if (ret != SANE_STATUS_GOOD)
7277       goto cleanup;
7278   }
7279 
7280   /* send calibration data to scanner */
7281   if(s->fcal_dest == FCAL_DEST_HW){
7282     ret = calibrate_fine_dest_hw(s);
7283     if (ret != SANE_STATUS_GOOD)
7284       goto cleanup;
7285   }
7286 
7287   /* log current cal settings so we won't recalibrate on next scan with same params */
7288   s->f_res = s->s.dpi_x;
7289   s->f_mode = s->s.mode;
7290 
7291   cleanup:
7292 
7293   DBG (10, "calibrate_fine: finish %d\n",ret);
7294 
7295   return ret;
7296 }
7297 
7298 
7299 /* extracts fine calibration data from scanner memory */
7300 static SANE_Status
calibrate_fine_src_hw(struct scanner * s)7301 calibrate_fine_src_hw (struct scanner *s)
7302 {
7303   SANE_Status ret = SANE_STATUS_GOOD;
7304   int i, j, k;
7305 
7306   unsigned char cmd[READ_len];
7307   size_t cmdLen = READ_len;
7308 
7309   unsigned char * in = NULL;
7310   size_t inLen = 0, reqLen = 0;
7311 
7312   /*buffer these for later*/
7313   int old_tl_y = s->u.tl_y;
7314   int old_br_y = s->u.br_y;
7315   int old_source = s->u.source;
7316 
7317   DBG (10, "calibrate_fine_src_hw: start\n");
7318 
7319   /* pretend we are doing a 1 line scan in duplex */
7320   s->u.tl_y = 0;
7321   s->u.br_y = 1200 / s->u.dpi_y;
7322   s->u.source = SOURCE_ADF_DUPLEX;
7323 
7324   /* load our own private copy of scan params */
7325   ret = update_params(s,1);
7326   if (ret != SANE_STATUS_GOOD) {
7327     DBG (5, "calibrate_fine_src_hw: ERROR: cannot update_params\n");
7328     goto cleanup;
7329   }
7330 
7331   /* clean scan params for new scan */
7332   ret = clean_params(s);
7333   if (ret != SANE_STATUS_GOOD) {
7334     DBG (5, "calibrate_fine_src_hw: ERROR: cannot clean_params\n");
7335     goto cleanup;
7336   }
7337 
7338   /*calibration buffers in scanner are single color channel, but duplex*/
7339   reqLen = s->s.width*2;
7340 
7341   in = malloc(reqLen);
7342   if (!in) {
7343     DBG (5, "calibrate_fine_src_hw: ERROR: cannot malloc in\n");
7344     ret = SANE_STATUS_NO_MEM;
7345     goto cleanup;
7346   }
7347 
7348   /*fine offset*/
7349   ret = offset_buffers(s,1);
7350   if (ret != SANE_STATUS_GOOD) {
7351     DBG (5, "calibrate_fine_src_hw: ERROR: cannot load offset buffers\n");
7352     goto cleanup;
7353   }
7354 
7355   DBG (10, "calibrate_fine_src_hw: %d %x\n", s->s.dpi_x/10, s->s.dpi_x/10);
7356 
7357   memset(cmd,0,cmdLen);
7358   set_SCSI_opcode(cmd, READ_code);
7359   set_R_datatype_code (cmd, SR_datatype_fineoffset);
7360   set_R_xfer_lid (cmd, s->s.dpi_x/10);
7361   set_R_xfer_length (cmd, reqLen);
7362 
7363   inLen = reqLen;
7364 
7365   ret = do_cmd (
7366     s, 1, 0,
7367     cmd, cmdLen,
7368     NULL, 0,
7369     in, &inLen
7370   );
7371   if (ret != SANE_STATUS_GOOD)
7372     goto cleanup;
7373 
7374   for(i=0;i<2;i++){
7375 
7376     /*color mode, expand offset across all three channels? */
7377     if(s->s.format == SANE_FRAME_RGB){
7378       for(j=0; j<s->s.valid_width; j++){
7379 
7380         /*red*/
7381         s->f_offset[i][j*3] = in[j*2+i];
7382         if(s->f_offset[i][j*3] < 1)
7383           s->f_offset[i][j*3] = 1;
7384 
7385         /*green and blue, same as red*/
7386         s->f_offset[i][j*3+1] = s->f_offset[i][j*3+2] = s->f_offset[i][j*3];
7387       }
7388     }
7389 
7390     /*gray mode, copy*/
7391     else{
7392       for(j=0; j<s->s.valid_width; j++){
7393 
7394         s->f_offset[i][j] = in[j*2+i];
7395         if(s->f_offset[i][j] < 1)
7396           s->f_offset[i][j] = 1;
7397       }
7398     }
7399   }
7400 
7401   /*fine gain*/
7402   ret = gain_buffers(s,1);
7403   if (ret != SANE_STATUS_GOOD) {
7404     DBG (5, "calibrate_fine_src_hw: ERROR: cannot load gain buffers\n");
7405     goto cleanup;
7406   }
7407 
7408   memset(cmd,0,cmdLen);
7409   set_SCSI_opcode(cmd, READ_code);
7410   set_R_datatype_code (cmd, SR_datatype_finegain);
7411   set_R_xfer_lid (cmd, s->s.dpi_x/10);
7412   set_R_xfer_length (cmd, reqLen);
7413 
7414   /*color gain split into three buffers, grab them and merge*/
7415   if(s->s.format == SANE_FRAME_RGB){
7416 
7417     int codes[] = {R_FINE_uid_red,R_FINE_uid_green,R_FINE_uid_blue};
7418 
7419     for(k=0;k<3;k++){
7420 
7421       set_R_xfer_uid (cmd, codes[k]);
7422       inLen = reqLen;
7423 
7424       ret = do_cmd (
7425         s, 1, 0,
7426         cmd, cmdLen,
7427         NULL, 0,
7428         in, &inLen
7429       );
7430       if (ret != SANE_STATUS_GOOD)
7431         goto cleanup;
7432 
7433       for(i=0;i<2;i++){
7434         for(j=0; j<s->s.valid_width; j++){
7435 
7436           s->f_gain[i][j*3+k] = in[j*2+i]*3/4;
7437 
7438           if(s->f_gain[i][j*3+k] < 1)
7439             s->f_gain[i][j*3+k] = 1;
7440         }
7441       }
7442     }
7443   }
7444 
7445   /*gray gain, copy*/
7446   else{
7447 
7448     set_R_xfer_uid (cmd, R_FINE_uid_gray);
7449     inLen = reqLen;
7450 
7451     ret = do_cmd (
7452       s, 1, 0,
7453       cmd, cmdLen,
7454       NULL, 0,
7455       in, &inLen
7456     );
7457     if (ret != SANE_STATUS_GOOD)
7458       goto cleanup;
7459 
7460     for(i=0;i<2;i++){
7461       for(j=0; j<s->s.valid_width; j++){
7462 
7463         s->f_gain[i][j] = in[j*2+i]*3/4;
7464 
7465         if(s->f_gain[i][j] < 1)
7466           s->f_gain[i][j] = 1;
7467       }
7468     }
7469   }
7470 
7471   cleanup:
7472 
7473   if(in){
7474     free(in);
7475   }
7476 
7477   /* recover user settings */
7478   s->u.tl_y = old_tl_y;
7479   s->u.br_y = old_br_y;
7480   s->u.source = old_source;
7481 
7482   DBG (10, "calibrate_fine_src_hw: finish %d\n",ret);
7483 
7484   return ret;
7485 }
7486 
7487 /*
7488  * makes several scans, generates fine calibration data
7489  */
7490 static SANE_Status
calibrate_fine_src_scan(struct scanner * s)7491 calibrate_fine_src_scan (struct scanner *s)
7492 {
7493   SANE_Status ret = SANE_STATUS_GOOD;
7494   int i, j, k;
7495   int min, max;
7496   int lines = 8;
7497 
7498   /*buffer these for later*/
7499   int old_tl_y = s->u.tl_y;
7500   int old_br_y = s->u.br_y;
7501   int old_source = s->u.source;
7502 
7503   DBG (10, "calibrate_fine_src_scan: start\n");
7504 
7505   /* always cal with a short scan in duplex */
7506   s->u.tl_y = 0;
7507   s->u.br_y = lines * 1200 / s->u.dpi_y;
7508   s->u.source = SOURCE_ADF_DUPLEX;
7509 
7510   /* load our own private copy of scan params */
7511   ret = update_params(s,1);
7512   if (ret != SANE_STATUS_GOOD) {
7513     DBG (5, "calibrate_fine_src_scan: ERROR: cannot update_params\n");
7514     goto cleanup;
7515   }
7516 
7517   /* clean scan params for new scan */
7518   ret = clean_params(s);
7519   if (ret != SANE_STATUS_GOOD) {
7520     DBG (5, "calibration_fine: ERROR: cannot clean_params\n");
7521     goto cleanup;
7522   }
7523 
7524   /* make buffers to hold the images */
7525   ret = image_buffers(s,1);
7526   if (ret != SANE_STATUS_GOOD) {
7527     DBG (5, "calibrate_fine_src_scan: ERROR: cannot load buffers\n");
7528     goto cleanup;
7529   }
7530 
7531   /*blast the existing fine cal data so reading code won't apply it*/
7532   ret = offset_buffers(s,0);
7533   ret = gain_buffers(s,0);
7534 
7535   /* need to tell it we want duplex */
7536   ret = ssm_buffer(s);
7537   if (ret != SANE_STATUS_GOOD) {
7538     DBG (5, "calibrate_fine_src_scan: ERROR: cannot ssm buffer\n");
7539     goto cleanup;
7540   }
7541 
7542   /* set window command */
7543   ret = set_window(s);
7544   if (ret != SANE_STATUS_GOOD) {
7545     DBG (5, "calibrate_fine_src_scan: ERROR: cannot set window\n");
7546     goto cleanup;
7547   }
7548 
7549   /* first pass (fine offset), lamp off */
7550   DBG (15, "calibrate_fine_src_scan: offset\n");
7551   ret = calibration_scan(s,0xff);
7552   if (ret != SANE_STATUS_GOOD) {
7553     DBG (5, "calibrate_fine_src_scan: ERROR: cannot make offset cal scan\n");
7554     goto cleanup;
7555   }
7556 
7557   ret = offset_buffers(s,1);
7558   if (ret != SANE_STATUS_GOOD) {
7559     DBG (5, "calibrate_fine_src_scan: ERROR: cannot load offset buffers\n");
7560     goto cleanup;
7561   }
7562 
7563   for(i=0;i<2;i++){
7564     for(j=0; j<s->s.valid_Bpl; j++){
7565       min = 0;
7566       for(k=j;k<lines*s->s.Bpl;k+=s->s.Bpl){
7567         min += s->buffers[i][k];
7568       }
7569       s->f_offset[i][j] = min/lines;
7570     }
7571     hexdump(15, "off:", s->f_offset[i], s->s.valid_Bpl);
7572   }
7573 
7574   /* second pass (fine gain), lamp on */
7575   DBG (15, "calibrate_fine_src_scan: gain\n");
7576   ret = calibration_scan(s,0xfe);
7577   if (ret != SANE_STATUS_GOOD) {
7578     DBG (5, "calibrate_fine_src_scan: ERROR: cannot make gain cal scan\n");
7579     goto cleanup;
7580   }
7581 
7582   ret = gain_buffers(s,1);
7583   if (ret != SANE_STATUS_GOOD) {
7584     DBG (5, "calibrate_fine_src_scan: ERROR: cannot load gain buffers\n");
7585     goto cleanup;
7586   }
7587 
7588   for(i=0;i<2;i++){
7589     for(j=0; j<s->s.valid_Bpl; j++){
7590       max = 0;
7591       for(k=j;k<lines*s->s.Bpl;k+=s->s.Bpl){
7592         max += s->buffers[i][k];
7593       }
7594       s->f_gain[i][j] = max/lines;
7595 
7596       if(s->f_gain[i][j] < 1)
7597         s->f_gain[i][j] = 1;
7598     }
7599     hexdump(15, "gain:", s->f_gain[i], s->s.valid_Bpl);
7600   }
7601 
7602   cleanup:
7603 
7604   /* recover user settings */
7605   s->u.tl_y = old_tl_y;
7606   s->u.br_y = old_br_y;
7607   s->u.source = old_source;
7608 
7609   DBG (10, "calibrate_fine_src_scan: finish %d\n",ret);
7610 
7611   return ret;
7612 }
7613 
7614 /* write calibration data to scanner memory and delete from struct */
7615 static SANE_Status
calibrate_fine_dest_hw(struct scanner * s)7616 calibrate_fine_dest_hw (struct scanner *s)
7617 {
7618   SANE_Status ret = SANE_STATUS_GOOD;
7619   int i, j, k;
7620 
7621   unsigned char cmd[SEND_len];
7622   size_t cmdLen = SEND_len;
7623 
7624   unsigned char * out = NULL;
7625   size_t outLen = 0;
7626 
7627   DBG (10, "calibrate_fine_dest_hw: start\n");
7628 
7629   /* calibration buffers in scanner are single color channel, but 16 bit, plus 4 byte header */
7630   outLen = s->s.width*2 + 4;
7631 
7632   out = calloc(outLen,1);
7633   if (!out) {
7634     DBG (5, "calibrate_fine_dest_hw: ERROR: cannot calloc out\n");
7635     ret = SANE_STATUS_NO_MEM;
7636     goto cleanup;
7637   }
7638 
7639   // sides
7640   for(i=0;i<2;i++){
7641 
7642     // colors
7643     for(j=0;j<3;j++){
7644 
7645       int codes[] = {
7646         S_FCAL_id_f_red, S_FCAL_id_f_green, S_FCAL_id_f_blue,
7647         S_FCAL_id_b_red, S_FCAL_id_b_green, S_FCAL_id_b_blue};
7648 
7649       // offset
7650       memset(cmd,0,cmdLen);
7651       set_SCSI_opcode(cmd, SEND_code);
7652       set_S_xfer_datatype (cmd, SR_datatype_fineoffset);
7653       set_S_xfer_length (cmd, outLen);
7654 
7655       set_S_FCAL_datatype (out, codes[i*3+j]);
7656 
7657       for(k=0; k<s->s.valid_width; k++){
7658         out[4+k*2] = 0;
7659 
7660         // TODO: calculate this instead of hardcode
7661         out[4+k*2+1] = 140;
7662       }
7663 
7664       ret = do_cmd (
7665         s, 1, 0,
7666         cmd, cmdLen,
7667         out, outLen,
7668         NULL, 0
7669       );
7670       if (ret != SANE_STATUS_GOOD)
7671         goto cleanup;
7672 
7673       // gain
7674       set_S_FCAL_datatype (out, codes[i*3+j] | 0x40);
7675 
7676       for(k=0; k<s->s.valid_width; k++){
7677         out[4+k*2] = 0;
7678 
7679         // TODO: calculate this instead of hardcode
7680         out[4+k*2+1] = 40;
7681       }
7682 
7683       ret = do_cmd (
7684         s, 1, 0,
7685         cmd, cmdLen,
7686         out, outLen,
7687         NULL, 0
7688       );
7689       if (ret != SANE_STATUS_GOOD)
7690         goto cleanup;
7691 
7692     }
7693   }
7694 
7695   cleanup:
7696 
7697   /*blast the fine cal data we generated above, so reading code wont apply it*/
7698   offset_buffers(s,0);
7699   gain_buffers(s,0);
7700 
7701   if(out){
7702     free(out);
7703   }
7704 
7705   DBG (10, "calibrate_fine_dest_hw: finish %d\n",ret);
7706 
7707   return ret;
7708 }
7709 
7710 /*
7711  * does a simple scan, ingests entire duplex image into buffers
7712  */
7713 static SANE_Status
calibration_scan(struct scanner * s,int scan)7714 calibration_scan (struct scanner *s, int scan)
7715 {
7716   SANE_Status ret = SANE_STATUS_GOOD;
7717 
7718   DBG (10, "calibration_scan: start\n");
7719 
7720   /* clean scan params for new scan */
7721   ret = clean_params(s);
7722   if (ret != SANE_STATUS_GOOD) {
7723     DBG (5, "calibration_scan: ERROR: cannot clean_params\n");
7724     return ret;
7725   }
7726 
7727   /* start scanning */
7728   ret = start_scan (s,scan);
7729   if (ret != SANE_STATUS_GOOD) {
7730     DBG (5, "calibration_scan: ERROR: cannot start_scan\n");
7731     return ret;
7732   }
7733 
7734   while(!s->s.eof[SIDE_FRONT] && !s->s.eof[SIDE_BACK]){
7735     ret = read_from_scanner_duplex(s,1);
7736   }
7737 
7738   DBG (10, "calibration_scan: finished\n");
7739 
7740   return ret;
7741 }
7742 
7743 /*
7744  * sends AFE and exposure params
7745  */
7746 static SANE_Status
write_AFE(struct scanner * s)7747 write_AFE(struct scanner *s)
7748 {
7749   SANE_Status ret = SANE_STATUS_GOOD;
7750 
7751   unsigned char cmd[COR_CAL_len];
7752   size_t cmdLen = COR_CAL_len;
7753 
7754   /*use the longest payload for buffer*/
7755   unsigned char pay[CC3_pay_len];
7756   size_t payLen = CC3_pay_len;
7757 
7758   DBG (10, "write_AFE: start\n");
7759 
7760   /* newer scanners use a longer cc payload */
7761   if(s->ccal_version == 3){
7762 
7763     memset(cmd,0,cmdLen);
7764     set_SCSI_opcode(cmd, COR_CAL_code);
7765     set_CC_version(cmd,CC3_pay_ver);
7766     set_CC_xferlen(cmd,payLen);
7767 
7768     memset(pay,0,payLen);
7769 
7770     set_CC3_gain_f_r(pay,s->c_gain[SIDE_FRONT]);
7771     set_CC3_gain_f_g(pay,s->c_gain[SIDE_FRONT]);
7772     set_CC3_gain_f_b(pay,s->c_gain[SIDE_FRONT]);
7773 
7774     set_CC3_off_f_r(pay,s->c_offset[SIDE_FRONT]);
7775     set_CC3_off_f_g(pay,s->c_offset[SIDE_FRONT]);
7776     set_CC3_off_f_b(pay,s->c_offset[SIDE_FRONT]);
7777 
7778     set_CC3_exp_f_r(pay,s->c_exposure[SIDE_FRONT][CHAN_RED]);
7779     set_CC3_exp_f_g(pay,s->c_exposure[SIDE_FRONT][CHAN_GREEN]);
7780     set_CC3_exp_f_b(pay,s->c_exposure[SIDE_FRONT][CHAN_BLUE]);
7781 
7782     set_CC3_gain_b_r(pay,s->c_gain[SIDE_BACK]);
7783     set_CC3_gain_b_g(pay,s->c_gain[SIDE_BACK]);
7784     set_CC3_gain_b_b(pay,s->c_gain[SIDE_BACK]);
7785 
7786     set_CC3_off_b_r(pay,s->c_offset[SIDE_BACK]);
7787     set_CC3_off_b_g(pay,s->c_offset[SIDE_BACK]);
7788     set_CC3_off_b_b(pay,s->c_offset[SIDE_BACK]);
7789 
7790     set_CC3_exp_b_r(pay,s->c_exposure[SIDE_BACK][CHAN_RED]);
7791     set_CC3_exp_b_g(pay,s->c_exposure[SIDE_BACK][CHAN_GREEN]);
7792     set_CC3_exp_b_b(pay,s->c_exposure[SIDE_BACK][CHAN_BLUE]);
7793   }
7794 
7795   else{
7796     payLen = CC_pay_len;
7797 
7798     memset(cmd,0,cmdLen);
7799     set_SCSI_opcode(cmd, COR_CAL_code);
7800     set_CC_version(cmd,CC_pay_ver);
7801     set_CC_xferlen(cmd,payLen);
7802 
7803     memset(pay,0,payLen);
7804     set_CC_f_gain(pay,s->c_gain[SIDE_FRONT]);
7805     set_CC_unk1(pay,1);
7806     set_CC_f_offset(pay,s->c_offset[SIDE_FRONT]);
7807     set_CC_unk2(pay,1);
7808     set_CC_exp_f_r1(pay,s->c_exposure[SIDE_FRONT][CHAN_RED]);
7809     set_CC_exp_f_g1(pay,s->c_exposure[SIDE_FRONT][CHAN_GREEN]);
7810     set_CC_exp_f_b1(pay,s->c_exposure[SIDE_FRONT][CHAN_BLUE]);
7811     set_CC_exp_f_r2(pay,s->c_exposure[SIDE_FRONT][CHAN_RED]);
7812     set_CC_exp_f_g2(pay,s->c_exposure[SIDE_FRONT][CHAN_GREEN]);
7813     set_CC_exp_f_b2(pay,s->c_exposure[SIDE_FRONT][CHAN_BLUE]);
7814 
7815     set_CC_b_gain(pay,s->c_gain[SIDE_BACK]);
7816     set_CC_b_offset(pay,s->c_offset[SIDE_BACK]);
7817     set_CC_exp_b_r1(pay,s->c_exposure[SIDE_BACK][CHAN_RED]);
7818     set_CC_exp_b_g1(pay,s->c_exposure[SIDE_BACK][CHAN_GREEN]);
7819     set_CC_exp_b_b1(pay,s->c_exposure[SIDE_BACK][CHAN_BLUE]);
7820     set_CC_exp_b_r2(pay,s->c_exposure[SIDE_BACK][CHAN_RED]);
7821     set_CC_exp_b_g2(pay,s->c_exposure[SIDE_BACK][CHAN_GREEN]);
7822     set_CC_exp_b_b2(pay,s->c_exposure[SIDE_BACK][CHAN_BLUE]);
7823   }
7824 
7825   ret = do_cmd (
7826     s, 1, 0,
7827     cmd, cmdLen,
7828     pay, payLen,
7829     NULL, NULL
7830   );
7831   if (ret != SANE_STATUS_GOOD)
7832     return ret;
7833 
7834   DBG (10, "write_AFE: finish\n");
7835 
7836   return ret;
7837 }
7838 
7839 /*
7840  * frees/callocs buffers to hold the fine cal offset data
7841  */
7842 static SANE_Status
offset_buffers(struct scanner * s,int setup)7843 offset_buffers (struct scanner *s, int setup)
7844 {
7845   SANE_Status ret = SANE_STATUS_GOOD;
7846   int side;
7847 
7848   DBG (10, "offset_buffers: start\n");
7849 
7850   for(side=0;side<2;side++){
7851 
7852     if (s->f_offset[side]) {
7853       DBG (15, "offset_buffers: free f_offset %d.\n",side);
7854       free(s->f_offset[side]);
7855       s->f_offset[side] = NULL;
7856     }
7857 
7858     if(setup){
7859       s->f_offset[side] = calloc (1,s->s.Bpl);
7860       if (!s->f_offset[side]) {
7861         DBG (5, "offset_buffers: error, no f_offset %d.\n",side);
7862         return SANE_STATUS_NO_MEM;
7863       }
7864     }
7865   }
7866 
7867   DBG (10, "offset_buffers: finish\n");
7868 
7869   return ret;
7870 }
7871 
7872 /*
7873  * frees/callocs buffers to hold the fine cal gain data
7874  */
7875 static SANE_Status
gain_buffers(struct scanner * s,int setup)7876 gain_buffers (struct scanner *s, int setup)
7877 {
7878   SANE_Status ret = SANE_STATUS_GOOD;
7879   int side;
7880 
7881   DBG (10, "gain_buffers: start\n");
7882 
7883   for(side=0;side<2;side++){
7884 
7885     if (s->f_gain[side]) {
7886       DBG (15, "gain_buffers: free f_gain %d.\n",side);
7887       free(s->f_gain[side]);
7888       s->f_gain[side] = NULL;
7889     }
7890 
7891     if(setup){
7892       s->f_gain[side] = calloc (1,s->s.Bpl);
7893       if (!s->f_gain[side]) {
7894         DBG (5, "gain_buffers: error, no f_gain %d.\n",side);
7895         return SANE_STATUS_NO_MEM;
7896       }
7897     }
7898   }
7899 
7900   DBG (10, "gain_buffers: finish\n");
7901 
7902   return ret;
7903 }
7904 
7905 /*
7906  * @@ Section 6 - SANE cleanup functions
7907  */
7908 /*
7909  * Cancels a scan.
7910  *
7911  * It has been said on the mailing list that sane_cancel is a bit of a
7912  * misnomer because it is routinely called to signal the end of a
7913  * batch - quoting David Mosberger-Tang:
7914  *
7915  * > In other words, the idea is to have sane_start() be called, and
7916  * > collect as many images as the frontend wants (which could in turn
7917  * > consist of multiple frames each as indicated by frame-type) and
7918  * > when the frontend is done, it should call sane_cancel().
7919  * > Sometimes it's better to think of sane_cancel() as "sane_stop()"
7920  * > but that name would have had some misleading connotations as
7921  * > well, that's why we stuck with "cancel".
7922  *
7923  * The current consensus regarding duplex and ADF scans seems to be
7924  * the following call sequence: sane_start; sane_read (repeat until
7925  * EOF); sane_start; sane_read...  and then call sane_cancel if the
7926  * batch is at an end. I.e. do not call sane_cancel during the run but
7927  * as soon as you get a SANE_STATUS_NO_DOCS.
7928  *
7929  * From the SANE spec:
7930  * This function is used to immediately or as quickly as possible
7931  * cancel the currently pending operation of the device represented by
7932  * handle h.  This function can be called at any time (as long as
7933  * handle h is a valid handle) but usually affects long-running
7934  * operations only (such as image acquisition). It is safe to call
7935  * this function asynchronously (e.g., from within a signal handler).
7936  * It is important to note that completion of this operation does not
7937  * imply that the currently pending operation has been cancelled. It
7938  * only guarantees that cancellation has been initiated. Cancellation
7939  * completes only when the cancelled call returns (typically with a
7940  * status value of SANE_STATUS_CANCELLED).  Since the SANE API does
7941  * not require any other operations to be re-entrant, this implies
7942  * that a frontend must not call any other operation until the
7943  * cancelled operation has returned.
7944  */
7945 void
sane_cancel(SANE_Handle handle)7946 sane_cancel (SANE_Handle handle)
7947 {
7948   struct scanner * s = (struct scanner *) handle;
7949 
7950   DBG (10, "sane_cancel: start\n");
7951   s->cancelled = 1;
7952 
7953   /* if there is no other running function to check, we do it */
7954   if(!s->reading)
7955     check_for_cancel(s);
7956 
7957   DBG (10, "sane_cancel: finish\n");
7958 }
7959 
7960 /* checks started and cancelled flags in scanner struct,
7961  * sends cancel command to scanner if required. don't call
7962  * this function asynchronously, wait for pending operation */
7963 static SANE_Status
check_for_cancel(struct scanner * s)7964 check_for_cancel(struct scanner *s)
7965 {
7966   SANE_Status ret=SANE_STATUS_GOOD;
7967 
7968   DBG (10, "check_for_cancel: start\n");
7969 
7970   if(s->started && s->cancelled){
7971     unsigned char cmd[CANCEL_len];
7972     size_t cmdLen = CANCEL_len;
7973 
7974     DBG (15, "check_for_cancel: cancelling\n");
7975 
7976     /* cancel scan */
7977     memset(cmd,0,cmdLen);
7978     set_SCSI_opcode(cmd, CANCEL_code);
7979 
7980     ret = do_cmd (
7981         s, 1, 0,
7982         cmd, cmdLen,
7983         NULL, 0,
7984         NULL, NULL
7985     );
7986     if(ret){
7987       DBG (5, "check_for_cancel: ignoring bad cancel: %d\n",ret);
7988     }
7989 
7990     ret = object_position(s,SANE_FALSE);
7991     if(ret){
7992       DBG (5, "check_for_cancel: ignoring bad eject: %d\n",ret);
7993     }
7994 
7995     s->started = 0;
7996     s->cancelled = 0;
7997     ret = SANE_STATUS_CANCELLED;
7998   }
7999   else if(s->cancelled){
8000     DBG (15, "check_for_cancel: already cancelled\n");
8001     s->cancelled = 0;
8002     ret = SANE_STATUS_CANCELLED;
8003   }
8004 
8005   DBG (10, "check_for_cancel: finish %d\n",ret);
8006   return ret;
8007 }
8008 
8009 /*
8010  * Ends use of the scanner.
8011  *
8012  * From the SANE spec:
8013  * This function terminates the association between the device handle
8014  * passed in argument h and the device it represents. If the device is
8015  * presently active, a call to sane_cancel() is performed first. After
8016  * this function returns, handle h must not be used anymore.
8017  */
8018 void
sane_close(SANE_Handle handle)8019 sane_close (SANE_Handle handle)
8020 {
8021   struct scanner * s = (struct scanner *) handle;
8022 
8023   DBG (10, "sane_close: start\n");
8024   disconnect_fd(s);
8025   image_buffers(s,0);
8026   offset_buffers(s,0);
8027   gain_buffers(s,0);
8028   DBG (10, "sane_close: finish\n");
8029 }
8030 
8031 static SANE_Status
disconnect_fd(struct scanner * s)8032 disconnect_fd (struct scanner *s)
8033 {
8034   DBG (10, "disconnect_fd: start\n");
8035 
8036   if(s->fd > -1){
8037     if (s->connection == CONNECTION_USB) {
8038       DBG (15, "disconnecting usb device\n");
8039       sanei_usb_close (s->fd);
8040     }
8041     else if (s->connection == CONNECTION_SCSI) {
8042       DBG (15, "disconnecting scsi device\n");
8043       sanei_scsi_close (s->fd);
8044     }
8045     s->fd = -1;
8046   }
8047 
8048   DBG (10, "disconnect_fd: finish\n");
8049 
8050   return SANE_STATUS_GOOD;
8051 }
8052 
8053 /*
8054  * Terminates the backend.
8055  *
8056  * From the SANE spec:
8057  * This function must be called to terminate use of a backend. The
8058  * function will first close all device handles that still might be
8059  * open (it is recommended to close device handles explicitly through
8060  * a call to sane_close(), but backends are required to release all
8061  * resources upon a call to this function). After this function
8062  * returns, no function other than sane_init() may be called
8063  * (regardless of the status value returned by sane_exit(). Neglecting
8064  * to call this function may result in some resources not being
8065  * released properly.
8066  */
8067 void
sane_exit(void)8068 sane_exit (void)
8069 {
8070   struct scanner *dev, *next;
8071 
8072   DBG (10, "sane_exit: start\n");
8073 
8074   for (dev = scanner_devList; dev; dev = next) {
8075       disconnect_fd(dev);
8076       next = dev->next;
8077       free (dev);
8078   }
8079 
8080   if (sane_devArray)
8081     free (sane_devArray);
8082 
8083   scanner_devList = NULL;
8084   sane_devArray = NULL;
8085 
8086   DBG (10, "sane_exit: finish\n");
8087 }
8088 
8089 
8090 /*
8091  * @@ Section 7 - misc helper functions
8092  */
8093 static void
default_globals(void)8094 default_globals(void)
8095 {
8096   global_buffer_size = global_buffer_size_default;
8097   global_padded_read = global_padded_read_default;
8098   global_extra_status = global_extra_status_default;
8099   global_duplex_offset = global_duplex_offset_default;
8100   global_inquiry_length = INQUIRY_std_typ_len;
8101   global_vpd_length = INQUIRY_vpd_typ_len;
8102   global_tur_timeout = global_tur_timeout_default;
8103   global_vendor_name[0] = 0;
8104   global_model_name[0] = 0;
8105   global_version_name[0] = 0;
8106 }
8107 
8108 /*
8109  * Called by the SANE SCSI core and our usb code on device errors
8110  * parses the request sense return data buffer,
8111  * decides the best SANE_Status for the problem, produces debug msgs,
8112  * and copies the sense buffer into the scanner struct
8113  */
8114 static SANE_Status
sense_handler(int fd,unsigned char * sensed_data,void * arg)8115 sense_handler (int fd, unsigned char * sensed_data, void *arg)
8116 {
8117   struct scanner *s = arg;
8118   unsigned int sense = get_RS_sense_key (sensed_data);
8119   unsigned int asc = get_RS_ASC (sensed_data);
8120   unsigned int ascq = get_RS_ASCQ (sensed_data);
8121   unsigned int eom = get_RS_EOM (sensed_data);
8122   unsigned int ili = get_RS_ILI (sensed_data);
8123   unsigned int info = get_RS_information (sensed_data);
8124 
8125   DBG (5, "sense_handler: start\n");
8126 
8127   /* kill compiler warning */
8128   (void) fd;
8129 
8130   /* copy the rs return data into the scanner struct
8131      so that the caller can use it if he wants
8132   memcpy(&s->rs_buffer,sensed_data,RS_return_size);
8133   */
8134 
8135   DBG (5, "Sense=%#02x, ASC=%#02x, ASCQ=%#02x, EOM=%d, ILI=%d, info=%#08x\n", sense, asc, ascq, eom, ili, info);
8136 
8137   switch (sense) {
8138     case 0:
8139       if (ili == 1) {
8140         s->rs_info = info;
8141         DBG  (5, "No sense: EOM remainder:%d\n",info);
8142         return SANE_STATUS_EOF;
8143       }
8144       DBG  (5, "No sense: unknown asc/ascq\n");
8145       return SANE_STATUS_GOOD;
8146 
8147     case 1:
8148       if (asc == 0x37 && ascq == 0x00) {
8149         DBG  (5, "Recovered error: parameter rounded\n");
8150         return SANE_STATUS_GOOD;
8151       }
8152       DBG  (5, "Recovered error: unknown asc/ascq\n");
8153       return SANE_STATUS_GOOD;
8154 
8155     case 2:
8156       if (asc == 0x04 && ascq == 0x01) {
8157         DBG  (5, "Not ready: previous command unfinished\n");
8158         return SANE_STATUS_DEVICE_BUSY;
8159       }
8160       DBG  (5, "Not ready: unknown asc/ascq\n");
8161       return SANE_STATUS_DEVICE_BUSY;
8162 
8163     case 3:
8164       if (asc == 0x36 && ascq == 0x00) {
8165         DBG  (5, "Medium error: no cartridge\n");
8166         return SANE_STATUS_IO_ERROR;
8167       }
8168       if (asc == 0x3a && ascq == 0x00) {
8169         DBG  (5, "Medium error: hopper empty\n");
8170         return SANE_STATUS_NO_DOCS;
8171       }
8172       if (asc == 0x80 && ascq == 0x00) {
8173         DBG  (5, "Medium error: paper jam\n");
8174         return SANE_STATUS_JAMMED;
8175       }
8176       if (asc == 0x80 && ascq == 0x01) {
8177         DBG  (5, "Medium error: cover open\n");
8178         return SANE_STATUS_COVER_OPEN;
8179       }
8180       if (asc == 0x81 && ascq == 0x01) {
8181         DBG  (5, "Medium error: double feed\n");
8182         return SANE_STATUS_JAMMED;
8183       }
8184       if (asc == 0x81 && ascq == 0x02) {
8185         DBG  (5, "Medium error: skew detected\n");
8186         return SANE_STATUS_JAMMED;
8187       }
8188       if (asc == 0x81 && ascq == 0x04) {
8189         DBG  (5, "Medium error: staple detected\n");
8190         return SANE_STATUS_JAMMED;
8191       }
8192       DBG  (5, "Medium error: unknown asc/ascq\n");
8193       return SANE_STATUS_IO_ERROR;
8194 
8195     case 4:
8196       if (asc == 0x60 && ascq == 0x00) {
8197         DBG  (5, "Hardware error: lamp error\n");
8198         return SANE_STATUS_IO_ERROR;
8199       }
8200       if (asc == 0x80 && ascq == 0x01) {
8201         DBG  (5, "Hardware error: CPU check error\n");
8202         return SANE_STATUS_IO_ERROR;
8203       }
8204       if (asc == 0x80 && ascq == 0x02) {
8205         DBG  (5, "Hardware error: RAM check error\n");
8206         return SANE_STATUS_IO_ERROR;
8207       }
8208       if (asc == 0x80 && ascq == 0x03) {
8209         DBG  (5, "Hardware error: ROM check error\n");
8210         return SANE_STATUS_IO_ERROR;
8211       }
8212       if (asc == 0x80 && ascq == 0x04) {
8213         DBG  (5, "Hardware error: hardware check error\n");
8214         return SANE_STATUS_IO_ERROR;
8215       }
8216       DBG  (5, "Hardware error: unknown asc/ascq\n");
8217       return SANE_STATUS_IO_ERROR;
8218 
8219     case 5:
8220       if (asc == 0x1a && ascq == 0x00) {
8221         DBG  (5, "Illegal request: Parameter list error\n");
8222         return SANE_STATUS_INVAL;
8223       }
8224       if (asc == 0x20 && ascq == 0x00) {
8225         DBG  (5, "Illegal request: invalid command\n");
8226         return SANE_STATUS_INVAL;
8227       }
8228       if (asc == 0x24 && ascq == 0x00) {
8229         DBG  (5, "Illegal request: invalid CDB field\n");
8230         return SANE_STATUS_INVAL;
8231       }
8232       if (asc == 0x25 && ascq == 0x00) {
8233         DBG  (5, "Illegal request: unsupported logical unit\n");
8234         return SANE_STATUS_UNSUPPORTED;
8235       }
8236       if (asc == 0x26 && ascq == 0x00) {
8237         DBG  (5, "Illegal request: invalid field in parm list\n");
8238         return SANE_STATUS_INVAL;
8239       }
8240       if (asc == 0x2c && ascq == 0x00) {
8241         DBG  (5, "Illegal request: command sequence error\n");
8242         return SANE_STATUS_INVAL;
8243       }
8244       if (asc == 0x2c && ascq == 0x01) {
8245         DBG  (5, "Illegal request: too many windows\n");
8246         return SANE_STATUS_INVAL;
8247       }
8248       if (asc == 0x3a && ascq == 0x00) {
8249         DBG  (5, "Illegal request: no paper\n");
8250         return SANE_STATUS_NO_DOCS;
8251       }
8252       if (asc == 0x3d && ascq == 0x00) {
8253         DBG  (5, "Illegal request: invalid IDENTIFY\n");
8254         return SANE_STATUS_INVAL;
8255       }
8256       if (asc == 0x55 && ascq == 0x00) {
8257         DBG  (5, "Illegal request: scanner out of memory\n");
8258         return SANE_STATUS_NO_MEM;
8259       }
8260       DBG  (5, "Illegal request: unknown asc/ascq\n");
8261       return SANE_STATUS_IO_ERROR;
8262       break;
8263 
8264     case 6:
8265       if (asc == 0x29 && ascq == 0x00) {
8266         DBG  (5, "Unit attention: device reset\n");
8267         return SANE_STATUS_GOOD;
8268       }
8269       if (asc == 0x2a && ascq == 0x00) {
8270         DBG  (5, "Unit attention: param changed by 2nd initiator\n");
8271         return SANE_STATUS_GOOD;
8272       }
8273       DBG  (5, "Unit attention: unknown asc/ascq\n");
8274       return SANE_STATUS_IO_ERROR;
8275       break;
8276 
8277     case 7:
8278       DBG  (5, "Data protect: unknown asc/ascq\n");
8279       return SANE_STATUS_IO_ERROR;
8280 
8281     case 8:
8282       DBG  (5, "Blank check: unknown asc/ascq\n");
8283       return SANE_STATUS_IO_ERROR;
8284 
8285     case 9:
8286       DBG  (5, "Vendor defined: unknown asc/ascq\n");
8287       return SANE_STATUS_IO_ERROR;
8288 
8289     case 0xa:
8290       DBG  (5, "Copy aborted: unknown asc/ascq\n");
8291       return SANE_STATUS_IO_ERROR;
8292 
8293     case 0xb:
8294       if (asc == 0x00 && ascq == 0x00) {
8295         DBG  (5, "Aborted command: no sense/cancelled\n");
8296         return SANE_STATUS_CANCELLED;
8297       }
8298       if (asc == 0x45 && ascq == 0x00) {
8299         DBG  (5, "Aborted command: reselect failure\n");
8300         return SANE_STATUS_IO_ERROR;
8301       }
8302       if (asc == 0x47 && ascq == 0x00) {
8303         DBG  (5, "Aborted command: SCSI parity error\n");
8304         return SANE_STATUS_IO_ERROR;
8305       }
8306       if (asc == 0x48 && ascq == 0x00) {
8307         DBG  (5, "Aborted command: initiator error message\n");
8308         return SANE_STATUS_IO_ERROR;
8309       }
8310       if (asc == 0x49 && ascq == 0x00) {
8311         DBG  (5, "Aborted command: invalid message\n");
8312         return SANE_STATUS_IO_ERROR;
8313       }
8314       if (asc == 0x80 && ascq == 0x00) {
8315         DBG  (5, "Aborted command: timeout\n");
8316         return SANE_STATUS_IO_ERROR;
8317       }
8318       DBG  (5, "Aborted command: unknown asc/ascq\n");
8319       return SANE_STATUS_IO_ERROR;
8320       break;
8321 
8322     case 0xc:
8323       DBG  (5, "Equal: unknown asc/ascq\n");
8324       return SANE_STATUS_IO_ERROR;
8325 
8326     case 0xd:
8327       DBG  (5, "Volume overflow: unknown asc/ascq\n");
8328       return SANE_STATUS_IO_ERROR;
8329 
8330     case 0xe:
8331       if (asc == 0x3b && ascq == 0x0d) {
8332         DBG  (5, "Miscompare: too many docs\n");
8333         return SANE_STATUS_IO_ERROR;
8334       }
8335       if (asc == 0x3b && ascq == 0x0e) {
8336         DBG  (5, "Miscompare: too few docs\n");
8337         return SANE_STATUS_IO_ERROR;
8338       }
8339       DBG  (5, "Miscompare: unknown asc/ascq\n");
8340       return SANE_STATUS_IO_ERROR;
8341 
8342     default:
8343       DBG (5, "Unknown Sense Code\n");
8344       return SANE_STATUS_IO_ERROR;
8345   }
8346 
8347   DBG (5, "sense_handler: should never happen!\n");
8348 
8349   return SANE_STATUS_IO_ERROR;
8350 }
8351 
8352 /*
8353  * take a bunch of pointers, send commands to scanner
8354  */
8355 static SANE_Status
do_cmd(struct scanner * s,int runRS,int timeout,unsigned char * cmdBuff,size_t cmdLen,unsigned char * outBuff,size_t outLen,unsigned char * inBuff,size_t * inLen)8356 do_cmd(struct scanner *s, int runRS, int timeout,
8357  unsigned char * cmdBuff, size_t cmdLen,
8358  unsigned char * outBuff, size_t outLen,
8359  unsigned char * inBuff, size_t * inLen
8360 )
8361 {
8362     if (s->connection == CONNECTION_SCSI) {
8363         return do_scsi_cmd(s, runRS, timeout,
8364                  cmdBuff, cmdLen,
8365                  outBuff, outLen,
8366                  inBuff, inLen
8367         );
8368     }
8369     if (s->connection == CONNECTION_USB) {
8370         return do_usb_cmd(s, runRS, timeout,
8371                  cmdBuff, cmdLen,
8372                  outBuff, outLen,
8373                  inBuff, inLen
8374         );
8375     }
8376     return SANE_STATUS_INVAL;
8377 }
8378 
8379 static SANE_Status
do_scsi_cmd(struct scanner * s,int runRS,int timeout,unsigned char * cmdBuff,size_t cmdLen,unsigned char * outBuff,size_t outLen,unsigned char * inBuff,size_t * inLen)8380 do_scsi_cmd(struct scanner *s, int runRS, int timeout,
8381  unsigned char * cmdBuff, size_t cmdLen,
8382  unsigned char * outBuff, size_t outLen,
8383  unsigned char * inBuff, size_t * inLen
8384 )
8385 {
8386   int ret;
8387 
8388   /*shut up compiler*/
8389   (void) runRS;
8390   (void) timeout;
8391 
8392   DBG(10, "do_scsi_cmd: start\n");
8393 
8394   DBG(25, "cmd: writing %d bytes\n", (int)cmdLen);
8395   hexdump(30, "cmd: >>", cmdBuff, cmdLen);
8396 
8397   if(outBuff && outLen){
8398     DBG(25, "out: writing %d bytes\n", (int)outLen);
8399     hexdump(30, "out: >>", outBuff, outLen);
8400   }
8401   if (inBuff && inLen){
8402     DBG(25, "in: reading %d bytes\n", (int)*inLen);
8403     memset(inBuff,0,*inLen);
8404   }
8405 
8406   ret = sanei_scsi_cmd2(s->fd, cmdBuff, cmdLen, outBuff, outLen, inBuff, inLen);
8407 
8408   if(ret != SANE_STATUS_GOOD && ret != SANE_STATUS_EOF){
8409     DBG(5,"do_scsi_cmd: return '%s'\n",sane_strstatus(ret));
8410     return ret;
8411   }
8412 
8413   if (inBuff && inLen){
8414     if(ret == SANE_STATUS_EOF){
8415       DBG(25, "in: short read, remainder %lu bytes\n", (u_long)s->rs_info);
8416       *inLen -= s->rs_info;
8417     }
8418     hexdump(31, "in: <<", inBuff, *inLen);
8419     DBG(25, "in: read %d bytes\n", (int)*inLen);
8420   }
8421 
8422   DBG(10, "do_scsi_cmd: finish\n");
8423 
8424   return ret;
8425 }
8426 
8427 static SANE_Status
do_usb_cmd(struct scanner * s,int runRS,int timeout,unsigned char * cmdBuff,size_t cmdLen,unsigned char * outBuff,size_t outLen,unsigned char * inBuff,size_t * inLen)8428 do_usb_cmd(struct scanner *s, int runRS, int timeout,
8429  unsigned char * cmdBuff, size_t cmdLen,
8430  unsigned char * outBuff, size_t outLen,
8431  unsigned char * inBuff, size_t * inLen
8432 )
8433 {
8434     size_t cmdOffset = 0;
8435     size_t cmdLength = 0;
8436     size_t cmdActual = 0;
8437     unsigned char * cmdBuffer = NULL;
8438 
8439     size_t outOffset = 0;
8440     size_t outLength = 0;
8441     size_t outActual = 0;
8442     unsigned char * outBuffer = NULL;
8443 
8444     size_t inOffset = 0;
8445     size_t inLength = 0;
8446     size_t inActual = 0;
8447     unsigned char * inBuffer = NULL;
8448 
8449     size_t extraLength = 0;
8450     int actTimeout = timeout ? timeout : USB_PACKET_TIMEOUT;
8451 
8452     int ret = 0;
8453     int ret2 = 0;
8454 
8455     struct timeval timer;
8456     gettimeofday(&timer,NULL);
8457 
8458     DBG (10, "do_usb_cmd: start %lu %lu\n", (long unsigned int)timer.tv_sec, (long unsigned int)timer.tv_usec);
8459 
8460     /* change timeout */
8461     sanei_usb_set_timeout(actTimeout);
8462 
8463     /****************************************************************/
8464     /* the command stage */
8465     {
8466       cmdOffset = USB_HEADER_LEN;
8467       cmdLength = cmdOffset+USB_COMMAND_LEN;
8468       cmdActual = cmdLength;
8469 
8470       /* build buffer */
8471       cmdBuffer = calloc(cmdLength,1);
8472       if(!cmdBuffer){
8473         DBG(5,"cmd: no mem\n");
8474         return SANE_STATUS_NO_MEM;
8475       }
8476 
8477       /* build a USB packet around the SCSI command */
8478       set_USB_CMD_xfer_length(cmdBuffer,cmdLength-4);
8479       cmdBuffer[5] = 1;
8480       cmdBuffer[6] = 0x90;
8481       memcpy(cmdBuffer+cmdOffset,cmdBuff,cmdLen);
8482 
8483       /* write the command out */
8484       DBG(25, "cmd: writing %d bytes, timeout %d\n", (int)cmdLength, actTimeout);
8485       hexdump(30, "cmd: >>", cmdBuffer, cmdLength);
8486       ret = sanei_usb_write_bulk(s->fd, cmdBuffer, &cmdActual);
8487       DBG(25, "cmd: wrote %d bytes, retVal %d\n", (int)cmdActual, ret);
8488 
8489       if(cmdLength != cmdActual){
8490         DBG(5,"cmd: wrong size %d/%d\n", (int)cmdLength, (int)cmdActual);
8491         free(cmdBuffer);
8492         return SANE_STATUS_IO_ERROR;
8493       }
8494       if(ret != SANE_STATUS_GOOD){
8495         DBG(5,"cmd: write error '%s'\n",sane_strstatus(ret));
8496         free(cmdBuffer);
8497         return ret;
8498       }
8499       free(cmdBuffer);
8500     }
8501 
8502     /****************************************************************/
8503     /* the extra status stage, used by few scanners                 */
8504     /* this is like the regular status block, with an additional    */
8505     /* length component at the end */
8506     if(s->extra_status){
8507       ret2 = do_usb_status(s,runRS,timeout,&extraLength);
8508 
8509       /* bail out on bad RS status */
8510       if(ret2){
8511         DBG(5,"extra: bad RS status, %d\n", ret2);
8512         return ret2;
8513       }
8514     }
8515 
8516     /****************************************************************/
8517     /* the output stage */
8518     if(outBuff && outLen){
8519 
8520       outOffset = USB_HEADER_LEN;
8521       outLength = outOffset+outLen;
8522       outActual = outLength;
8523 
8524       /* build outBuffer */
8525       outBuffer = calloc(outLength,1);
8526       if(!outBuffer){
8527         DBG(5,"out: no mem\n");
8528         return SANE_STATUS_NO_MEM;
8529       }
8530 
8531       /* build a USB packet around the SCSI command */
8532       set_USB_OUT_xfer_length(outBuffer,outLength-4);
8533       outBuffer[5] = 2;
8534       outBuffer[6] = 0xb0;
8535       memcpy(outBuffer+outOffset,outBuff,outLen);
8536 
8537       /* write the command out */
8538       DBG(25, "out: writing %d bytes, timeout %d\n", (int)outLength, actTimeout);
8539       hexdump(30, "out: >>", outBuffer, outLength);
8540       ret = sanei_usb_write_bulk(s->fd, outBuffer, &outActual);
8541       DBG(25, "out: wrote %d bytes, retVal %d\n", (int)outActual, ret);
8542 
8543       if(outLength != outActual){
8544         DBG(5,"out: wrong size %d/%d\n", (int)outLength, (int)outActual);
8545         free(outBuffer);
8546         return SANE_STATUS_IO_ERROR;
8547       }
8548       if(ret != SANE_STATUS_GOOD){
8549         DBG(5,"out: write error '%s'\n",sane_strstatus(ret));
8550         free(outBuffer);
8551         return ret;
8552       }
8553       free(outBuffer);
8554     }
8555 
8556     /****************************************************************/
8557     /* the input stage */
8558     if(inBuff && inLen){
8559 
8560       inOffset = 0;
8561       if(s->padded_read)
8562         inOffset = USB_HEADER_LEN;
8563 
8564       inLength = inOffset+*inLen;
8565       inActual = inLength;
8566 
8567       /* use the extra length to alter the amount of in we request */
8568       if(s->extra_status && extraLength && *inLen > extraLength){
8569         DBG(5,"in: adjust extra, %d %d\n", (int)*inLen, (int)extraLength);
8570         inActual = inOffset+extraLength;
8571       }
8572 
8573       /*blast caller's copy in case we error out*/
8574       *inLen = 0;
8575 
8576       /* build inBuffer */
8577       inBuffer = calloc(inActual,1);
8578       if(!inBuffer){
8579         DBG(5,"in: no mem\n");
8580         return SANE_STATUS_NO_MEM;
8581       }
8582 
8583       DBG(25, "in: reading %d bytes, timeout %d\n", (int)inActual, actTimeout);
8584       ret = sanei_usb_read_bulk(s->fd, inBuffer, &inActual);
8585       DBG(25, "in: read %d bytes, retval %d\n", (int)inActual, ret);
8586       hexdump(31, "in: <<", inBuffer, inActual);
8587 
8588       if(!inActual){
8589         DBG(5,"in: got no data, clearing\n");
8590         free(inBuffer);
8591 	return do_usb_clear(s,1,runRS);
8592       }
8593       if(inActual < inOffset){
8594         DBG(5,"in: read shorter than inOffset\n");
8595         free(inBuffer);
8596         return SANE_STATUS_IO_ERROR;
8597       }
8598       if(ret != SANE_STATUS_GOOD){
8599         DBG(5,"in: return error '%s'\n",sane_strstatus(ret));
8600         free(inBuffer);
8601         return ret;
8602       }
8603 
8604       /* note that inBuffer is not copied and freed here...*/
8605     }
8606 
8607     /****************************************************************/
8608     /* the normal status stage */
8609     ret2 = do_usb_status(s,runRS,timeout,&extraLength);
8610 
8611     /* if status said EOF, adjust input with remainder count */
8612     if(ret2 == SANE_STATUS_EOF && inBuffer){
8613 
8614       /* EOF is ok */
8615       ret2 = SANE_STATUS_GOOD;
8616 
8617       if(inActual < inLength - s->rs_info){
8618         DBG(5,"in: we read < RS, ignoring RS: %d < %d (%d-%d)\n",
8619           (int)inActual,(int)(inLength-s->rs_info),(int)inLength,(int)s->rs_info);
8620       }
8621       else if(inActual > inLength - s->rs_info){
8622         DBG(5,"in: we read > RS, using RS: %d to %d (%d-%d)\n",
8623           (int)inActual,(int)(inLength-s->rs_info),(int)inLength,(int)s->rs_info);
8624         inActual = inLength - s->rs_info;
8625       }
8626     }
8627 
8628     /* bail out on bad RS status */
8629     if(ret2){
8630       if(inBuffer) free(inBuffer);
8631       DBG(5,"stat: bad RS status, %d\n", ret2);
8632       return ret2;
8633     }
8634 
8635     /* now that we have read status, deal with input buffer */
8636     if(inBuffer){
8637       if(inLength != inActual){
8638         ret = SANE_STATUS_EOF;
8639         DBG(5,"in: short read, %d/%d\n", (int)inLength,(int)inActual);
8640       }
8641 
8642       /* ignore the USB packet around the SCSI command */
8643       *inLen = inActual - inOffset;
8644       memcpy(inBuff,inBuffer+inOffset,*inLen);
8645 
8646       free(inBuffer);
8647     }
8648 
8649     gettimeofday(&timer,NULL);
8650 
8651     DBG (10, "do_usb_cmd: finish %lu %lu\n", (long unsigned int)timer.tv_sec, (long unsigned int)timer.tv_usec);
8652 
8653     return ret;
8654 }
8655 
8656 static SANE_Status
do_usb_status(struct scanner * s,int runRS,int timeout,size_t * extraLength)8657 do_usb_status(struct scanner *s, int runRS, int timeout, size_t * extraLength)
8658 {
8659 
8660 #define EXTRA_READ_len 4
8661 
8662     size_t statPadding = 0;
8663     size_t statOffset = 0;
8664     size_t statLength = 0;
8665     size_t statActual = 0;
8666     unsigned char * statBuffer = NULL;
8667 
8668     int actTimeout = timeout ? timeout : USB_PACKET_TIMEOUT;
8669 
8670     int ret = 0;
8671 
8672     if(s->padded_read)
8673       statPadding = USB_HEADER_LEN;
8674 
8675     statLength = statPadding+USB_STATUS_LEN;
8676     statOffset = statLength-1;
8677 
8678     if(s->extra_status)
8679       statLength += EXTRA_READ_len;
8680 
8681     statActual = statLength;
8682 
8683     /* change timeout */
8684     sanei_usb_set_timeout(timeout ? timeout : USB_PACKET_TIMEOUT);
8685 
8686     /* build statBuffer */
8687     statBuffer = calloc(statLength,1);
8688     if(!statBuffer){
8689       DBG(5,"stat: no mem\n");
8690       return SANE_STATUS_NO_MEM;
8691     }
8692 
8693     DBG(25, "stat: reading %d bytes, timeout %d\n", (int)statLength, actTimeout);
8694     ret = sanei_usb_read_bulk(s->fd, statBuffer, &statActual);
8695     DBG(25, "stat: read %d bytes, retval %d\n", (int)statActual, ret);
8696     hexdump(30, "stat: <<", statBuffer, statActual);
8697 
8698     /*weird status*/
8699     if(ret != SANE_STATUS_GOOD){
8700       DBG(5,"stat: clearing error '%s'\n",sane_strstatus(ret));
8701       ret = do_usb_clear(s,1,runRS);
8702     }
8703     /*short read*/
8704     else if(statLength != statActual){
8705       DBG(5,"stat: clearing short %d/%d\n",(int)statLength,(int)statActual);
8706       ret = do_usb_clear(s,1,runRS);
8707     }
8708     /*inspect the status byte of the response*/
8709     else if(statBuffer[statOffset]){
8710       DBG(5,"stat: status %d\n",statBuffer[statOffset]);
8711       ret = do_usb_clear(s,0,runRS);
8712     }
8713 
8714     /*extract the extra length byte of the response*/
8715     if(s->extra_status){
8716       *extraLength = get_ES_length(statBuffer);
8717       DBG(15,"stat: extra %d\n",(int)*extraLength);
8718     }
8719 
8720     free(statBuffer);
8721 
8722     return ret;
8723 }
8724 
8725 static SANE_Status
do_usb_clear(struct scanner * s,int clear,int runRS)8726 do_usb_clear(struct scanner *s, int clear, int runRS)
8727 {
8728     SANE_Status ret, ret2;
8729 
8730     DBG (10, "do_usb_clear: start\n");
8731 
8732     usleep(100000);
8733 
8734     if(clear){
8735       DBG (15, "do_usb_clear: clear halt\n");
8736       ret = sanei_usb_clear_halt(s->fd);
8737       if(ret != SANE_STATUS_GOOD){
8738         DBG(5,"do_usb_clear: can't clear halt, returning %d\n", ret);
8739         return ret;
8740       }
8741     }
8742 
8743     /* caller is interested in having RS run on errors */
8744     if(runRS){
8745 
8746         unsigned char rs_cmd[REQUEST_SENSE_len];
8747         size_t rs_cmdLen = REQUEST_SENSE_len;
8748 
8749         unsigned char rs_in[RS_return_size];
8750         size_t rs_inLen = RS_return_size;
8751 
8752         memset(rs_cmd,0,rs_cmdLen);
8753         set_SCSI_opcode(rs_cmd, REQUEST_SENSE_code);
8754 	set_RS_return_size(rs_cmd, rs_inLen);
8755 
8756         DBG(25,"rs sub call >>\n");
8757         ret2 = do_cmd(
8758           s, 0, 0,
8759           rs_cmd, rs_cmdLen,
8760           NULL,0,
8761           rs_in, &rs_inLen
8762         );
8763         DBG(25,"rs sub call <<\n");
8764 
8765         if(ret2 == SANE_STATUS_EOF){
8766           DBG(5,"rs: got EOF, returning IO_ERROR\n");
8767           return SANE_STATUS_IO_ERROR;
8768         }
8769         if(ret2 != SANE_STATUS_GOOD){
8770           DBG(5,"rs: return error '%s'\n",sane_strstatus(ret2));
8771           return ret2;
8772         }
8773 
8774         /* parse the rs data */
8775         ret2 = sense_handler( 0, rs_in, (void *)s );
8776 
8777         DBG (10, "do_usb_clear: finish after RS\n");
8778         return ret2;
8779     }
8780 
8781     DBG (10, "do_usb_clear: finish with io error\n");
8782 
8783     return SANE_STATUS_IO_ERROR;
8784 }
8785 
8786 static SANE_Status
wait_scanner(struct scanner * s)8787 wait_scanner(struct scanner *s)
8788 {
8789   SANE_Status ret = SANE_STATUS_GOOD;
8790 
8791   unsigned char cmd[TEST_UNIT_READY_len];
8792   size_t cmdLen = TEST_UNIT_READY_len;
8793 
8794   DBG (10, "wait_scanner: start\n");
8795 
8796   memset(cmd,0,cmdLen);
8797   set_SCSI_opcode(cmd,TEST_UNIT_READY_code);
8798 
8799   ret = do_cmd (
8800     s, 0, s->tur_timeout,
8801     cmd, cmdLen,
8802     NULL, 0,
8803     NULL, NULL
8804   );
8805 
8806   if (ret != SANE_STATUS_GOOD) {
8807     DBG(5,"WARNING: Brain-dead scanner. Hitting with stick.\n");
8808     ret = do_cmd (
8809       s, 0, s->tur_timeout,
8810       cmd, cmdLen,
8811       NULL, 0,
8812       NULL, NULL
8813     );
8814   }
8815   if (ret != SANE_STATUS_GOOD) {
8816     DBG(5,"WARNING: Brain-dead scanner. Hitting with stick again.\n");
8817     ret = do_cmd (
8818       s, 0, s->tur_timeout,
8819       cmd, cmdLen,
8820       NULL, 0,
8821       NULL, NULL
8822     );
8823   }
8824   // some scanners (such as DR-F120) are OK but will not respond to commands
8825   // when in sleep mode. By checking the sense it wakes them up.
8826   if (ret != SANE_STATUS_GOOD) {
8827     DBG(5,"WARNING: Brain-dead scanner. Hitting with stick and request sense.\n");
8828     ret = do_cmd (
8829       s, 1, s->tur_timeout,
8830       cmd, cmdLen,
8831       NULL, 0,
8832       NULL, NULL
8833     );
8834   }
8835   if (ret != SANE_STATUS_GOOD) {
8836     DBG(5,"WARNING: Brain-dead scanner. Hitting with stick a fourth time.\n");
8837     ret = do_cmd (
8838       s, 0, s->tur_timeout,
8839       cmd, cmdLen,
8840       NULL, 0,
8841       NULL, NULL
8842     );
8843   }
8844 
8845   if (ret != SANE_STATUS_GOOD) {
8846     DBG (5, "wait_scanner: error '%s'\n", sane_strstatus (ret));
8847   }
8848 
8849   DBG (10, "wait_scanner: finish (status=%d)\n", ret);
8850 
8851   return ret;
8852 }
8853 
8854 /* Some scanners have per-resolution
8855  * color interlacing values, but most
8856  * don't. This helper can tell the
8857  * difference.
8858  */
8859 static int
get_color_inter(struct scanner * s,int side,int res)8860 get_color_inter(struct scanner *s, int side, int res)
8861 {
8862   int i;
8863   for(i=0;i<DPI_1200;i++){
8864     if(res == dpi_list[i])
8865       break;
8866   }
8867 
8868   if(s->color_inter_by_res[i])
8869     return s->color_inter_by_res[i];
8870 
8871   return s->color_interlace[side];
8872 }
8873 
8874 /* s->u.page_x stores the user setting
8875  * for the paper width in adf. sometimes,
8876  * we need a value that differs from this
8877  * due to using FB or overscan.
8878  */
8879 static int
get_page_width(struct scanner * s)8880 get_page_width(struct scanner *s)
8881 {
8882   int width = s->u.page_x;
8883 
8884   /* scanner max for fb */
8885   if(s->u.source == SOURCE_FLATBED){
8886       return s->max_x_fb;
8887   }
8888 
8889   /* can't overscan larger than scanner max */
8890   if(width > s->valid_x){
8891       return s->valid_x;
8892   }
8893 
8894   /* overscan adds a margin to both sides */
8895   return width;
8896 }
8897 
8898 /* s->u.page_y stores the user setting
8899  * for the paper height in adf. sometimes,
8900  * we need a value that differs from this
8901  * due to using FB or overscan.
8902  */
8903 static int
get_page_height(struct scanner * s)8904 get_page_height(struct scanner *s)
8905 {
8906   int height = s->u.page_y;
8907 
8908   /* scanner max for fb */
8909   if(s->u.source == SOURCE_FLATBED){
8910       return s->max_y_fb;
8911   }
8912 
8913   /* can't overscan larger than scanner max */
8914   if(height > s->max_y){
8915       return s->max_y;
8916   }
8917 
8918   /* overscan adds a margin to both sides */
8919   return height;
8920 }
8921 
8922 
8923 /**
8924  * Convenience method to determine longest string size in a list.
8925  */
8926 static size_t
maxStringSize(const SANE_String_Const strings[])8927 maxStringSize (const SANE_String_Const strings[])
8928 {
8929   size_t size, max_size = 0;
8930   int i;
8931 
8932   for (i = 0; strings[i]; ++i) {
8933     size = strlen (strings[i]) + 1;
8934     if (size > max_size)
8935       max_size = size;
8936   }
8937 
8938   return max_size;
8939 }
8940 
8941 /*
8942  * Prints a hex dump of the given buffer onto the debug output stream.
8943  */
8944 static void
hexdump(int level,char * comment,unsigned char * p,int l)8945 hexdump (int level, char *comment, unsigned char *p, int l)
8946 {
8947   int i;
8948   char line[70]; /* 'xxx: xx xx ... xx xx abc */
8949   char *hex = line+4;
8950   char *bin = line+53;
8951 
8952   if(DBG_LEVEL < level)
8953     return;
8954 
8955   line[0] = 0;
8956 
8957   DBG (level, "%s\n", comment);
8958 
8959   for (i = 0; i < l; i++, p++) {
8960 
8961     /* at start of line */
8962     if ((i % 16) == 0) {
8963 
8964       /* not at start of first line, print current, reset */
8965       if (i) {
8966         DBG (level, "%s\n", line);
8967       }
8968 
8969       memset(line,0x20,69);
8970       line[69] = 0;
8971       hex = line + 4;
8972       bin = line + 53;
8973 
8974       sprintf (line, "%3.3x:", i);
8975     }
8976 
8977     /* the hex section */
8978     sprintf (hex, " %2.2x", *p);
8979     hex += 3;
8980     *hex = ' ';
8981 
8982     /* the char section */
8983     if(*p >= 0x20 && *p <= 0x7e){
8984       *bin=*p;
8985     }
8986     else{
8987       *bin='.';
8988     }
8989     bin++;
8990   }
8991 
8992   /* print last (partial) line */
8993   if (i)
8994     DBG (level, "%s\n", line);
8995 }
8996 
8997 /**
8998  * An advanced method we don't support but have to define.
8999  */
9000 SANE_Status
sane_set_io_mode(SANE_Handle h,SANE_Bool non_blocking)9001 sane_set_io_mode (SANE_Handle h, SANE_Bool non_blocking)
9002 {
9003   DBG (10, "sane_set_io_mode\n");
9004   DBG (15, "%d %p\n", non_blocking, h);
9005   return SANE_STATUS_UNSUPPORTED;
9006 }
9007 
9008 /**
9009  * An advanced method we don't support but have to define.
9010  */
9011 SANE_Status
sane_get_select_fd(SANE_Handle h,SANE_Int * fdp)9012 sane_get_select_fd (SANE_Handle h, SANE_Int *fdp)
9013 {
9014   DBG (10, "sane_get_select_fd\n");
9015   DBG (15, "%p %d\n", h, *fdp);
9016   return SANE_STATUS_UNSUPPORTED;
9017 }
9018 
9019 /*
9020  * @@ Section 8 - Image processing functions
9021  */
9022 
9023 /* Look in image for likely upper and left paper edges, then rotate
9024  * image so that upper left corner of paper is upper left of image.
9025  * FIXME: should we do this before we binarize instead of after? */
9026 static SANE_Status
buffer_deskew(struct scanner * s,int side)9027 buffer_deskew(struct scanner *s, int side)
9028 {
9029   SANE_Status ret = SANE_STATUS_GOOD;
9030 
9031   unsigned char bg_color = calc_bg_color(s);
9032 
9033   DBG (10, "buffer_deskew: start\n");
9034 
9035   ret = sane_get_parameters((SANE_Handle) s, &s->s_params);
9036 
9037   /*only find skew on first image from a page, or if first image had error */
9038   if(s->side == SIDE_FRONT || s->u.source == SOURCE_ADF_BACK || s->deskew_stat){
9039 
9040     s->deskew_stat = sanei_magic_findSkew(
9041       &s->s_params,s->buffers[side],s->u.dpi_x,s->u.dpi_y,
9042       &s->deskew_vals[0],&s->deskew_vals[1],&s->deskew_slope);
9043 
9044     if(s->deskew_stat){
9045       DBG (5, "buffer_deskew: bad findSkew, bailing\n");
9046       goto cleanup;
9047     }
9048   }
9049   /* backside images can use a 'flipped' version of frontside data */
9050   else{
9051     s->deskew_slope *= -1;
9052     s->deskew_vals[0] = s->s_params.pixels_per_line - s->deskew_vals[0];
9053   }
9054 
9055   ret = sanei_magic_rotate(&s->s_params,s->buffers[side],
9056     s->deskew_vals[0],s->deskew_vals[1],s->deskew_slope,bg_color);
9057 
9058   if(ret){
9059     DBG(5,"buffer_deskew: rotate error: %d",ret);
9060     ret = SANE_STATUS_GOOD;
9061     goto cleanup;
9062   }
9063 
9064   cleanup:
9065   DBG (10, "buffer_deskew: finish\n");
9066   return ret;
9067 }
9068 
9069 /* Look in image for likely left/right/bottom paper edges, then crop
9070  * image to match. Does not attempt to rotate the image.
9071  * FIXME: should we do this before we binarize instead of after? */
9072 static SANE_Status
buffer_crop(struct scanner * s,int side)9073 buffer_crop(struct scanner *s, int side)
9074 {
9075   SANE_Status ret = SANE_STATUS_GOOD;
9076 
9077   DBG (10, "buffer_crop: start\n");
9078 
9079   ret = sane_get_parameters((SANE_Handle) s, &s->s_params);
9080 
9081   ret = sanei_magic_findEdges(
9082     &s->s_params,s->buffers[side],s->u.dpi_x,s->u.dpi_y,
9083     &s->crop_vals[0],&s->crop_vals[1],&s->crop_vals[2],&s->crop_vals[3]);
9084 
9085   if(ret){
9086     DBG (5, "buffer_crop: bad edges, bailing\n");
9087     ret = SANE_STATUS_GOOD;
9088     goto cleanup;
9089   }
9090 
9091   DBG (15, "buffer_crop: t:%d b:%d l:%d r:%d\n",
9092     s->crop_vals[0],s->crop_vals[1],s->crop_vals[2],s->crop_vals[3]);
9093 
9094   /* if we will later binarize this image, make sure the width
9095    * is a multiple of 8 pixels, by adjusting the right side */
9096   if ( must_downsample(s) && s->u.mode < MODE_GRAYSCALE ){
9097     s->crop_vals[3] -= (s->crop_vals[3]-s->crop_vals[2]) % 8;
9098   }
9099 
9100   /* now crop the image */
9101   ret = sanei_magic_crop(&s->s_params,s->buffers[side],
9102       s->crop_vals[0],s->crop_vals[1],s->crop_vals[2],s->crop_vals[3]);
9103 
9104   if(ret){
9105     DBG (5, "buffer_crop: bad crop, bailing\n");
9106     ret = SANE_STATUS_GOOD;
9107     goto cleanup;
9108   }
9109 
9110   /* need to update user with new size */
9111   s->i.width = s->s_params.pixels_per_line;
9112   s->i.height = s->s_params.lines;
9113   s->i.Bpl = s->s_params.bytes_per_line;
9114 
9115   /* update image size counter to new, smaller size */
9116   s->i.bytes_tot[side] = s->s_params.lines * s->s_params.bytes_per_line;
9117   s->i.bytes_sent[side] = s->i.bytes_tot[side];
9118   s->u.bytes_sent[side] = 0;
9119 
9120   cleanup:
9121   DBG (10, "buffer_crop: finish\n");
9122   return ret;
9123 }
9124 
9125 /* Look in image for disconnected 'spots' of the requested size.
9126  * Replace the spots with the average color of the surrounding pixels.
9127  * FIXME: should we do this before we binarize instead of after? */
9128 static SANE_Status
buffer_despeck(struct scanner * s,int side)9129 buffer_despeck(struct scanner *s, int side)
9130 {
9131   SANE_Status ret = SANE_STATUS_GOOD;
9132 
9133   DBG (10, "buffer_despeck: start\n");
9134 
9135   ret = sane_get_parameters((SANE_Handle) s, &s->s_params);
9136 
9137   ret = sanei_magic_despeck(&s->s_params,s->buffers[side],s->swdespeck);
9138   if(ret){
9139     DBG (5, "buffer_despeck: bad despeck, bailing\n");
9140     ret = SANE_STATUS_GOOD;
9141     goto cleanup;
9142   }
9143 
9144   cleanup:
9145   DBG (10, "buffer_despeck: finish\n");
9146   return ret;
9147 }
9148 
9149 /* Look if image has too few dark pixels.*/
9150 static int
buffer_isblank(struct scanner * s,int side)9151 buffer_isblank(struct scanner *s, int side)
9152 {
9153   SANE_Status ret = SANE_STATUS_GOOD;
9154   int status = 0;
9155 
9156   DBG (10, "buffer_isblank: start\n");
9157 
9158   ret = sane_get_parameters((SANE_Handle) s, &s->s_params);
9159 
9160   ret = sanei_magic_isBlank2(&s->s_params, s->buffers[side],
9161     s->u.dpi_x, s->u.dpi_y, s->swskip);
9162 
9163   if(ret == SANE_STATUS_NO_DOCS){
9164     DBG (5, "buffer_isblank: blank!\n");
9165     status = 1;
9166   }
9167   else if(ret){
9168     DBG (5, "buffer_isblank: error %d\n",ret);
9169   }
9170 
9171   DBG (10, "buffer_isblank: finished\n");
9172   return status;
9173 }
9174 
9175 /* certain options require the entire image to
9176  * be collected from the scanner before we can
9177  * tell the user the size of the image. */
9178 static int
must_fully_buffer(struct scanner * s)9179 must_fully_buffer(struct scanner *s)
9180 {
9181 
9182   if(
9183     (s->swdeskew || s->swdespeck || s->swcrop)
9184     && s->s.format != SANE_FRAME_JPEG
9185   ){
9186     return 1;
9187   }
9188 
9189   return 0;
9190 }
9191 
9192 /* certain scanners require the mode of the
9193  * image to be changed in software. */
9194 static int
must_downsample(struct scanner * s)9195 must_downsample(struct scanner *s)
9196 {
9197   if(s->s.mode != s->i.mode
9198     && s->compress != COMP_JPEG
9199   ){
9200     return 1;
9201   }
9202 
9203   return 0;
9204 }
9205 
9206 /* Function to build a lookup table (LUT), often
9207    used by scanners to implement brightness/contrast/gamma
9208    or by backends to speed binarization/thresholding
9209 
9210    offset and slope inputs are -127 to +127
9211 
9212    slope rotates line around central input/output val,
9213    0 makes horizontal line
9214 
9215        pos           zero          neg
9216        .       x     .             .  x
9217        .      x      .             .   x
9218    out .     x       .xxxxxxxxxxx  .    x
9219        .    x        .             .     x
9220        ....x.......  ............  .......x....
9221             in            in            in
9222 
9223    offset moves line vertically, and clamps to output range
9224    0 keeps the line crossing the center of the table
9225 
9226        pos            zero          neg
9227        .   xxxxxxxx   .        xx   .
9228        . x            .      x      .
9229    out x              .    x        .          x
9230        .              .  x          .        x
9231        ............   xx..........  xxxxxxxx....
9232             in             in
9233 
9234    out_min/max provide bounds on output values,
9235    useful when building thresholding lut.
9236    0 and 255 are good defaults otherwise.
9237   */
9238 static SANE_Status
load_lut(unsigned char * lut,int in_bits,int out_bits,int out_min,int out_max,int slope,int offset)9239 load_lut (unsigned char * lut,
9240   int in_bits, int out_bits,
9241   int out_min, int out_max,
9242   int slope, int offset)
9243 {
9244   SANE_Status ret = SANE_STATUS_GOOD;
9245   int i, j;
9246   double shift, rise;
9247   int max_in_val = (1 << in_bits) - 1;
9248   int max_out_val = (1 << out_bits) - 1;
9249   unsigned char * lut_p = lut;
9250 
9251   DBG (10, "load_lut: start %d %d\n", slope, offset);
9252 
9253   /* slope is converted to rise per unit run:
9254    * first [-127,127] to [-.999,.999]
9255    * then to [-PI/4,PI/4] then [0,PI/2]
9256    * then take the tangent (T.O.A)
9257    * then multiply by the normal linear slope
9258    * because the table may not be square, i.e. 1024x256*/
9259   rise = tan((double)slope/128 * M_PI_4 + M_PI_4) * max_out_val / max_in_val;
9260 
9261   /* line must stay vertically centered, so figure
9262    * out vertical offset at central input value */
9263   shift = (double)max_out_val/2 - (rise*max_in_val/2);
9264 
9265   /* convert the user offset setting to scale of output
9266    * first [-127,127] to [-1,1]
9267    * then to [-max_out_val/2,max_out_val/2]*/
9268   shift += (double)offset / 127 * max_out_val / 2;
9269 
9270   for(i=0;i<=max_in_val;i++){
9271     j = rise*i + shift;
9272 
9273     if(j<out_min){
9274       j=out_min;
9275     }
9276     else if(j>out_max){
9277       j=out_max;
9278     }
9279 
9280     *lut_p=j;
9281     lut_p++;
9282   }
9283 
9284   hexdump(5, "load_lut: ", lut, max_in_val+1);
9285 
9286   DBG (10, "load_lut: finish\n");
9287   return ret;
9288 }
9289