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