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