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