1 /* sane - Scanner Access Now Easy.
2
3 This file implements a SANE backend for the Fujitsu fi-60F, the
4 ScanSnap S300/S1300, and (hopefully) other Epson-based scanners.
5
6 Copyright 2007-2022 by m. allan noah <kitno455 at gmail dot com>
7 Copyright 2009 by Richard Goedeken <richard at fascinationsoftware dot com>
8
9 Development funded by Microdea, Inc., TrueCheck, Inc. and Archivista, GmbH
10
11 --------------------------------------------------------------------------
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <https://www.gnu.org/licenses/>.
25
26 As a special exception, the authors of SANE give permission for
27 additional uses of the libraries contained in this release of SANE.
28
29 The exception is that, if you link a SANE library with other files
30 to produce an executable, this does not by itself cause the
31 resulting executable to be covered by the GNU General Public
32 License. Your use of that executable is in no way restricted on
33 account of linking the SANE library code into it.
34
35 This exception does not, however, invalidate any other reasons why
36 the executable file might be covered by the GNU General Public
37 License.
38
39 If you submit changes to SANE to the maintainers to be included in
40 a subsequent release, you agree by submitting the changes that
41 those changes may be distributed with this exception intact.
42
43 If you write modifications of your own for SANE, it is your choice
44 whether to permit this exception to apply to your modifications.
45 If you do not wish that, delete this exception notice.
46
47 --------------------------------------------------------------------------
48
49 The source code is divided in sections which you can easily find by
50 searching for the tag "@@".
51
52 Section 1 - Init & static stuff
53 Section 2 - sane_init, _get_devices, _open & friends
54 Section 3 - sane_*_option functions
55 Section 4 - sane_start, _get_param, _read & friends
56 Section 5 - sane_close functions
57 Section 6 - misc functions
58
59 Changes:
60 v0, 2007-08-08, MAN
61 - initial alpha release, S300 raw data only
62 v1, 2007-09-03, MAN
63 - only supports 300dpi duplex binary for S300
64 v2, 2007-09-05, MAN
65 - add resolution option (only one choice)
66 - add simplex option
67 v3, 2007-09-12, MAN
68 - add support for 150 dpi resolution
69 v4, 2007-10-03, MAN
70 - change binarization algo to use average of all channels
71 v5, 2007-10-10, MAN
72 - move data blocks to separate file
73 - add basic fi-60F support (600dpi color)
74 v6, 2007-11-12, MAN
75 - move various data vars into transfer structs
76 - move most of read_from_scanner to sane_read
77 - add single line reads to calibration code
78 - generate calibration buffer from above reads
79 v7, 2007-12-05, MAN
80 - split calibration into fine and coarse functions
81 - add S300 fine calibration code
82 - add S300 color and grayscale support
83 v8, 2007-12-06, MAN
84 - change sane_start to call ingest earlier
85 - enable SOURCE_ADF_BACK
86 - add if() around memcopy and better debugs in sane_read
87 - shorten default scan sizes from 15.4 to 11.75 inches
88 v9, 2007-12-17, MAN
89 - fi-60F 300 & 600 dpi support (150 is non-square?)
90 - fi-60F gray & binary support
91 - fi-60F improved calibration
92 v10, 2007-12-19, MAN (SANE v1.0.19)
93 - fix missing function (and memory leak)
94 v11 2008-02-14, MAN
95 - sanei_config_read has already cleaned string (#310597)
96 v12 2008-02-28, MAN
97 - cleanup double free bug with new destroy()
98 v13 2008-09-18, MAN
99 - add working page-height control
100 - add working brightness, contrast and threshold controls
101 - add disabled threshold curve and geometry controls
102 - move initialization code to sane_get_devices, for hotplugging
103 v14 2008-09-24, MAN
104 - support S300 on USB power
105 - support S300 225x200 and 600x600 scans
106 - support for automatic paper length detection (parm.lines = -1)
107 v15 2008-09-24, MAN
108 - expose hardware buttons/sensors as options for S300
109 v16 2008-10-01, MAN
110 - split fill_frontback_buffers_S300 into 3 functions
111 - enable threshold_curve option
112 - add 1-D dynamic binary thresholding code
113 - remove y-resolution option
114 - pad 225x200 data to 225x225
115 v17 2008-10-03, MAN
116 - increase scan height ~1/2 inch due to head offset
117 - change page length autodetection condition
118 v18 2009-01-21, MAN
119 - don't export private symbols
120 v19 2009-08-31, RG
121 - rewritten calibration routines
122 v20 2010-02-09, MAN (SANE 1.0.21 to 1.0.24)
123 - cleanup #include lines & copyright
124 - add S1300
125 v21 2011-04-15, MAN
126 - unreleased attempt at S1100 support
127 v22 2014-05-15, MAN/Hiroshi Miura
128 - port some S1100 changes from v21
129 - add paper size support
130 v23 2014-05-20, MAN
131 - add S1300i support
132 - fix buffer overruns in read_from_scanner
133 - set default page width
134 - simplified the 225x200 resolution code
135 v24 2014-06-01, MAN
136 - enable fine calibration for S1300i 225 & 300 dpi, and S300 150 dpi
137 v25 2014-06-04, MAN
138 - initial support for fi-65F
139 - initial support for S1100
140 v26 2014-06-28, MAN
141 - add resolution scaling
142 - fix 150 dpi settings for fi-60F and fi-65F
143 - make adf_height_padding variable
144 - make white_factor variable
145 v27 2015-01-24, MAN
146 - don't override br_x and br_y
147 - call change_params after changing page_width
148 v28 2015-03-23, MAN
149 - call get_hardware_status before starting scan
150 v29 2017-03-18, MAN
151 - fix infinite loop when scaling in Y direction
152 v30 2017-03-21, MAN
153 - fix image truncation when using 150 DPI in Y direction
154 - add 200 and 400 DPI Y direction support for fi-60F/65F
155 v31 2017-04-09, MAN
156 - hardware gray support for fi-60F/65F (disabled pending calibration)
157 - merge fi-60F/65F settings
158 v32 2022-11-15, MAN
159 - fix hanging scan when using source = ADF Back (fixes #601)
160 v33 2022-11-17, MAN
161 - S1300i: fix color plane offset at 225 and 330 dpi (fixes #538)
162
163 SANE FLOW DIAGRAM
164
165 - sane_init() : initialize backend
166 . - sane_get_devices() : query list of scanner devices
167 . - sane_open() : open a particular scanner device
168 . . - sane_set_io_mode : set blocking mode
169 . . - sane_get_select_fd : get scanner fd
170 . .
171 . . - sane_get_option_descriptor() : get option information
172 . . - sane_control_option() : change option values
173 . . - sane_get_parameters() : returns estimated scan parameters
174 . . - (repeat previous 3 functions)
175 . .
176 . . - sane_start() : start image acquisition
177 . . - sane_get_parameters() : returns actual scan parameters
178 . . - sane_read() : read image data (from pipe)
179 . . (sane_read called multiple times; after sane_read returns EOF,
180 . . loop may continue with sane_start which may return a 2nd page
181 . . when doing duplex scans, or load the next page from the ADF)
182 . .
183 . . - sane_cancel() : cancel operation
184 . - sane_close() : close opened scanner device
185 - sane_exit() : terminate use of backend
186
187 */
188
189 /*
190 * @@ Section 1 - Init
191 */
192
193 #include "../include/sane/config.h"
194
195 #include <string.h> /*memcpy...*/
196 #include <ctype.h> /*isspace*/
197 #include <math.h> /*tan*/
198 #include <unistd.h> /*usleep*/
199 #include <time.h> /*time*/
200
201 #include "../include/sane/sanei_backend.h"
202 #include "../include/sane/sanei_usb.h"
203 #include "../include/sane/saneopts.h"
204 #include "../include/sane/sanei_config.h"
205
206 #include "epjitsu.h"
207 #include "epjitsu-cmd.h"
208
209 #define DEBUG 1
210 #define BUILD 33
211
212 #ifndef MIN
213 #define MIN(a,b) ((a) < (b) ? (a) : (b))
214 #endif
215 #ifndef MAX
216 #define MAX(a,b) ((a) > (b) ? (a) : (b))
217 #endif
218 #ifndef MAX3
219 #define MAX3(a,b,c) ((a) > (b) ? ((a) > (c) ? a : c) : ((b) > (c) ? b : c))
220 #endif
221
222 unsigned char global_firmware_filename[PATH_MAX];
223
224 /* values for SANE_DEBUG_EPJITSU env var:
225 - errors 5
226 - function trace 10
227 - function detail 15
228 - get/setopt cmds 20
229 - usb cmd trace 25
230 - usb cmd detail 30
231 - useless noise 35
232 */
233
234 /* Calibration settings */
235 #define COARSE_OFFSET_TARGET 15
236 static int coarse_gain_min[3] = { 88, 88, 88 }; /* front, back, FI-60F 3rd plane */
237 static int coarse_gain_max[3] = { 92, 92, 92 };
238 static int fine_gain_target[3] = {185, 150, 170}; /* front, back, FI-60F is this ok? */
239
240 /* ------------------------------------------------------------------------- */
241 #define STRING_FLATBED SANE_I18N("Flatbed")
242 #define STRING_ADFFRONT SANE_I18N("ADF Front")
243 #define STRING_ADFBACK SANE_I18N("ADF Back")
244 #define STRING_ADFDUPLEX SANE_I18N("ADF Duplex")
245
246 #define STRING_LINEART SANE_VALUE_SCAN_MODE_LINEART
247 #define STRING_GRAYSCALE SANE_VALUE_SCAN_MODE_GRAY
248 #define STRING_COLOR SANE_VALUE_SCAN_MODE_COLOR
249
250 /*
251 * used by attach* and sane_get_devices
252 * a ptr to a null term array of ptrs to SANE_Device structs
253 * a ptr to a single-linked list of scanner structs
254 */
255 static const SANE_Device **sane_devArray = NULL;
256 static struct scanner *scanner_devList = NULL;
257
258 /*
259 * @@ Section 2 - SANE & scanner init code
260 */
261
262 /*
263 * Called by SANE initially.
264 *
265 * From the SANE spec:
266 * This function must be called before any other SANE function can be
267 * called. The behavior of a SANE backend is undefined if this
268 * function is not called first. The version code of the backend is
269 * returned in the value pointed to by version_code. If that pointer
270 * is NULL, no version code is returned. Argument authorize is either
271 * a pointer to a function that is invoked when the backend requires
272 * authentication for a specific resource or NULL if the frontend does
273 * not support authentication.
274 */
275 SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)276 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
277 {
278 (void) authorize; /* get rid of compiler warning */
279
280 DBG_INIT ();
281 DBG (10, "sane_init: start\n");
282
283 if (version_code)
284 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
285
286 DBG (5, "sane_init: epjitsu backend %d.%d.%d, from %s\n",
287 SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING);
288
289 DBG (10, "sane_init: finish\n");
290
291 return SANE_STATUS_GOOD;
292 }
293
294 /*
295 * Called by SANE to find out about supported devices.
296 *
297 * From the SANE spec:
298 * This function can be used to query the list of devices that are
299 * available. If the function executes successfully, it stores a
300 * pointer to a NULL terminated array of pointers to SANE_Device
301 * structures in *device_list. The returned list is guaranteed to
302 * remain unchanged and valid until (a) another call to this function
303 * is performed or (b) a call to sane_exit() is performed. This
304 * function can be called repeatedly to detect when new devices become
305 * available. If argument local_only is true, only local devices are
306 * returned (devices directly attached to the machine that SANE is
307 * running on). If it is false, the device list includes all remote
308 * devices that are accessible to the SANE library.
309 *
310 * SANE does not require that this function is called before a
311 * sane_open() call is performed. A device name may be specified
312 * explicitly by a user which would make it unnecessary and
313 * undesirable to call this function first.
314 *
315 * Read the config file, find scanners with help from sanei_*
316 * store in global device structs
317 */
318 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)319 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
320 {
321 SANE_Status ret = SANE_STATUS_GOOD;
322 struct scanner * s;
323 struct scanner * prev = NULL;
324 char line[PATH_MAX];
325 const char *lp;
326 FILE *fp;
327 int num_devices=0;
328 int i=0;
329
330 (void) local_only; /* get rid of compiler warning */
331
332 DBG (10, "sane_get_devices: start\n");
333
334 /* mark all existing scanners as missing, attach_one will remove mark */
335 for (s = scanner_devList; s; s = s->next) {
336 s->missing = 1;
337 }
338
339 sanei_usb_init();
340
341 fp = sanei_config_open (CONFIG_FILE);
342
343 if (fp) {
344
345 DBG (15, "sane_get_devices: reading config file %s\n", CONFIG_FILE);
346
347 while (sanei_config_read (line, PATH_MAX, fp)) {
348
349 lp = line;
350
351 /* ignore comments */
352 if (*lp == '#')
353 continue;
354
355 /* skip empty lines */
356 if (*lp == 0)
357 continue;
358
359 if ((strncmp ("firmware", lp, 8) == 0) && isspace (lp[8])) {
360 size_t firmware_len;
361
362 lp += 8;
363 lp = sanei_config_skip_whitespace (lp);
364 DBG (15, "sane_get_devices: firmware '%s'\n", lp);
365
366 firmware_len = strlen(lp);
367 if (firmware_len > sizeof(global_firmware_filename) - 1)
368 {
369 DBG (5, "sane_get_devices: firmware file too long. ignoring '%s'\n", lp);
370 }
371 else
372 {
373 strcpy((char *)global_firmware_filename, lp);
374 }
375 }
376 else if ((strncmp ("usb", lp, 3) == 0) && isspace (lp[3])) {
377 DBG (15, "sane_get_devices: looking for '%s'\n", lp);
378 sanei_usb_attach_matching_devices(lp, attach_one);
379 }
380 else{
381 DBG (5, "sane_get_devices: config line \"%s\" ignored.\n", lp);
382 }
383 }
384 fclose (fp);
385 }
386
387 else {
388 DBG (5, "sane_get_devices: no config file '%s'!\n",
389 CONFIG_FILE);
390 }
391
392 /*delete missing scanners from list*/
393 for (s = scanner_devList; s;) {
394 if(s->missing){
395 DBG (5, "sane_get_devices: missing scanner %s\n",s->sane.name);
396
397 /*splice s out of list by changing pointer in prev to next*/
398 if(prev){
399 prev->next = s->next;
400 free(s);
401 s=prev->next;
402 }
403 /*remove s from head of list, using prev to cache it*/
404 else{
405 prev = s;
406 s = s->next;
407 free(prev);
408 prev=NULL;
409
410 /*reset head to next s*/
411 scanner_devList = s;
412 }
413 }
414 else{
415 prev = s;
416 s=prev->next;
417 }
418 }
419
420 for (s = scanner_devList; s; s=s->next) {
421 DBG (15, "sane_get_devices: found scanner %s\n",s->sane.name);
422 num_devices++;
423 }
424
425 DBG (15, "sane_get_devices: found %d scanner(s)\n",num_devices);
426
427 if (sane_devArray)
428 free (sane_devArray);
429
430 sane_devArray = calloc (num_devices + 1, sizeof (SANE_Device*));
431 if (!sane_devArray)
432 return SANE_STATUS_NO_MEM;
433
434 for (s = scanner_devList; s; s=s->next) {
435 sane_devArray[i++] = (SANE_Device *)&s->sane;
436 }
437 sane_devArray[i] = 0;
438
439 if(device_list){
440 *device_list = sane_devArray;
441 }
442
443 DBG (10, "sane_get_devices: finish\n");
444
445 return ret;
446 }
447
448 /* callback used by sane_init
449 * build the scanner struct and link to global list
450 * unless struct is already loaded, then pretend
451 */
452 static SANE_Status
attach_one(const char *name)453 attach_one (const char *name)
454 {
455 struct scanner *s;
456 int ret, i;
457
458 DBG (10, "attach_one: start '%s'\n", name);
459
460 for (s = scanner_devList; s; s = s->next) {
461 if (strcmp (s->sane.name, name) == 0) {
462 DBG (10, "attach_one: already attached!\n");
463 s->missing = 0;
464 return SANE_STATUS_GOOD;
465 }
466 }
467
468 /* build a scanner struct to hold it */
469 DBG (15, "attach_one: init struct\n");
470
471 if ((s = calloc (sizeof (*s), 1)) == NULL)
472 return SANE_STATUS_NO_MEM;
473
474 /* copy the device name */
475 s->sane.name = strdup (name);
476 if (!s->sane.name){
477 destroy(s);
478 return SANE_STATUS_NO_MEM;
479 }
480
481 /* connect the fd */
482 DBG (15, "attach_one: connect fd\n");
483
484 s->fd = -1;
485 ret = connect_fd(s);
486 if(ret != SANE_STATUS_GOOD){
487 destroy(s);
488 return ret;
489 }
490
491 /* load the firmware file into scanner */
492 ret = load_fw(s);
493 if (ret != SANE_STATUS_GOOD) {
494 destroy(s);
495 DBG (5, "attach_one: firmware load failed\n");
496 return ret;
497 }
498
499 /* Now query the device to load its vendor/model/version */
500 ret = get_ident(s);
501 if (ret != SANE_STATUS_GOOD) {
502 destroy(s);
503 DBG (5, "attach_one: identify failed\n");
504 return ret;
505 }
506
507 DBG (15, "attach_one: Found %s scanner %s at %s\n",
508 s->sane.vendor, s->sane.model, s->sane.name);
509
510 if (strstr (s->sane.model, "S1300i")){
511 unsigned char stat;
512
513 DBG (15, "attach_one: Found S1300i\n");
514
515 stat = get_stat(s);
516 if(stat & 0x01){
517 DBG (5, "attach_one: on USB power?\n");
518 s->usb_power=1;
519 }
520
521 s->model = MODEL_S1300i;
522
523 s->has_adf = 1;
524 s->has_adf_duplex = 1;
525 s->min_res = 50;
526 s->max_res = 600;
527 s->adf_height_padding = 600;
528 /* Blue, Red, Green */
529 s->white_factor[0] = 1.0;
530 s->white_factor[1] = 0.93;
531 s->white_factor[2] = 0.98;
532
533 s->source = SOURCE_ADF_FRONT;
534 s->mode = MODE_LINEART;
535 s->resolution = 300;
536 s->page_height = 11.5 * 1200;
537 s->page_width = 8.5 * 1200;
538
539 s->threshold = 120;
540 s->threshold_curve = 55;
541 }
542 else if (strstr (s->sane.model, "S300") || strstr (s->sane.model, "S1300")){
543 unsigned char stat;
544
545 DBG (15, "attach_one: Found S300/S1300\n");
546
547 stat = get_stat(s);
548 if(stat & 0x01){
549 DBG (5, "attach_one: on USB power?\n");
550 s->usb_power=1;
551 }
552
553 s->model = MODEL_S300;
554
555 s->has_adf = 1;
556 s->has_adf_duplex = 1;
557 s->min_res = 50;
558 s->max_res = 600;
559 s->adf_height_padding = 600;
560 /* Blue, Red, Green */
561 s->white_factor[0] = 1.0;
562 s->white_factor[1] = 0.93;
563 s->white_factor[2] = 0.98;
564
565 s->source = SOURCE_ADF_FRONT;
566 s->mode = MODE_LINEART;
567 s->resolution = 300;
568 s->page_height = 11.5 * 1200;
569 s->page_width = 8.5 * 1200;
570
571 s->threshold = 120;
572 s->threshold_curve = 55;
573 }
574 else if (strstr (s->sane.model, "S1100")){
575 DBG (15, "attach_one: Found S1100\n");
576 s->model = MODEL_S1100;
577
578 s->usb_power = 1;
579 s->has_adf = 1;
580 s->has_adf_duplex = 0;
581 s->min_res = 50;
582 s->max_res = 600;
583 s->adf_height_padding = 450;
584 /* Blue, Red, Green */
585 s->white_factor[0] = 0.95;
586 s->white_factor[1] = 1.0;
587 s->white_factor[2] = 1.0;
588
589 s->source = SOURCE_ADF_FRONT;
590 s->mode = MODE_LINEART;
591 s->resolution = 300;
592 s->page_height = 11.5 * 1200;
593 s->page_width = 8.5 * 1200;
594
595 s->threshold = 120;
596 s->threshold_curve = 55;
597 }
598 else if (strstr (s->sane.model, "fi-60F")){
599 DBG (15, "attach_one: Found fi-60F\n");
600
601 s->model = MODEL_FI60F;
602
603 s->has_fb = 1;
604 s->min_res = 50;
605 s->max_res = 600;
606 /* Blue, Red, Green */
607 s->white_factor[0] = 1.0;
608 s->white_factor[1] = 0.93;
609 s->white_factor[2] = 0.98;
610
611 s->source = SOURCE_FLATBED;
612 s->mode = MODE_COLOR;
613 s->resolution = 300;
614 s->page_height = 5.83 * 1200;
615 s->page_width = 4.1 * 1200;
616
617 s->threshold = 120;
618 s->threshold_curve = 55;
619 }
620
621 else if (strstr (s->sane.model, "fi-65F")){
622 DBG (15, "attach_one: Found fi-65F\n");
623
624 s->model = MODEL_FI65F;
625
626 s->has_fb = 1;
627 s->min_res = 50;
628 s->max_res = 600;
629 /* Blue, Red, Green */
630 s->white_factor[0] = 1.0;
631 s->white_factor[1] = 0.93;
632 s->white_factor[2] = 0.98;
633
634 s->source = SOURCE_FLATBED;
635 s->mode = MODE_COLOR;
636 s->resolution = 300;
637 s->page_height = 5.83 * 1200;
638 s->page_width = 4.1 * 1200;
639
640 s->threshold = 120;
641 s->threshold_curve = 55;
642 }
643 else{
644 DBG (15, "attach_one: Found other\n");
645 }
646
647 /* set SANE option 'values' to good defaults */
648 DBG (15, "attach_one: init options\n");
649
650 /* go ahead and setup the first opt, because
651 * frontend may call control_option on it
652 * before calling get_option_descriptor
653 */
654 memset (s->opt, 0, sizeof (s->opt));
655 for (i = 0; i < NUM_OPTIONS; ++i) {
656 s->opt[i].name = "filler";
657 s->opt[i].size = sizeof (SANE_Word);
658 s->opt[i].cap = SANE_CAP_INACTIVE;
659 }
660
661 s->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS;
662 s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
663 s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
664 s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
665
666 DBG (15, "attach_one: init settings\n");
667 ret = change_params(s);
668
669 /* we close the connection, so that another backend can talk to scanner */
670 disconnect_fd(s);
671
672 s->next = scanner_devList;
673 scanner_devList = s;
674
675 DBG (10, "attach_one: finish\n");
676
677 return SANE_STATUS_GOOD;
678 }
679
680 /*
681 * connect the fd in the scanner struct
682 */
683 static SANE_Status
connect_fd(struct scanner *s)684 connect_fd (struct scanner *s)
685 {
686 SANE_Status ret;
687
688 DBG (10, "connect_fd: start\n");
689
690 if(s->fd > -1){
691 DBG (5, "connect_fd: already open\n");
692 ret = SANE_STATUS_GOOD;
693 }
694 else {
695 DBG (15, "connect_fd: opening USB device\n");
696 ret = sanei_usb_open (s->sane.name, &(s->fd));
697 }
698
699 if(ret != SANE_STATUS_GOOD){
700 DBG (5, "connect_fd: could not open device: %d\n", ret);
701 }
702
703 DBG (10, "connect_fd: finish\n");
704
705 return ret;
706 }
707
708 /*
709 * try to load fw into scanner
710 */
711 static SANE_Status
load_fw(struct scanner *s)712 load_fw (struct scanner *s)
713 {
714 SANE_Status ret = SANE_STATUS_GOOD;
715 int file, i;
716 int len = 0;
717 unsigned char * buf;
718
719 unsigned char cmd[4];
720 size_t cmdLen;
721 unsigned char stat[2];
722 size_t statLen;
723
724 DBG (10, "load_fw: start\n");
725
726 /*check status*/
727 /*reuse stat buffer*/
728 stat[0] = get_stat(s);
729
730 if(stat[0] & 0x10){
731 DBG (5, "load_fw: firmware already loaded?\n");
732 return SANE_STATUS_GOOD;
733 }
734
735 if(!global_firmware_filename[0]){
736 DBG (5, "load_fw: missing filename\n");
737 return SANE_STATUS_NO_DOCS;
738 }
739
740 file = open((char *)global_firmware_filename,O_RDONLY);
741 if(!file){
742 DBG (5, "load_fw: failed to open file %s\n",global_firmware_filename);
743 return SANE_STATUS_NO_DOCS;
744 }
745
746 /* skip first 256 (=0x100) bytes */
747 if(lseek(file,0x100,SEEK_SET) != 0x100){
748 DBG (5, "load_fw: failed to lseek file %s\n",global_firmware_filename);
749 close(file);
750 return SANE_STATUS_NO_DOCS;
751 }
752
753 buf = malloc(FIRMWARE_LENGTH);
754 if(!buf){
755 DBG (5, "load_fw: failed to alloc mem\n");
756 close(file);
757 return SANE_STATUS_NO_MEM;
758 }
759
760 len = read(file,buf,FIRMWARE_LENGTH);
761 close(file);
762
763 if(len != FIRMWARE_LENGTH){
764 DBG (5, "load_fw: firmware file %s wrong length\n",
765 global_firmware_filename);
766 free(buf);
767 return SANE_STATUS_NO_DOCS;
768 }
769
770 DBG (15, "load_fw: read firmware file %s ok\n", global_firmware_filename);
771
772 /* firmware upload is in three commands */
773
774 /*start/status*/
775 cmd[0] = 0x1b;
776 cmd[1] = 0x06;
777 cmdLen = 2;
778 statLen = 1;
779
780 ret = do_cmd(
781 s, 0,
782 cmd, cmdLen,
783 NULL, 0,
784 stat, &statLen
785 );
786 if(ret){
787 DBG (5, "load_fw: error on cmd 1\n");
788 free(buf);
789 return ret;
790 }
791 if(stat[0] != 6){
792 DBG (5, "load_fw: bad stat on cmd 1\n");
793 free(buf);
794 return SANE_STATUS_IO_ERROR;
795 }
796
797 /*length/data*/
798 cmd[0] = 0x01;
799 cmd[1] = 0x00;
800 cmd[2] = 0x01;
801 cmd[3] = 0x00;
802 cmdLen = 4;
803
804 ret = do_cmd(
805 s, 0,
806 cmd, cmdLen,
807 buf, FIRMWARE_LENGTH,
808 NULL, 0
809 );
810 if(ret){
811 DBG (5, "load_fw: error on cmd 2\n");
812 free(buf);
813 return ret;
814 }
815
816 /*checksum/status*/
817 cmd[0] = 0;
818 for(i=0;i<FIRMWARE_LENGTH;i++){
819 cmd[0] += buf[i];
820 }
821 free(buf);
822
823 cmdLen = 1;
824 statLen = 1;
825
826 ret = do_cmd(
827 s, 0,
828 cmd, cmdLen,
829 NULL, 0,
830 stat, &statLen
831 );
832 if(ret){
833 DBG (5, "load_fw: error on cmd 3\n");
834 return ret;
835 }
836 if(stat[0] != 6){
837 DBG (5, "load_fw: bad stat on cmd 3\n");
838 return SANE_STATUS_IO_ERROR;
839 }
840
841 /*reinit*/
842 cmd[0] = 0x1b;
843 cmd[1] = 0x16;
844 cmdLen = 2;
845 statLen = 1;
846
847 ret = do_cmd(
848 s, 0,
849 cmd, cmdLen,
850 NULL, 0,
851 stat, &statLen
852 );
853 if(ret){
854 DBG (5, "load_fw: error reinit cmd\n");
855 return ret;
856 }
857 if(stat[0] != 6){
858 DBG (5, "load_fw: reinit cmd bad status?\n");
859 return SANE_STATUS_IO_ERROR;
860 }
861
862 cmd[0] = 0x80;
863 cmdLen = 1;
864 statLen = 1;
865
866 ret = do_cmd(
867 s, 0,
868 cmd, cmdLen,
869 NULL, 0,
870 stat, &statLen
871 );
872 if(ret){
873 DBG (5, "load_fw: error reinit payload\n");
874 return ret;
875 }
876 if(stat[0] != 6){
877 DBG (5, "load_fw: reinit payload bad status?\n");
878 return SANE_STATUS_IO_ERROR;
879 }
880
881 /*reuse stat buffer*/
882 stat[0] = get_stat(s);
883
884 if(!(stat[0] & 0x10)){
885 DBG (5, "load_fw: firmware not loaded? %#x\n",stat[0]);
886 return SANE_STATUS_IO_ERROR;
887 }
888
889 return ret;
890 }
891
892 /*
893 * get status from scanner
894 */
895 static unsigned char
get_stat(struct scanner *s)896 get_stat(struct scanner *s)
897 {
898 SANE_Status ret = SANE_STATUS_GOOD;
899
900 unsigned char cmd[2];
901 size_t cmdLen;
902 unsigned char stat[2];
903 size_t statLen;
904
905 DBG (10, "get_stat: start\n");
906
907 /*check status*/
908 cmd[0] = 0x1b;
909 cmd[1] = 0x03;
910 cmdLen = 2;
911 statLen = 2;
912
913 ret = do_cmd(
914 s, 0,
915 cmd, cmdLen,
916 NULL, 0,
917 stat, &statLen
918 );
919 if(ret){
920 DBG (5, "get_stat: error checking status\n");
921 return 0;
922 }
923
924 return stat[0];
925 }
926
927 /*
928 * get scanner identification
929 */
930
931 static SANE_Status
get_ident(struct scanner *s)932 get_ident(struct scanner *s)
933 {
934 int i;
935 SANE_Status ret;
936
937 unsigned char cmd[] = {0x1b,0x13};
938 size_t cmdLen = 2;
939 unsigned char in[0x20];
940 size_t inLen = sizeof(in);
941
942 DBG (10, "get_ident: start\n");
943
944 ret = do_cmd (
945 s, 0,
946 cmd, cmdLen,
947 NULL, 0,
948 in, &inLen
949 );
950
951 if (ret != SANE_STATUS_GOOD){
952 return ret;
953 }
954
955 /*hmm, similar to scsi?*/
956 for (i = 7; (in[i] == ' ' || in[i] == 0xff) && i >= 0; i--){
957 in[i] = 0;
958 }
959 s->sane.vendor = strndup((char *)in, 8);
960
961 for (i = 23; (in[i] == ' ' || in[i] == 0xff) && i >= 8; i--){
962 in[i] = 0;
963 }
964 s->sane.model= strndup((char *)in+8, 24);
965
966 s->sane.type = "scanner";
967
968 DBG (10, "get_ident: finish\n");
969 return ret;
970 }
971
972 /*
973 * From the SANE spec:
974 * This function is used to establish a connection to a particular
975 * device. The name of the device to be opened is passed in argument
976 * name. If the call completes successfully, a handle for the device
977 * is returned in *h. As a special case, specifying a zero-length
978 * string as the device requests opening the first available device
979 * (if there is such a device).
980 */
981 SANE_Status
sane_open(SANE_String_Const name, SANE_Handle * handle)982 sane_open (SANE_String_Const name, SANE_Handle * handle)
983 {
984 struct scanner *dev = NULL;
985 struct scanner *s = NULL;
986 SANE_Status ret;
987
988 DBG (10, "sane_open: start\n");
989
990 if(scanner_devList){
991 DBG (15, "sane_open: searching currently attached scanners\n");
992 }
993 else{
994 DBG (15, "sane_open: no scanners currently attached, attaching\n");
995
996 ret = sane_get_devices(NULL,0);
997 if(ret != SANE_STATUS_GOOD){
998 return ret;
999 }
1000 }
1001
1002 if(name[0] == 0){
1003 DBG (15, "sane_open: no device requested, using default\n");
1004 s = scanner_devList;
1005 }
1006 else{
1007 DBG (15, "sane_open: device %s requested, attaching\n", name);
1008
1009 for (dev = scanner_devList; dev; dev = dev->next) {
1010 if (strcmp (dev->sane.name, name) == 0) {
1011 s = dev;
1012 break;
1013 }
1014 }
1015 }
1016
1017 if (!s) {
1018 DBG (5, "sane_open: no device found\n");
1019 return SANE_STATUS_INVAL;
1020 }
1021
1022 DBG (15, "sane_open: device %s found\n", s->sane.name);
1023
1024 *handle = s;
1025
1026 /* connect the fd so we can talk to scanner */
1027 ret = connect_fd(s);
1028 if(ret != SANE_STATUS_GOOD){
1029 return ret;
1030 }
1031
1032 DBG (10, "sane_open: finish\n");
1033
1034 return SANE_STATUS_GOOD;
1035 }
1036
1037 /*
1038 * @@ Section 3 - SANE Options functions
1039 */
1040
1041 /*
1042 * Returns the options we know.
1043 *
1044 * From the SANE spec:
1045 * This function is used to access option descriptors. The function
1046 * returns the option descriptor for option number n of the device
1047 * represented by handle h. Option number 0 is guaranteed to be a
1048 * valid option. Its value is an integer that specifies the number of
1049 * options that are available for device handle h (the count includes
1050 * option 0). If n is not a valid option index, the function returns
1051 * NULL. The returned option descriptor is guaranteed to remain valid
1052 * (and at the returned address) until the device is closed.
1053 */
1054 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)1055 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
1056 {
1057 struct scanner *s = handle;
1058 int i;
1059 SANE_Option_Descriptor *opt = &s->opt[option];
1060
1061 DBG (20, "sane_get_option_descriptor: %d\n", option);
1062
1063 if ((unsigned) option >= NUM_OPTIONS)
1064 return NULL;
1065
1066 /* "Mode" group -------------------------------------------------------- */
1067 if(option==OPT_MODE_GROUP){
1068 opt->title = "Scan Mode";
1069 opt->desc = "";
1070 opt->type = SANE_TYPE_GROUP;
1071 opt->constraint_type = SANE_CONSTRAINT_NONE;
1072 }
1073
1074 /* source */
1075 else if(option==OPT_SOURCE){
1076 i=0;
1077 if(s->has_fb){
1078 s->source_list[i++]=STRING_FLATBED;
1079 }
1080 if(s->has_adf){
1081 s->source_list[i++]=STRING_ADFFRONT;
1082 if(s->has_adf_duplex){
1083 s->source_list[i++]=STRING_ADFBACK;
1084 s->source_list[i++]=STRING_ADFDUPLEX;
1085 }
1086 }
1087 s->source_list[i]=NULL;
1088
1089 opt->name = SANE_NAME_SCAN_SOURCE;
1090 opt->title = SANE_TITLE_SCAN_SOURCE;
1091 opt->desc = SANE_DESC_SCAN_SOURCE;
1092 opt->type = SANE_TYPE_STRING;
1093 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
1094 opt->constraint.string_list = s->source_list;
1095 opt->size = maxStringSize (opt->constraint.string_list);
1096 if(i > 1){
1097 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1098 }
1099 }
1100
1101 /* scan mode */
1102 else if(option==OPT_MODE){
1103 i=0;
1104 s->mode_list[i++]=STRING_LINEART;
1105 s->mode_list[i++]=STRING_GRAYSCALE;
1106 s->mode_list[i++]=STRING_COLOR;
1107 s->mode_list[i]=NULL;
1108
1109 opt->name = SANE_NAME_SCAN_MODE;
1110 opt->title = SANE_TITLE_SCAN_MODE;
1111 opt->desc = SANE_DESC_SCAN_MODE;
1112 opt->type = SANE_TYPE_STRING;
1113 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
1114 opt->constraint.string_list = s->mode_list;
1115 opt->size = maxStringSize (opt->constraint.string_list);
1116 if(i > 1){
1117 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1118 }
1119 }
1120
1121 else if(option==OPT_RES){
1122 opt->name = SANE_NAME_SCAN_RESOLUTION;
1123 opt->title = SANE_TITLE_SCAN_RESOLUTION;
1124 opt->desc = SANE_DESC_SCAN_RESOLUTION;
1125 opt->type = SANE_TYPE_INT;
1126 opt->unit = SANE_UNIT_DPI;
1127 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1128
1129 s->res_range.min = s->min_res;
1130 s->res_range.max = s->max_res;
1131 s->res_range.quant = 1;
1132 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1133 opt->constraint.range = &s->res_range;
1134 }
1135
1136 /* "Geometry" group ---------------------------------------------------- */
1137 if(option==OPT_GEOMETRY_GROUP){
1138 opt->name = SANE_NAME_GEOMETRY;
1139 opt->title = SANE_TITLE_GEOMETRY;
1140 opt->desc = SANE_DESC_GEOMETRY;
1141 opt->type = SANE_TYPE_GROUP;
1142 opt->constraint_type = SANE_CONSTRAINT_NONE;
1143 }
1144
1145 /* top-left x */
1146 if(option==OPT_TL_X){
1147 /* values stored in 1200 dpi units */
1148 /* must be converted to MM for sane */
1149 s->tl_x_range.min = SCANNER_UNIT_TO_FIXED_MM(0);
1150 s->tl_x_range.max = SCANNER_UNIT_TO_FIXED_MM(MAX(0, get_page_width(s)-s->min_x));
1151 s->tl_x_range.quant = MM_PER_UNIT_FIX;
1152
1153 opt->name = SANE_NAME_SCAN_TL_X;
1154 opt->title = SANE_TITLE_SCAN_TL_X;
1155 opt->desc = SANE_DESC_SCAN_TL_X;
1156 opt->type = SANE_TYPE_FIXED;
1157 opt->unit = SANE_UNIT_MM;
1158 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1159 opt->constraint.range = &(s->tl_x_range);
1160 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1161 opt->cap = SANE_CAP_INACTIVE;
1162 }
1163
1164 /* top-left y */
1165 if(option==OPT_TL_Y){
1166 /* values stored in 1200 dpi units */
1167 /* must be converted to MM for sane */
1168 s->tl_y_range.min = SCANNER_UNIT_TO_FIXED_MM(0);
1169 s->tl_y_range.max = SCANNER_UNIT_TO_FIXED_MM(MAX(0, get_page_height(s)-s->min_y));
1170 s->tl_y_range.quant = MM_PER_UNIT_FIX;
1171
1172 opt->name = SANE_NAME_SCAN_TL_Y;
1173 opt->title = SANE_TITLE_SCAN_TL_Y;
1174 opt->desc = SANE_DESC_SCAN_TL_Y;
1175 opt->type = SANE_TYPE_FIXED;
1176 opt->unit = SANE_UNIT_MM;
1177 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1178 opt->constraint.range = &(s->tl_y_range);
1179 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1180 }
1181
1182 /* bottom-right x */
1183 if(option==OPT_BR_X){
1184 /* values stored in 1200 dpi units */
1185 /* must be converted to MM for sane */
1186 s->br_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x);
1187 s->br_x_range.max = SCANNER_UNIT_TO_FIXED_MM(MAX(s->min_x, get_page_width(s)));
1188 s->br_x_range.quant = MM_PER_UNIT_FIX;
1189
1190 opt->name = SANE_NAME_SCAN_BR_X;
1191 opt->title = SANE_TITLE_SCAN_BR_X;
1192 opt->desc = SANE_DESC_SCAN_BR_X;
1193 opt->type = SANE_TYPE_FIXED;
1194 opt->unit = SANE_UNIT_MM;
1195 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1196 opt->constraint.range = &(s->br_x_range);
1197 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1198 opt->cap = SANE_CAP_INACTIVE;
1199 }
1200
1201 /* bottom-right y */
1202 if(option==OPT_BR_Y){
1203 /* values stored in 1200 dpi units */
1204 /* must be converted to MM for sane */
1205 s->br_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y);
1206 s->br_y_range.max = SCANNER_UNIT_TO_FIXED_MM(MAX(s->min_y, get_page_height(s)));
1207 s->br_y_range.quant = MM_PER_UNIT_FIX;
1208
1209 opt->name = SANE_NAME_SCAN_BR_Y;
1210 opt->title = SANE_TITLE_SCAN_BR_Y;
1211 opt->desc = SANE_DESC_SCAN_BR_Y;
1212 opt->type = SANE_TYPE_FIXED;
1213 opt->unit = SANE_UNIT_MM;
1214 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1215 opt->constraint.range = &(s->br_y_range);
1216 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1217 opt->cap = SANE_CAP_INACTIVE;
1218 }
1219
1220 /* page width */
1221 if(option==OPT_PAGE_WIDTH){
1222 /* values stored in 1200 dpi units */
1223 /* must be converted to MM for sane */
1224 s->paper_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x);
1225 s->paper_x_range.max = SCANNER_UNIT_TO_FIXED_MM(s->max_x);
1226 s->paper_x_range.quant = MM_PER_UNIT_FIX;
1227
1228 opt->name = SANE_NAME_PAGE_WIDTH;
1229 opt->title = SANE_TITLE_PAGE_WIDTH;
1230 opt->desc = SANE_DESC_PAGE_WIDTH;
1231 opt->type = SANE_TYPE_FIXED;
1232 opt->unit = SANE_UNIT_MM;
1233 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1234 opt->constraint.range = &s->paper_x_range;
1235
1236 if(s->has_adf){
1237 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1238 if(s->source == SOURCE_FLATBED){
1239 opt->cap |= SANE_CAP_INACTIVE;
1240 }
1241 }
1242 else{
1243 opt->cap = SANE_CAP_INACTIVE;
1244 }
1245 }
1246
1247 /* page height */
1248 if(option==OPT_PAGE_HEIGHT){
1249 /* values stored in 1200 dpi units */
1250 /* must be converted to MM for sane */
1251 s->paper_y_range.min = SCANNER_UNIT_TO_FIXED_MM(0);
1252 s->paper_y_range.max = SCANNER_UNIT_TO_FIXED_MM(s->max_y);
1253 s->paper_y_range.quant = MM_PER_UNIT_FIX;
1254
1255 opt->name = SANE_NAME_PAGE_HEIGHT;
1256 opt->title = SANE_TITLE_PAGE_HEIGHT;
1257 opt->desc = "Specifies the height of the media, 0 will auto-detect.";
1258 opt->type = SANE_TYPE_FIXED;
1259 opt->unit = SANE_UNIT_MM;
1260 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1261 opt->constraint.range = &s->paper_y_range;
1262
1263 if(s->has_adf){
1264 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1265 if(s->source == SOURCE_FLATBED){
1266 opt->cap |= SANE_CAP_INACTIVE;
1267 }
1268 }
1269 else{
1270 opt->cap = SANE_CAP_INACTIVE;
1271 }
1272 }
1273
1274 /* "Enhancement" group ------------------------------------------------- */
1275 if(option==OPT_ENHANCEMENT_GROUP){
1276 opt->name = SANE_NAME_ENHANCEMENT;
1277 opt->title = SANE_TITLE_ENHANCEMENT;
1278 opt->desc = SANE_DESC_ENHANCEMENT;
1279 opt->type = SANE_TYPE_GROUP;
1280 opt->constraint_type = SANE_CONSTRAINT_NONE;
1281 }
1282
1283 /* brightness */
1284 if(option==OPT_BRIGHTNESS){
1285 opt->name = SANE_NAME_BRIGHTNESS;
1286 opt->title = SANE_TITLE_BRIGHTNESS;
1287 opt->desc = SANE_DESC_BRIGHTNESS;
1288 opt->type = SANE_TYPE_INT;
1289 opt->unit = SANE_UNIT_NONE;
1290
1291 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1292 opt->constraint.range = &s->brightness_range;
1293 s->brightness_range.quant=1;
1294 s->brightness_range.min=-127;
1295 s->brightness_range.max=127;
1296
1297 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1298 }
1299
1300 /* contrast */
1301 if(option==OPT_CONTRAST){
1302 opt->name = SANE_NAME_CONTRAST;
1303 opt->title = SANE_TITLE_CONTRAST;
1304 opt->desc = SANE_DESC_CONTRAST;
1305 opt->type = SANE_TYPE_INT;
1306 opt->unit = SANE_UNIT_NONE;
1307
1308 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1309 opt->constraint.range = &s->contrast_range;
1310 s->contrast_range.quant=1;
1311 s->contrast_range.min=-127;
1312 s->contrast_range.max=127;
1313
1314 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1315 }
1316
1317 /* gamma */
1318 if(option==OPT_GAMMA){
1319 opt->name = "gamma";
1320 opt->title = "Gamma function exponent";
1321 opt->desc = "Changes intensity of midtones";
1322 opt->type = SANE_TYPE_FIXED;
1323 opt->unit = SANE_UNIT_NONE;
1324
1325 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1326 opt->constraint.range = &s->gamma_range;
1327
1328 /* value ranges from .3 to 5, should be log scale? */
1329 s->gamma_range.quant=SANE_FIX(0.01);
1330 s->gamma_range.min=SANE_FIX(0.3);
1331 s->gamma_range.max=SANE_FIX(5);
1332
1333 /*if (s->num_download_gamma){
1334 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1335 }*/
1336
1337 opt->cap = SANE_CAP_INACTIVE;
1338 }
1339
1340 /*threshold*/
1341 if(option==OPT_THRESHOLD){
1342 opt->name = SANE_NAME_THRESHOLD;
1343 opt->title = SANE_TITLE_THRESHOLD;
1344 opt->desc = SANE_DESC_THRESHOLD;
1345 opt->type = SANE_TYPE_INT;
1346 opt->unit = SANE_UNIT_NONE;
1347 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1348 opt->constraint.range = &s->threshold_range;
1349 s->threshold_range.min=0;
1350 s->threshold_range.max=255;
1351 s->threshold_range.quant=1;
1352
1353 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1354 if(s->mode != MODE_LINEART){
1355 opt->cap |= SANE_CAP_INACTIVE;
1356 }
1357 }
1358
1359 if(option==OPT_THRESHOLD_CURVE){
1360 opt->name = "threshold-curve";
1361 opt->title = "Threshold curve";
1362 opt->desc = "Dynamic threshold curve, from light to dark, normally 50-65";
1363 opt->type = SANE_TYPE_INT;
1364 opt->unit = SANE_UNIT_NONE;
1365
1366 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1367 opt->constraint.range = &s->threshold_curve_range;
1368 s->threshold_curve_range.min=0;
1369 s->threshold_curve_range.max=127;
1370 s->threshold_curve_range.quant=1;
1371
1372 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1373 if(s->mode != MODE_LINEART){
1374 opt->cap |= SANE_CAP_INACTIVE;
1375 }
1376 }
1377
1378 /* "Sensor" group ------------------------------------------------------ */
1379 if(option==OPT_SENSOR_GROUP){
1380 opt->name = SANE_NAME_SENSORS;
1381 opt->title = SANE_TITLE_SENSORS;
1382 opt->desc = SANE_DESC_SENSORS;
1383 opt->type = SANE_TYPE_GROUP;
1384 opt->constraint_type = SANE_CONSTRAINT_NONE;
1385
1386 /*flaming hack to get scanimage to hide group*/
1387 if (!s->has_adf)
1388 opt->type = SANE_TYPE_BOOL;
1389 }
1390
1391 if(option==OPT_SCAN_SW){
1392 opt->name = SANE_NAME_SCAN;
1393 opt->title = SANE_TITLE_SCAN;
1394 opt->desc = SANE_DESC_SCAN;
1395 opt->type = SANE_TYPE_BOOL;
1396 opt->unit = SANE_UNIT_NONE;
1397 if (s->has_adf)
1398 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
1399 else
1400 opt->cap = SANE_CAP_INACTIVE;
1401 }
1402
1403 if(option==OPT_HOPPER){
1404 opt->name = SANE_NAME_PAGE_LOADED;
1405 opt->title = SANE_TITLE_PAGE_LOADED;
1406 opt->desc = SANE_DESC_PAGE_LOADED;
1407 opt->type = SANE_TYPE_BOOL;
1408 opt->unit = SANE_UNIT_NONE;
1409 if (s->has_adf)
1410 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
1411 else
1412 opt->cap = SANE_CAP_INACTIVE;
1413 }
1414
1415 if(option==OPT_TOP){
1416 opt->name = "top-edge";
1417 opt->title = "Top edge";
1418 opt->desc = "Paper is pulled partly into adf";
1419 opt->type = SANE_TYPE_BOOL;
1420 opt->unit = SANE_UNIT_NONE;
1421 if (s->has_adf)
1422 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
1423 else
1424 opt->cap = SANE_CAP_INACTIVE;
1425 }
1426
1427 if(option==OPT_ADF_OPEN){
1428 opt->name = SANE_NAME_COVER_OPEN;
1429 opt->title = SANE_TITLE_COVER_OPEN;
1430 opt->desc = SANE_DESC_COVER_OPEN;
1431 opt->type = SANE_TYPE_BOOL;
1432 opt->unit = SANE_UNIT_NONE;
1433 if (s->has_adf)
1434 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
1435 else
1436 opt->cap = SANE_CAP_INACTIVE;
1437 }
1438
1439 if(option==OPT_SLEEP){
1440 opt->name = "power-save";
1441 opt->title = "Power saving";
1442 opt->desc = "Scanner in power saving mode";
1443 opt->type = SANE_TYPE_BOOL;
1444 opt->unit = SANE_UNIT_NONE;
1445 if (s->has_adf)
1446 opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
1447 else
1448 opt->cap = SANE_CAP_INACTIVE;
1449 }
1450
1451 return opt;
1452 }
1453
1454 /**
1455 * Gets or sets an option value.
1456 *
1457 * From the SANE spec:
1458 * This function is used to set or inquire the current value of option
1459 * number n of the device represented by handle h. The manner in which
1460 * the option is controlled is specified by parameter action. The
1461 * possible values of this parameter are described in more detail
1462 * below. The value of the option is passed through argument val. It
1463 * is a pointer to the memory that holds the option value. The memory
1464 * area pointed to by v must be big enough to hold the entire option
1465 * value (determined by member size in the corresponding option
1466 * descriptor).
1467 *
1468 * The only exception to this rule is that when setting the value of a
1469 * string option, the string pointed to by argument v may be shorter
1470 * since the backend will stop reading the option value upon
1471 * encountering the first NUL terminator in the string. If argument i
1472 * is not NULL, the value of *i will be set to provide details on how
1473 * well the request has been met.
1474 */
1475 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int * info)1476 sane_control_option (SANE_Handle handle, SANE_Int option,
1477 SANE_Action action, void *val, SANE_Int * info)
1478 {
1479 struct scanner *s = (struct scanner *) handle;
1480 SANE_Int dummy = 0;
1481
1482 /* Make sure that all those statements involving *info cannot break (better
1483 * than having to do "if (info) ..." everywhere!)
1484 */
1485 if (info == 0)
1486 info = &dummy;
1487
1488 if (option >= NUM_OPTIONS) {
1489 DBG (5, "sane_control_option: %d too big\n", option);
1490 return SANE_STATUS_INVAL;
1491 }
1492
1493 if (!SANE_OPTION_IS_ACTIVE (s->opt[option].cap)) {
1494 DBG (5, "sane_control_option: %d inactive\n", option);
1495 return SANE_STATUS_INVAL;
1496 }
1497
1498 /*
1499 * SANE_ACTION_GET_VALUE: We have to find out the current setting and
1500 * return it in a human-readable form (often, text).
1501 */
1502 if (action == SANE_ACTION_GET_VALUE) {
1503 SANE_Word * val_p = (SANE_Word *) val;
1504
1505 DBG (20, "sane_control_option: get value for '%s' (%d)\n", s->opt[option].name,option);
1506
1507 switch (option) {
1508
1509 case OPT_NUM_OPTS:
1510 *val_p = NUM_OPTIONS;
1511 return SANE_STATUS_GOOD;
1512
1513 case OPT_SOURCE:
1514 if(s->source == SOURCE_FLATBED){
1515 strcpy (val, STRING_FLATBED);
1516 }
1517 else if(s->source == SOURCE_ADF_FRONT){
1518 strcpy (val, STRING_ADFFRONT);
1519 }
1520 else if(s->source == SOURCE_ADF_BACK){
1521 strcpy (val, STRING_ADFBACK);
1522 }
1523 else if(s->source == SOURCE_ADF_DUPLEX){
1524 strcpy (val, STRING_ADFDUPLEX);
1525 }
1526 else{
1527 DBG(5,"missing option val for source\n");
1528 }
1529 return SANE_STATUS_GOOD;
1530
1531 case OPT_MODE:
1532 if(s->mode == MODE_LINEART){
1533 strcpy (val, STRING_LINEART);
1534 }
1535 else if(s->mode == MODE_GRAYSCALE){
1536 strcpy (val, STRING_GRAYSCALE);
1537 }
1538 else if(s->mode == MODE_COLOR){
1539 strcpy (val, STRING_COLOR);
1540 }
1541 return SANE_STATUS_GOOD;
1542
1543 case OPT_RES:
1544 *val_p = s->resolution;
1545 return SANE_STATUS_GOOD;
1546
1547 case OPT_TL_X:
1548 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->tl_x);
1549 return SANE_STATUS_GOOD;
1550
1551 case OPT_TL_Y:
1552 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->tl_y);
1553 return SANE_STATUS_GOOD;
1554
1555 case OPT_BR_X:
1556 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->br_x);
1557 return SANE_STATUS_GOOD;
1558
1559 case OPT_BR_Y:
1560 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->br_y);
1561 return SANE_STATUS_GOOD;
1562
1563 case OPT_PAGE_WIDTH:
1564 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->page_width);
1565 return SANE_STATUS_GOOD;
1566
1567 case OPT_PAGE_HEIGHT:
1568 *val_p = SCANNER_UNIT_TO_FIXED_MM(s->page_height);
1569 return SANE_STATUS_GOOD;
1570
1571 case OPT_BRIGHTNESS:
1572 *val_p = s->brightness;
1573 return SANE_STATUS_GOOD;
1574
1575 case OPT_CONTRAST:
1576 *val_p = s->contrast;
1577 return SANE_STATUS_GOOD;
1578
1579 case OPT_GAMMA:
1580 *val_p = SANE_FIX(s->gamma);
1581 return SANE_STATUS_GOOD;
1582
1583 case OPT_THRESHOLD:
1584 *val_p = s->threshold;
1585 return SANE_STATUS_GOOD;
1586
1587 case OPT_THRESHOLD_CURVE:
1588 *val_p = s->threshold_curve;
1589 return SANE_STATUS_GOOD;
1590
1591 /* Sensor Group */
1592 case OPT_SCAN_SW:
1593 get_hardware_status(s);
1594 *val_p = s->hw_scan_sw;
1595 return SANE_STATUS_GOOD;
1596
1597 case OPT_HOPPER:
1598 get_hardware_status(s);
1599 *val_p = s->hw_hopper;
1600 return SANE_STATUS_GOOD;
1601
1602 case OPT_TOP:
1603 get_hardware_status(s);
1604 *val_p = s->hw_top;
1605 return SANE_STATUS_GOOD;
1606
1607 case OPT_ADF_OPEN:
1608 get_hardware_status(s);
1609 *val_p = s->hw_adf_open;
1610 return SANE_STATUS_GOOD;
1611
1612 case OPT_SLEEP:
1613 get_hardware_status(s);
1614 *val_p = s->hw_sleep;
1615 return SANE_STATUS_GOOD;
1616 }
1617 }
1618 else if (action == SANE_ACTION_SET_VALUE) {
1619 int tmp;
1620 SANE_Word val_c;
1621 SANE_Status status;
1622
1623 DBG (20, "sane_control_option: set value for '%s' (%d)\n", s->opt[option].name,option);
1624
1625 if ( s->started ) {
1626 DBG (5, "sane_control_option: can't set, device busy\n");
1627 return SANE_STATUS_DEVICE_BUSY;
1628 }
1629
1630 if (!SANE_OPTION_IS_SETTABLE (s->opt[option].cap)) {
1631 DBG (5, "sane_control_option: not settable\n");
1632 return SANE_STATUS_INVAL;
1633 }
1634
1635 status = sanei_constrain_value (s->opt + option, val, info);
1636 if (status != SANE_STATUS_GOOD) {
1637 DBG (5, "sane_control_option: bad value\n");
1638 return status;
1639 }
1640
1641 /* may have been changed by constraints, so don't copy until now */
1642 val_c = *(SANE_Word *)val;
1643
1644 /*
1645 * Note - for those options which can assume one of a list of
1646 * valid values, we can safely assume that they will have
1647 * exactly one of those values because that's what
1648 * sanei_constrain_value does. Hence no "else: invalid" branches
1649 * below.
1650 */
1651 switch (option) {
1652
1653 /* Mode Group */
1654 case OPT_SOURCE:
1655 if (!strcmp (val, STRING_ADFFRONT)) {
1656 tmp = SOURCE_ADF_FRONT;
1657 }
1658 else if (!strcmp (val, STRING_ADFBACK)) {
1659 tmp = SOURCE_ADF_BACK;
1660 }
1661 else if (!strcmp (val, STRING_ADFDUPLEX)) {
1662 tmp = SOURCE_ADF_DUPLEX;
1663 }
1664 else{
1665 tmp = SOURCE_FLATBED;
1666 }
1667
1668 if (s->source == tmp)
1669 return SANE_STATUS_GOOD;
1670
1671 s->source = tmp;
1672 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1673 return SANE_STATUS_GOOD;
1674
1675 case OPT_MODE:
1676 if (!strcmp (val, STRING_LINEART)) {
1677 tmp = MODE_LINEART;
1678 }
1679 else if (!strcmp (val, STRING_GRAYSCALE)) {
1680 tmp = MODE_GRAYSCALE;
1681 }
1682 else{
1683 tmp = MODE_COLOR;
1684 }
1685
1686 if (tmp == s->mode)
1687 return SANE_STATUS_GOOD;
1688
1689 s->mode = tmp;
1690 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1691 return SANE_STATUS_GOOD;
1692
1693 case OPT_RES:
1694
1695 if (s->resolution == val_c)
1696 return SANE_STATUS_GOOD;
1697
1698 s->resolution = val_c;
1699
1700 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1701 return SANE_STATUS_GOOD;
1702
1703 /* Geometry Group */
1704 case OPT_TL_X:
1705 if (s->tl_x == FIXED_MM_TO_SCANNER_UNIT(val_c))
1706 return SANE_STATUS_GOOD;
1707
1708 s->tl_x = FIXED_MM_TO_SCANNER_UNIT(val_c);
1709
1710 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1711 return SANE_STATUS_GOOD;
1712
1713 case OPT_TL_Y:
1714 if (s->tl_y == FIXED_MM_TO_SCANNER_UNIT(val_c))
1715 return SANE_STATUS_GOOD;
1716
1717 s->tl_y = FIXED_MM_TO_SCANNER_UNIT(val_c);
1718
1719 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1720 return change_params(s);
1721
1722 case OPT_BR_X:
1723 if (s->br_x == FIXED_MM_TO_SCANNER_UNIT(val_c))
1724 return SANE_STATUS_GOOD;
1725
1726 s->br_x = FIXED_MM_TO_SCANNER_UNIT(val_c);
1727
1728 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1729 return SANE_STATUS_GOOD;
1730
1731 case OPT_BR_Y:
1732 if (s->br_y == FIXED_MM_TO_SCANNER_UNIT(val_c))
1733 return SANE_STATUS_GOOD;
1734
1735 s->br_y = FIXED_MM_TO_SCANNER_UNIT(val_c);
1736
1737 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1738 return SANE_STATUS_GOOD;
1739
1740 case OPT_PAGE_WIDTH:
1741 if (s->page_width == FIXED_MM_TO_SCANNER_UNIT(val_c))
1742 return SANE_STATUS_GOOD;
1743
1744 s->page_width = FIXED_MM_TO_SCANNER_UNIT(val_c);
1745 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1746 return change_params(s);
1747
1748 case OPT_PAGE_HEIGHT:
1749 if (s->page_height == FIXED_MM_TO_SCANNER_UNIT(val_c))
1750 return SANE_STATUS_GOOD;
1751
1752 s->page_height = FIXED_MM_TO_SCANNER_UNIT(val_c);
1753 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1754 return change_params(s);
1755
1756 /* Enhancement Group */
1757 case OPT_BRIGHTNESS:
1758 s->brightness = val_c;
1759 return SANE_STATUS_GOOD;
1760
1761 case OPT_CONTRAST:
1762 s->contrast = val_c;
1763 return SANE_STATUS_GOOD;
1764
1765 case OPT_GAMMA:
1766 s->gamma = SANE_UNFIX(val_c);
1767 return SANE_STATUS_GOOD;
1768
1769 case OPT_THRESHOLD:
1770 s->threshold = val_c;
1771 return SANE_STATUS_GOOD;
1772
1773 case OPT_THRESHOLD_CURVE:
1774 s->threshold_curve = val_c;
1775 return SANE_STATUS_GOOD;
1776
1777 } /* switch */
1778 } /* else */
1779
1780 return SANE_STATUS_INVAL;
1781 }
1782
1783 /* use height and width to initialize rest of transfer vals */
1784 static void
update_transfer_totals(struct transfer * t)1785 update_transfer_totals(struct transfer * t)
1786 {
1787 if (t->image == NULL) return;
1788
1789 t->total_bytes = t->line_stride * t->image->height;
1790 t->rx_bytes = 0;
1791 t->done = 0;
1792 }
1793
1794 /* each model has various settings that differ based on X resolution */
1795 /* we hard-code the list (determined from usb snoops) here */
1796 struct model_res {
1797 int model;
1798 int mode;
1799 int x_res;
1800 int y_res;
1801 int usb_power;
1802
1803 int max_x;
1804 int min_x;
1805 int max_y;
1806 int min_y;
1807
1808 int line_stride; /* byte width of 1 raw side, with padding */
1809 int plane_stride; /* byte width of 1 raw color plane, with padding */
1810 int plane_width; /* byte width of 1 raw color plane, without padding */
1811
1812 int block_height;
1813
1814 int cal_line_stride;
1815 int cal_plane_stride;
1816 int cal_plane_width;
1817
1818 unsigned char * sw_coarsecal;
1819 unsigned char * sw_finecal;
1820 unsigned char * sw_sendcal;
1821
1822 unsigned char * head_cal1;
1823 unsigned char * head_cal2;
1824 unsigned char * sw_scan;
1825
1826 };
1827
1828 static struct model_res settings[] = {
1829
1830 /*S300 AC*/
1831 /* model mode xres yres u mxx mnx mxy mny lin_s pln_s pln_w bh cls cps cpw */
1832 { MODEL_S300, MODE_COLOR, 150, 150, 0, 1296, 32, 2662, 32, 4256*3, 1480*3, 1296, 41, 8512*3, 2960*3, 2592,
1833 setWindowCoarseCal_S300_150, setWindowFineCal_S300_150,
1834 setWindowSendCal_S300_150, sendCal1Header_S300_150,
1835 sendCal2Header_S300_150, setWindowScan_S300_150 },
1836
1837 { MODEL_S300, MODE_COLOR, 225, 200, 0, 1944, 32, 3993, 32, 6144*3, 2100*3, 1944, 28, 8192*3, 2800*3, 2592,
1838 setWindowCoarseCal_S300_225, setWindowFineCal_S300_225,
1839 setWindowSendCal_S300_225, sendCal1Header_S300_225,
1840 sendCal2Header_S300_225, setWindowScan_S300_225 },
1841
1842 { MODEL_S300, MODE_COLOR, 300, 300, 0, 2592, 32, 5324, 32, 8192*3, 2800*3, 2592, 21, 8192*3, 2800*3, 2592,
1843 setWindowCoarseCal_S300_300, setWindowFineCal_S300_300,
1844 setWindowSendCal_S300_300, sendCal1Header_S300_300,
1845 sendCal2Header_S300_300, setWindowScan_S300_300 },
1846
1847 { MODEL_S300, MODE_COLOR, 600, 600, 0, 5184, 32, 10648, 32, 16064*3, 5440*3, 5184, 10, 16064*3, 5440*3, 5184,
1848 setWindowCoarseCal_S300_600, setWindowFineCal_S300_600,
1849 setWindowSendCal_S300_600, sendCal1Header_S300_600,
1850 sendCal2Header_S300_600, setWindowScan_S300_600 },
1851
1852 /*S300 USB*/
1853 /* model mode xres yres u mxx mnx mxy mny lin_s pln_s pln_w bh cls cps cpw */
1854 { MODEL_S300, MODE_COLOR, 150, 150, 1, 1296, 32, 2662, 32, 7216*3, 2960*3, 1296, 24, 14432*3, 5920*3, 2592,
1855 setWindowCoarseCal_S300_150_U, setWindowFineCal_S300_150_U,
1856 setWindowSendCal_S300_150_U, sendCal1Header_S300_150_U,
1857 sendCal2Header_S300_150_U, setWindowScan_S300_150_U },
1858
1859 { MODEL_S300, MODE_COLOR, 225, 200, 1, 1944, 32, 3993, 32, 10584*3, 4320*3, 1944, 16, 14112*3, 5760*3, 2592,
1860 setWindowCoarseCal_S300_225_U, setWindowFineCal_S300_225_U,
1861 setWindowSendCal_S300_225_U, sendCal1Header_S300_225_U,
1862 sendCal2Header_S300_225_U, setWindowScan_S300_225_U },
1863
1864 { MODEL_S300, MODE_COLOR, 300, 300, 1, 2592, 32, 5324, 32, 15872*3, 6640*3, 2592, 11, 15872*3, 6640*3, 2592,
1865 setWindowCoarseCal_S300_300_U, setWindowFineCal_S300_300_U,
1866 setWindowSendCal_S300_300_U, sendCal1Header_S300_300_U,
1867 sendCal2Header_S300_300_U, setWindowScan_S300_300_U },
1868
1869 { MODEL_S300, MODE_COLOR, 600, 600, 1, 5184, 32, 10648, 32, 16064*3, 5440*3, 5184, 10, 16064*3, 5440*3, 5184,
1870 setWindowCoarseCal_S300_600, setWindowFineCal_S300_600,
1871 setWindowSendCal_S300_600, sendCal1Header_S300_600,
1872 sendCal2Header_S300_600, setWindowScan_S300_600 },
1873
1874 /*S1300i AC*/
1875 /* model mode xres yres u mxx mnx mxy mny lin_s pln_s pln_w bh cls cps cpw */
1876 { MODEL_S1300i, MODE_COLOR, 150, 150, 0, 1296, 32, 2662, 32, 4016*3, 1360*3, 1296, 43, 8032*3, 2720*3, 2592,
1877 setWindowCoarseCal_S1300i_150, setWindowFineCal_S1300i_150,
1878 setWindowSendCal_S1300i_150, sendCal1Header_S1300i_150,
1879 sendCal2Header_S1300i_150, setWindowScan_S1300i_150 },
1880
1881 { MODEL_S1300i, MODE_COLOR, 225, 200, 0, 1944, 32, 3993, 32, 6072*3, 2063*3, 1944, 28, 8096*3, 2752*3, 2592,
1882 setWindowCoarseCal_S1300i_225, setWindowFineCal_S1300i_225,
1883 setWindowSendCal_S1300i_225, sendCal1Header_S1300i_225,
1884 sendCal2Header_S1300i_225, setWindowScan_S1300i_225 },
1885
1886 { MODEL_S1300i, MODE_COLOR, 300, 300, 0, 2592, 32, 5324, 32, 8096*3, 2751*3, 2592, 21, 8096*3, 2752*3, 2592,
1887 setWindowCoarseCal_S1300i_300, setWindowFineCal_S1300i_300,
1888 setWindowSendCal_S1300i_300, sendCal1Header_S1300i_300,
1889 sendCal2Header_S1300i_300, setWindowScan_S1300i_300 },
1890
1891 /*NOTE: S1300i uses S300 data blocks for remainder*/
1892 { MODEL_S1300i, MODE_COLOR, 600, 600, 0, 5184, 32, 10648, 32, 16064*3, 5440*3, 5184, 10, 16064*3, 5440*3, 5184,
1893 setWindowCoarseCal_S300_600, setWindowFineCal_S300_600,
1894 setWindowSendCal_S300_600, sendCal1Header_S300_600,
1895 sendCal2Header_S300_600, setWindowScan_S300_600 },
1896
1897 /*S1300i USB*/
1898 /* model mode xres yres u mxx mnx mxy mny lin_s pln_s pln_w bh cls cps cpw */
1899 { MODEL_S1300i, MODE_COLOR, 150, 150, 1, 1296, 32, 2662, 32, 7216*3, 2960*3, 1296, 24, 14432*3, 5920*3, 2592,
1900 setWindowCoarseCal_S300_150_U, setWindowFineCal_S300_150_U,
1901 setWindowSendCal_S300_150_U, sendCal1Header_S1300i_USB,
1902 sendCal2Header_S1300i_USB, setWindowScan_S300_150_U },
1903
1904 { MODEL_S1300i, MODE_COLOR, 225, 200, 1, 1944, 32, 3993, 32, 10584*3, 4320*3, 1944, 16, 14112*3, 5760*3, 2592,
1905 setWindowCoarseCal_S300_225_U, setWindowFineCal_S300_225_U,
1906 setWindowSendCal_S300_225_U, sendCal1Header_S1300i_USB,
1907 sendCal2Header_S1300i_USB, setWindowScan_S300_225_U },
1908
1909 { MODEL_S1300i, MODE_COLOR, 300, 300, 1, 2592, 32, 5324, 32, 15872*3, 6640*3, 2592, 11, 15872*3, 6640*3, 2592,
1910 setWindowCoarseCal_S300_300_U, setWindowFineCal_S300_300_U,
1911 setWindowSendCal_S300_300_U, sendCal1Header_S1300i_USB,
1912 sendCal2Header_S1300i_USB, setWindowScan_S300_300_U },
1913
1914 { MODEL_S1300i, MODE_COLOR, 600, 600, 1, 5184, 32, 10648, 32, 16064*3, 5440*3, 5184, 10, 16064*3, 5440*3, 5184,
1915 setWindowCoarseCal_S300_600, setWindowFineCal_S300_600,
1916 setWindowSendCal_S300_600, sendCal1Header_S1300i_USB,
1917 sendCal2Header_S1300i_USB, setWindowScan_S300_600 },
1918
1919 /*fi-60F/65F GRAY */
1920 /* model mode xres yres u mxx mnx mxy mny lin_s pln_s pln_w bh cls cps cpw */
1921 /* disabled until calibration code supports grayscale
1922 { MODEL_FI60F | MODEL_FI65F, MODE_GRAYSCALE, 300, 300, 0, 1296, 32, 1749, 32, 1440, 480, 432, 364, 2400*3, 958*3, 432,
1923 setWindowCoarseCal_FI60F_300, setWindowFineCal_FI60F_300,
1924 setWindowSendCal_FI60F_300, sendCal1Header_FI60F_300,
1925 sendCal2Header_FI60F_300, setWindowScan_FI60F_300_g },
1926
1927 { MODEL_FI60F | MODEL_FI65F, MODE_GRAYSCALE, 600, 400, 0, 2592, 32, 2332, 32, 2592, 864, 864, 202, 2848*3, 978*3, 864,
1928 setWindowCoarseCal_FI60F_600, setWindowFineCal_FI60F_600,
1929 setWindowSendCal_FI60F_600, sendCal1Header_FI60F_600,
1930 sendCal2Header_FI60F_600, setWindowScan_FI60F_400_g },
1931
1932 { MODEL_FI60F | MODEL_FI65F, MODE_GRAYSCALE, 600, 600, 0, 2592, 32, 3498, 32, 2592, 864, 864, 202, 2848*3, 978*3, 864,
1933 setWindowCoarseCal_FI60F_600, setWindowFineCal_FI60F_600,
1934 setWindowSendCal_FI60F_600, sendCal1Header_FI60F_600,
1935 sendCal2Header_FI60F_600, setWindowScan_FI60F_600_g },
1936 */
1937
1938 /*fi-60F/65F*/
1939 /* model mode xres yres u mxx mnx mxy mny lin_s pln_s pln_w bh cls cps cpw */
1940 { MODEL_FI60F | MODEL_FI65F, MODE_COLOR, 300, 150, 0, 1296, 32, 875, 32, 2400*3, 958*3, 432, 72, 2400*3, 958*3, 432,
1941 setWindowCoarseCal_FI60F_300, setWindowFineCal_FI60F_300,
1942 setWindowSendCal_FI60F_300, sendCal1Header_FI60F_300,
1943 sendCal2Header_FI60F_300, setWindowScan_FI60F_150 },
1944
1945 { MODEL_FI60F | MODEL_FI65F, MODE_COLOR, 300, 200, 0, 1296, 32, 1166, 32, 2400*3, 958*3, 432, 72, 2400*3, 958*3, 432,
1946 setWindowCoarseCal_FI60F_300, setWindowFineCal_FI60F_300,
1947 setWindowSendCal_FI60F_300, sendCal1Header_FI60F_300,
1948 sendCal2Header_FI60F_300, setWindowScan_FI60F_200 },
1949
1950 { MODEL_FI60F | MODEL_FI65F, MODE_COLOR, 300, 300, 0, 1296, 32, 1749, 32, 2400*3, 958*3, 432, 72, 2400*3, 958*3, 432,
1951 setWindowCoarseCal_FI60F_300, setWindowFineCal_FI60F_300,
1952 setWindowSendCal_FI60F_300, sendCal1Header_FI60F_300,
1953 sendCal2Header_FI60F_300, setWindowScan_FI60F_300 },
1954
1955 { MODEL_FI60F | MODEL_FI65F, MODE_COLOR, 600, 400, 0, 2592, 32, 2332, 32, 2848*3, 978*3, 864, 61, 2848*3, 978*3, 864,
1956 setWindowCoarseCal_FI60F_600, setWindowFineCal_FI60F_600,
1957 setWindowSendCal_FI60F_600, sendCal1Header_FI60F_600,
1958 sendCal2Header_FI60F_600, setWindowScan_FI60F_400 },
1959
1960 { MODEL_FI60F | MODEL_FI65F, MODE_COLOR, 600, 600, 0, 2592, 32, 3498, 32, 2848*3, 978*3, 864, 61, 2848*3, 978*3, 864,
1961 setWindowCoarseCal_FI60F_600, setWindowFineCal_FI60F_600,
1962 setWindowSendCal_FI60F_600, sendCal1Header_FI60F_600,
1963 sendCal2Header_FI60F_600, setWindowScan_FI60F_600 },
1964
1965 /*S1100 USB*/
1966 /* model mode xres yres u mxx mnx mxy mny lin_s pln_s pln_w bh cls cps cpw */
1967 { MODEL_S1100, MODE_COLOR, 300, 300, 1, 2592, 32, 5324, 32, 8912, 3160, 2592, 58, 8912, 3160, 2592,
1968 setWindowCoarseCal_S1100_300_U, setWindowFineCal_S1100_300_U,
1969 setWindowSendCal_S1100_300_U, sendCal1Header_S1100_300_U,
1970 sendCal2Header_S1100_300_U, setWindowScan_S1100_300_U },
1971
1972 { MODEL_S1100, MODE_COLOR, 600, 600, 1, 5184, 32, 10648, 32, 15904, 5360, 5184, 32, 15904, 5360, 5184,
1973 setWindowCoarseCal_S1100_600_U, setWindowFineCal_S1100_600_U,
1974 setWindowSendCal_S1100_600_U, sendCal1Header_S1100_600_U,
1975 sendCal2Header_S1100_600_U, setWindowScan_S1100_600_U },
1976
1977 { MODEL_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1978 NULL, NULL, NULL, NULL, NULL, NULL },
1979
1980 };
1981
1982 /*
1983 * clean up scanner struct vals when user changes mode, res, etc
1984 */
1985 static SANE_Status
change_params(struct scanner *s)1986 change_params(struct scanner *s)
1987 {
1988 SANE_Status ret = SANE_STATUS_GOOD;
1989
1990 int img_heads, img_pages, width;
1991 int i=0;
1992
1993 DBG (10, "change_params: start\n");
1994
1995 do {
1996 if(settings[i].model & s->model
1997 && settings[i].mode <= s->mode
1998 && settings[i].x_res >= s->resolution
1999 && settings[i].y_res >= s->resolution
2000 && settings[i].usb_power == s->usb_power
2001 ){
2002 break;
2003 }
2004 i++;
2005 } while (settings[i].model);
2006
2007 if (!settings[i].model){
2008 return SANE_STATUS_INVAL;
2009 }
2010
2011 /*1200 dpi*/
2012 s->max_x = PIX_TO_SCANNER_UNIT( settings[i].max_x, settings[i].x_res );
2013 s->min_x = PIX_TO_SCANNER_UNIT( settings[i].min_x, settings[i].x_res );
2014 s->max_y = PIX_TO_SCANNER_UNIT( settings[i].max_y, settings[i].y_res );
2015 s->min_y = PIX_TO_SCANNER_UNIT( settings[i].min_y, settings[i].y_res );
2016
2017 /*current dpi*/
2018 s->setWindowCoarseCal = settings[i].sw_coarsecal;
2019 s->setWindowCoarseCalLen = SET_WINDOW_LEN;
2020
2021 s->setWindowFineCal = settings[i].sw_finecal;
2022 s->setWindowFineCalLen = SET_WINDOW_LEN;
2023
2024 s->setWindowSendCal = settings[i].sw_sendcal;
2025 s->setWindowSendCalLen = SET_WINDOW_LEN;
2026
2027 s->sendCal1Header = settings[i].head_cal1;
2028 s->sendCal1HeaderLen = 14;
2029
2030 s->sendCal2Header = settings[i].head_cal2;
2031 s->sendCal2HeaderLen = 7;
2032
2033 s->setWindowScan = settings[i].sw_scan;
2034 s->setWindowScanLen = SET_WINDOW_LEN;
2035
2036 if (s->model == MODEL_S300 || s->model == MODEL_S1300i)
2037 {
2038 img_heads = 1; /* image width is the same as the plane width on the S300 */
2039 img_pages = 2;
2040 }
2041 else if (s->model == MODEL_S1100)
2042 {
2043 img_heads = 1; /* image width is the same as the plane width on the S1000 */
2044 img_pages = 1;
2045 }
2046 else /* MODEL_FI60F or MODEL_FI65F */
2047 {
2048 img_heads = 3; /* image width is 3* the plane width on the FI-60F */
2049 img_pages = 1;
2050 }
2051
2052 /* height */
2053 if (s->tl_y > s->max_y - s->min_y)
2054 s->tl_y = s->max_y - s->min_y - s->adf_height_padding;
2055 s->page_height = MIN(s->page_height, s->max_y - s->adf_height_padding - s->tl_y);
2056 if (s->page_height > 0)
2057 s->page_height = MAX(s->page_height, s->min_y);
2058 if (s->tl_y + s->page_height > s->max_y)
2059 s->tl_y = s->max_y - s->adf_height_padding - s->page_height;
2060 s->tl_y = MAX(s->tl_y, 0);
2061
2062 if (s->page_height > 0) {
2063 s->br_y = s->tl_y + s->page_height;
2064 }
2065 else {
2066 s->br_y = s->max_y;
2067 }
2068
2069 /*width*/
2070 s->page_width = MIN(s->page_width, s->max_x);
2071 s->page_width = MAX(s->page_width, s->min_x);
2072
2073 s->tl_x = (s->max_x - s->page_width)/2;
2074 s->br_x = (s->max_x + s->page_width)/2;
2075
2076 /*=============================================================*/
2077 /* set up the calibration scan structs */
2078 /* generally full width, short height, full resolution */
2079 s->cal_image.line_stride = settings[i].cal_line_stride;
2080 s->cal_image.plane_stride = settings[i].cal_plane_stride;
2081 s->cal_image.plane_width = settings[i].cal_plane_width;
2082 s->cal_image.mode = MODE_COLOR;
2083 s->cal_image.x_res = settings[i].x_res;
2084 s->cal_image.y_res = settings[i].y_res;
2085 s->cal_image.raw_data = NULL;
2086 s->cal_image.image = NULL;
2087
2088 /* width is the same, but there are 2 bytes per pixel component */
2089 s->cal_data.line_stride = settings[i].cal_line_stride * 2;
2090 s->cal_data.plane_stride = settings[i].cal_plane_stride * 2;
2091 s->cal_data.plane_width = settings[i].cal_plane_width;
2092 s->cal_data.mode = MODE_COLOR;
2093 s->cal_data.x_res = settings[i].x_res;
2094 s->cal_data.y_res = settings[i].y_res;
2095 s->cal_data.raw_data = NULL;
2096 s->cal_data.image = &s->sendcal;
2097
2098 /*=============================================================*/
2099 /* set up the calibration image blocks */
2100 width = s->cal_image.plane_width * img_heads;
2101 s->coarsecal.width_pix = s->darkcal.width_pix = s->lightcal.width_pix = width;
2102 s->coarsecal.width_bytes = s->darkcal.width_bytes = s->lightcal.width_bytes = width * 3;
2103 s->coarsecal.height = 1;
2104 s->coarsecal.mode = MODE_COLOR;
2105 s->coarsecal.x_res = s->darkcal.x_res = s->lightcal.x_res = settings[i].x_res;
2106 s->coarsecal.y_res = s->darkcal.y_res = s->lightcal.y_res = settings[i].y_res;
2107 s->darkcal.height = s->lightcal.height = 16;
2108 s->coarsecal.pages = s->darkcal.pages = s->lightcal.pages = img_pages;
2109 s->coarsecal.buffer = s->darkcal.buffer = s->lightcal.buffer = NULL;
2110
2111 /* set up the calibration data block */
2112 width = s->cal_data.plane_width * img_heads;
2113 s->sendcal.width_pix = width;
2114 s->sendcal.width_bytes = width * 6; /* 2 bytes of cal data per pixel component */
2115 s->sendcal.height = 1;
2116 s->sendcal.mode = MODE_COLOR;
2117 s->sendcal.x_res = settings[i].x_res;
2118 s->sendcal.y_res = settings[i].y_res;
2119 s->sendcal.pages = img_pages;
2120 s->sendcal.buffer = NULL;
2121
2122 /*=============================================================*/
2123 /* set up the fullscan parameters */
2124 /* this is bookkeeping for what we actually pull from the scanner */
2125 /* note that this has no image, just dimensions and counters */
2126 s->fullscan.width_bytes = settings[i].line_stride;
2127 s->fullscan.mode = settings[i].mode;
2128 s->fullscan.x_res = settings[i].x_res;
2129 s->fullscan.y_res = settings[i].y_res;
2130 if(s->source == SOURCE_FLATBED || !s->page_height)
2131 {
2132 /* flatbed and adf in autodetect always ask for all*/
2133 s->fullscan.height = SCANNER_UNIT_TO_PIX(s->max_y, s->fullscan.y_res);
2134 }
2135 else
2136 {
2137 /* adf with specified paper size requires padding on top of page_height (~1/2in) */
2138 s->fullscan.height = SCANNER_UNIT_TO_PIX((s->page_height + s->tl_y + s->adf_height_padding), s->fullscan.y_res);
2139 }
2140
2141 /*=============================================================*/
2142 /* set up the input block raw struct */
2143 /* this holds up to 512k of raw scan data */
2144 s->block_xfr.line_stride = settings[i].line_stride;
2145 s->block_xfr.plane_stride = settings[i].plane_stride;
2146 s->block_xfr.plane_width = settings[i].plane_width;
2147 s->block_xfr.mode = settings[i].mode;
2148 s->block_xfr.x_res = settings[i].x_res;
2149 s->block_xfr.y_res = settings[i].y_res;
2150 s->block_xfr.raw_data = NULL;
2151 s->block_xfr.image = &s->block_img;
2152
2153 /* set up the input block image struct */
2154 /* note that this is the same width/x_res as the final output image */
2155 /* but the mode, height and y_res are the same as block_xfr */
2156 width = (settings[i].max_x * s->resolution / settings[i].x_res);
2157 s->block_img.width_pix = width;
2158 s->block_img.width_bytes = width * (settings[i].mode == MODE_COLOR ? 3 : 1);
2159 s->block_img.height = settings[i].block_height;
2160 s->block_img.mode = settings[i].mode;
2161 s->block_img.x_res = s->resolution;
2162 s->block_img.y_res = settings[i].y_res;
2163 s->block_img.pages = img_pages;
2164 s->block_img.buffer = NULL;
2165
2166 /*=============================================================*/
2167 /* set up the output image structs */
2168 /* output image might be different from scan due to interpolation */
2169 s->front.mode = s->mode;
2170 s->front.x_res = s->resolution;
2171 s->front.y_res = s->resolution;
2172 if(s->source == SOURCE_FLATBED)
2173 {
2174 /* flatbed ignores the tly */
2175 s->front.height = SCANNER_UNIT_TO_PIX(s->max_y - s->tl_y, s->front.y_res);
2176 }
2177 else if(!s->page_height)
2178 {
2179 /* adf in autodetect always asks for all */
2180 s->front.height = SCANNER_UNIT_TO_PIX(s->max_y, s->front.y_res);
2181 }
2182 else
2183 {
2184 /* adf with specified paper size */
2185 s->front.height = SCANNER_UNIT_TO_PIX(s->page_height, s->front.y_res);
2186 }
2187 s->front.width_pix = SCANNER_UNIT_TO_PIX(s->page_width, s->resolution * img_heads);
2188 s->front.x_start_offset = (s->block_xfr.image->width_pix - s->front.width_pix)/2;
2189 switch (s->mode) {
2190 case MODE_COLOR:
2191 s->front.width_bytes = s->front.width_pix*3;
2192 s->front.x_offset_bytes = s->front.x_start_offset *3;
2193 break;
2194 case MODE_GRAYSCALE:
2195 s->front.width_bytes = s->front.width_pix;
2196 s->front.x_offset_bytes = s->front.x_start_offset;
2197 break;
2198 default: /*binary*/
2199 s->front.width_bytes = s->front.width_pix/8;
2200 s->front.width_pix = s->front.width_bytes * 8;
2201 /*s->page_width = PIX_TO_SCANNER_UNIT(s->front.width_pix, (img_heads * s->resolution_x));*/
2202 s->front.x_offset_bytes = s->front.x_start_offset/8;
2203 break;
2204 }
2205
2206 /* ADF front need to remove padding header */
2207 if (s->source != SOURCE_FLATBED)
2208 {
2209 s->front.y_skip_offset = SCANNER_UNIT_TO_PIX(s->tl_y+s->adf_height_padding, s->fullscan.y_res);
2210 }
2211 else
2212 {
2213 s->front.y_skip_offset = SCANNER_UNIT_TO_PIX(s->tl_y, s->fullscan.y_res);
2214 }
2215
2216 s->front.pages = 1;
2217 s->front.buffer = NULL;
2218
2219 /* back settings always same as front settings */
2220 s->back.width_pix = s->front.width_pix;
2221 s->back.width_bytes = s->front.width_bytes;
2222 s->back.mode = s->front.mode;
2223 s->back.x_res = s->front.x_res;
2224 s->back.y_res = s->front.y_res;
2225 s->back.height = s->front.height;
2226 s->back.x_start_offset = s->front.x_start_offset;
2227 s->back.x_offset_bytes = s->front.x_offset_bytes;
2228 s->back.y_skip_offset = SCANNER_UNIT_TO_PIX(s->tl_y, s->fullscan.y_res);
2229 s->back.pages = 1;
2230 s->back.buffer = NULL;
2231
2232 /* dynamic threshold temp buffer, in gray */
2233 s->dt.width_pix = s->front.width_pix;
2234 s->dt.width_bytes = s->front.width_pix;
2235 s->dt.mode = MODE_GRAYSCALE;
2236 s->dt.x_res = s->front.x_res;
2237 s->dt.y_res = s->front.y_res;
2238 s->dt.height = 1;
2239 s->dt.pages = 1;
2240 s->dt.buffer = NULL;
2241
2242 /* set up the pointers to the page images in the page structs */
2243 s->pages[SIDE_FRONT].image = &s->front;
2244 s->pages[SIDE_BACK].image = &s->back;
2245 s->pages[SIDE_FRONT].done = 0;
2246 s->pages[SIDE_BACK].done = 0;
2247
2248 DBG (10, "change_params: finish\n");
2249
2250 return ret;
2251 }
2252
2253 /* Function to build a lookup table (LUT), often
2254 used by scanners to implement brightness/contrast/gamma
2255 or by backends to speed binarization/thresholding
2256
2257 offset and slope inputs are -127 to +127
2258
2259 slope rotates line around central input/output val,
2260 0 makes horizontal line
2261
2262 pos zero neg
2263 . x . . x
2264 . x . . x
2265 out . x .xxxxxxxxxxx . x
2266 . x . . x
2267 ....x....... ............ .......x....
2268 in in in
2269
2270 offset moves line vertically, and clamps to output range
2271 0 keeps the line crossing the center of the table
2272
2273 high low
2274 . xxxxxxxx .
2275 . x .
2276 out x . x
2277 . . x
2278 ............ xxxxxxxx....
2279 in in
2280
2281 out_min/max provide bounds on output values,
2282 useful when building thresholding lut.
2283 0 and 255 are good defaults otherwise.
2284 */
2285 static SANE_Status
load_lut(unsigned char * lut, int in_bits, int out_bits, int out_min, int out_max, int slope, int offset)2286 load_lut (unsigned char * lut,
2287 int in_bits, int out_bits,
2288 int out_min, int out_max,
2289 int slope, int offset)
2290 {
2291 SANE_Status ret = SANE_STATUS_GOOD;
2292 int i, j;
2293 double shift, rise;
2294 int max_in_val = (1 << in_bits) - 1;
2295 int max_out_val = (1 << out_bits) - 1;
2296 unsigned char * lut_p = lut;
2297
2298 DBG (10, "load_lut: start\n");
2299
2300 /* slope is converted to rise per unit run:
2301 * first [-127,127] to [-1,1]
2302 * then multiply by PI/2 to convert to radians
2303 * then take the tangent (T.O.A)
2304 * then multiply by the normal linear slope
2305 * because the table may not be square, i.e. 1024x256*/
2306 rise = tan((double)slope/127 * M_PI/2) * max_out_val / max_in_val;
2307
2308 /* line must stay vertically centered, so figure
2309 * out vertical offset at central input value */
2310 shift = (double)max_out_val/2 - (rise*max_in_val/2);
2311
2312 /* convert the user offset setting to scale of output
2313 * first [-127,127] to [-1,1]
2314 * then to [-max_out_val/2,max_out_val/2]*/
2315 shift += (double)offset / 127 * max_out_val / 2;
2316
2317 for(i=0;i<=max_in_val;i++){
2318 j = rise*i + shift;
2319
2320 j = MAX(j, out_min);
2321 j = MIN(j, out_max);
2322
2323 *lut_p=j;
2324 lut_p++;
2325 }
2326
2327 hexdump(5, "load_lut: ", lut, max_in_val+1);
2328
2329 DBG (10, "load_lut: finish\n");
2330 return ret;
2331 }
2332
2333 /*
2334 * @@ Section 4 - SANE scanning functions
2335 */
2336 /*
2337 * Called by SANE to retrieve information about the type of data
2338 * that the current scan will return.
2339 *
2340 * From the SANE spec:
2341 * This function is used to obtain the current scan parameters. The
2342 * returned parameters are guaranteed to be accurate between the time
2343 * a scan has been started (sane_start() has been called) and the
2344 * completion of that request. Outside of that window, the returned
2345 * values are best-effort estimates of what the parameters will be
2346 * when sane_start() gets invoked.
2347 *
2348 * Calling this function before a scan has actually started allows,
2349 * for example, to get an estimate of how big the scanned image will
2350 * be. The parameters passed to this function are the handle h of the
2351 * device for which the parameters should be obtained and a pointer p
2352 * to a parameter structure.
2353 */
2354 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)2355 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
2356 {
2357 struct scanner *s = (struct scanner *) handle;
2358
2359 DBG (10, "sane_get_parameters: start\n");
2360
2361 params->pixels_per_line = s->front.width_pix;
2362 params->bytes_per_line = s->front.width_bytes;
2363 if(!s->page_height){
2364 params->lines = -1;
2365 }
2366 else{
2367 params->lines = s->front.height;
2368 }
2369 params->last_frame = 1;
2370
2371 if (s->mode == MODE_COLOR) {
2372 params->format = SANE_FRAME_RGB;
2373 params->depth = 8;
2374 }
2375 else if (s->mode == MODE_GRAYSCALE) {
2376 params->format = SANE_FRAME_GRAY;
2377 params->depth = 8;
2378 }
2379 else if (s->mode == MODE_LINEART) {
2380 params->format = SANE_FRAME_GRAY;
2381 params->depth = 1;
2382 }
2383
2384 DBG (15, "\tdepth %d\n", params->depth);
2385 DBG (15, "\tlines %d\n", params->lines);
2386 DBG (15, "\tpixels_per_line %d\n", params->pixels_per_line);
2387 DBG (15, "\tbytes_per_line %d\n", params->bytes_per_line);
2388
2389 DBG (10, "sane_get_parameters: finish\n");
2390
2391 return SANE_STATUS_GOOD;
2392 }
2393
2394 /*
2395 * Called by SANE when a page acquisition operation is to be started.
2396 * FIXME: won't handle SOURCE_ADF_BACK
2397 */
2398 SANE_Status
sane_start(SANE_Handle handle)2399 sane_start (SANE_Handle handle)
2400 {
2401 struct scanner *s = handle;
2402 SANE_Status ret;
2403 int i;
2404
2405 DBG (10, "sane_start: start\n");
2406
2407 /* set side marker on first page */
2408 if(!s->started){
2409 if(s->source == SOURCE_ADF_BACK){
2410 s->side = SIDE_BACK;
2411 }
2412 else{
2413 s->side = SIDE_FRONT;
2414 }
2415 }
2416 /* if already running, duplex needs to switch sides */
2417 else if(s->source == SOURCE_ADF_DUPLEX){
2418 s->side = !s->side;
2419 }
2420
2421 /* recent scanners need ghs called before scanning */
2422 ret = get_hardware_status(s);
2423
2424 /* ingest paper with adf */
2425 if( s->source == SOURCE_ADF_BACK || s->source == SOURCE_ADF_FRONT
2426 || (s->source == SOURCE_ADF_DUPLEX && s->side == SIDE_FRONT) ){
2427 ret = object_position(s,EPJITSU_PAPER_INGEST);
2428 if (ret != SANE_STATUS_GOOD) {
2429 DBG (5, "sane_start: ERROR: failed to ingest\n");
2430 sane_cancel((SANE_Handle)s);
2431 return ret;
2432 }
2433 }
2434
2435 /* first page requires buffers, etc */
2436 if(!s->started){
2437
2438 DBG(15,"sane_start: first page\n");
2439
2440 s->started=1;
2441
2442 ret = teardown_buffers(s);
2443 if (ret != SANE_STATUS_GOOD) {
2444 DBG (5, "sane_start: ERROR: failed to teardown buffers\n");
2445 sane_cancel((SANE_Handle)s);
2446 return SANE_STATUS_NO_MEM;
2447 }
2448
2449 ret = change_params(s);
2450 if (ret != SANE_STATUS_GOOD) {
2451 DBG (5, "sane_start: ERROR: failed to change_params\n");
2452 sane_cancel((SANE_Handle)s);
2453 return SANE_STATUS_NO_MEM;
2454 }
2455
2456 ret = setup_buffers(s);
2457 if (ret != SANE_STATUS_GOOD) {
2458 DBG (5, "sane_start: ERROR: failed to setup buffers\n");
2459 sane_cancel((SANE_Handle)s);
2460 return SANE_STATUS_NO_MEM;
2461 }
2462
2463 ret = load_lut(s->dt_lut, 8, 8, 50, 205,
2464 s->threshold_curve, s->threshold-127);
2465 if (ret != SANE_STATUS_GOOD) {
2466 DBG (5, "sane_start: ERROR: failed to load_lut for dt\n");
2467 sane_cancel((SANE_Handle)s);
2468 return ret;
2469 }
2470
2471 ret = coarsecal(s);
2472 if (ret != SANE_STATUS_GOOD) {
2473 DBG (5, "sane_start: ERROR: failed to coarsecal\n");
2474 sane_cancel((SANE_Handle)s);
2475 return ret;
2476 }
2477
2478 ret = finecal(s);
2479 if (ret != SANE_STATUS_GOOD) {
2480 DBG (5, "sane_start: ERROR: failed to finecal\n");
2481 sane_cancel((SANE_Handle)s);
2482 return ret;
2483 }
2484
2485 ret = send_lut(s);
2486 if (ret != SANE_STATUS_GOOD) {
2487 DBG (5, "sane_start: ERROR: failed to send lut\n");
2488 sane_cancel((SANE_Handle)s);
2489 return ret;
2490 }
2491
2492 ret = lamp(s,1);
2493 if (ret != SANE_STATUS_GOOD) {
2494 DBG (5, "sane_start: ERROR: failed to heat lamp\n");
2495 sane_cancel((SANE_Handle)s);
2496 return ret;
2497 }
2498
2499 /*should this be between each page*/
2500 ret = set_window(s,WINDOW_SCAN);
2501 if (ret != SANE_STATUS_GOOD) {
2502 DBG (5, "sane_start: ERROR: failed to set window\n");
2503 sane_cancel((SANE_Handle)s);
2504 return ret;
2505 }
2506
2507 }
2508
2509 /* reset everything when starting any front, or just back */
2510 if(s->side == SIDE_FRONT || s->source == SOURCE_ADF_BACK){
2511
2512 DBG(15,"sane_start: reset counters\n");
2513
2514 /* reset scan */
2515 s->fullscan.done = 0;
2516 s->fullscan.rx_bytes = 0;
2517 s->fullscan.total_bytes = s->fullscan.width_bytes * s->fullscan.height;
2518
2519 /* reset block */
2520 update_transfer_totals(&s->block_xfr);
2521
2522 /* reset front and back page counters */
2523 for (i = 0; i < 2; i++)
2524 {
2525 struct image *page_img = s->pages[i].image;
2526 s->pages[i].bytes_total = page_img->width_bytes * page_img->height;
2527 s->pages[i].bytes_scanned = 0;
2528 s->pages[i].bytes_read = 0;
2529 s->pages[i].lines_rx = 0;
2530 s->pages[i].lines_pass = 0;
2531 s->pages[i].lines_tx = 0;
2532 s->pages[i].done = 0;
2533 }
2534
2535 ret = scan(s);
2536 if (ret != SANE_STATUS_GOOD) {
2537 DBG (5, "sane_start: ERROR: failed to start scan\n");
2538 sane_cancel((SANE_Handle)s);
2539 return ret;
2540 }
2541 }
2542 else{
2543 DBG(15,"sane_start: back side\n");
2544 }
2545
2546 DBG (10, "sane_start: finish\n");
2547
2548 return SANE_STATUS_GOOD;
2549 }
2550
2551 /* the +8 on all the lengths is to makeup for potential block trailers */
2552 static SANE_Status
setup_buffers(struct scanner *s)2553 setup_buffers(struct scanner *s)
2554 {
2555 SANE_Status ret = SANE_STATUS_GOOD;
2556
2557 DBG (10, "setup_buffers: start\n");
2558
2559 /* temporary cal data */
2560 s->coarsecal.buffer = calloc (1,s->coarsecal.width_bytes * s->coarsecal.height * s->coarsecal.pages);
2561 if(!s->coarsecal.buffer){
2562 DBG (5, "setup_buffers: ERROR: failed to setup coarse cal buffer\n");
2563 return SANE_STATUS_NO_MEM;
2564 }
2565
2566 s->darkcal.buffer = calloc (1,s->darkcal.width_bytes * s->darkcal.height * s->darkcal.pages);
2567 if(!s->darkcal.buffer){
2568 DBG (5, "setup_buffers: ERROR: failed to setup fine cal buffer\n");
2569 return SANE_STATUS_NO_MEM;
2570 }
2571
2572 s->lightcal.buffer = calloc (1,s->lightcal.width_bytes * s->lightcal.height * s->lightcal.pages);
2573 if(!s->lightcal.buffer){
2574 DBG (5, "setup_buffers: ERROR: failed to setup fine cal buffer\n");
2575 return SANE_STATUS_NO_MEM;
2576 }
2577
2578 s->sendcal.buffer = calloc (1,s->sendcal.width_bytes * s->sendcal.height * s->sendcal.pages);
2579 if(!s->sendcal.buffer){
2580 DBG (5, "setup_buffers: ERROR: failed to setup send cal buffer\n");
2581 return SANE_STATUS_NO_MEM;
2582 }
2583
2584 s->cal_image.raw_data = calloc(1, s->cal_image.line_stride * 16 + 8); /* maximum 16 lines input for fine calibration */
2585 if(!s->cal_image.raw_data){
2586 DBG (5, "setup_buffers: ERROR: failed to setup calibration input raw data buffer\n");
2587 return SANE_STATUS_NO_MEM;
2588 }
2589
2590 s->cal_data.raw_data = calloc(1, s->cal_data.line_stride); /* only 1 line of data is sent */
2591 if(!s->cal_data.raw_data){
2592 DBG (5, "setup_buffers: ERROR: failed to setup calibration output raw data buffer\n");
2593 return SANE_STATUS_NO_MEM;
2594 }
2595
2596 /* grab up to 512K at a time */
2597 s->block_img.buffer = calloc (1,s->block_img.width_bytes * s->block_img.height * s->block_img.pages);
2598 if(!s->block_img.buffer){
2599 DBG (5, "setup_buffers: ERROR: failed to setup block image buffer\n");
2600 return SANE_STATUS_NO_MEM;
2601 }
2602 s->block_xfr.raw_data = calloc(1, s->block_xfr.line_stride * s->block_img.height + 8);
2603 if(!s->block_xfr.raw_data){
2604 DBG (5, "setup_buffers: ERROR: failed to setup block raw data buffer\n");
2605 return SANE_STATUS_NO_MEM;
2606 }
2607
2608 /* one grayscale line for dynamic threshold */
2609 s->dt.buffer = calloc (1,s->dt.width_bytes * s->dt.height * s->dt.pages);
2610 if(!s->dt.buffer){
2611 DBG (5, "setup_buffers: ERROR: failed to setup dt buffer\n");
2612 return SANE_STATUS_NO_MEM;
2613 }
2614
2615 /* make image buffer to hold frontside data */
2616 if(s->source != SOURCE_ADF_BACK){
2617
2618 s->front.buffer = calloc (1,s->front.width_bytes * s->front.height * s->front.pages);
2619 if(!s->front.buffer){
2620 DBG (5, "setup_buffers: ERROR: failed to setup front buffer\n");
2621 return SANE_STATUS_NO_MEM;
2622 }
2623 }
2624
2625 /* make image buffer to hold backside data */
2626 if(s->source == SOURCE_ADF_DUPLEX || s->source == SOURCE_ADF_BACK){
2627
2628 s->back.buffer = calloc (1,s->back.width_bytes * s->back.height * s->back.pages);
2629 if(!s->back.buffer){
2630 DBG (5, "setup_buffers: ERROR: failed to setup back buffer\n");
2631 return SANE_STATUS_NO_MEM;
2632 }
2633 }
2634
2635 DBG (10, "setup_buffers: finish\n");
2636 return ret;
2637 }
2638
2639 /*
2640 coarse calibration consists of:
2641 1. turn lamp off (d0)
2642 2. set window for single line of data (d1)
2643 3. get line (d2)
2644 4. update dark coarse cal (c6)
2645 5. return to #3 if not dark enough
2646 6. turn lamp on (d0)
2647 7. get line (d2)
2648 8. update light coarse cal (c6)
2649 9. return to #7 if not light enough
2650 */
2651
2652 static SANE_Status
coarsecal_send_cal(struct scanner *s, unsigned char *pay)2653 coarsecal_send_cal(struct scanner *s, unsigned char *pay)
2654 {
2655 SANE_Status ret = SANE_STATUS_GOOD;
2656 unsigned char cmd[2];
2657 unsigned char stat[1];
2658 size_t cmdLen,statLen,payLen;
2659
2660 DBG (10, "coarsecal_send_cal: start\n");
2661 /* send coarse cal (c6) */
2662 cmd[0] = 0x1b;
2663 cmd[1] = 0xc6;
2664 cmdLen = 2;
2665 stat[0] = 0;
2666 statLen = 1;
2667
2668 ret = do_cmd(
2669 s, 0,
2670 cmd, cmdLen,
2671 NULL, 0,
2672 stat, &statLen
2673 );
2674 if(ret){
2675 DBG (5, "coarsecal_send_cal: error sending c6 cmd\n");
2676 return ret;
2677 }
2678 if(stat[0] != 6){
2679 DBG (5, "coarsecal_send_cal: cmd bad c6 status?\n");
2680 return SANE_STATUS_IO_ERROR;
2681 }
2682
2683 /*send coarse cal payload*/
2684 stat[0] = 0;
2685 statLen = 1;
2686 payLen = 28;
2687
2688 ret = do_cmd(
2689 s, 0,
2690 pay, payLen,
2691 NULL, 0,
2692 stat, &statLen
2693 );
2694 if(ret){
2695 DBG (5, "coarsecal_send_cal: error sending c6 payload\n");
2696 return ret;
2697 }
2698 if(stat[0] != 6){
2699 DBG (5, "coarsecal_send_cal: c6 payload bad status?\n");
2700 return SANE_STATUS_IO_ERROR;
2701 }
2702
2703 DBG (10, "coarsecal_send_cal: finish\n");
2704 return ret;
2705 }
2706
2707 static SANE_Status
coarsecal_get_line(struct scanner *s, struct image *img)2708 coarsecal_get_line(struct scanner *s, struct image *img)
2709 {
2710 SANE_Status ret = SANE_STATUS_GOOD;
2711 unsigned char cmd[2];
2712 unsigned char stat[1];
2713 size_t cmdLen,statLen;
2714
2715 DBG (10, "coarsecal_get_line: start\n");
2716
2717 /* send scan d2 command */
2718 cmd[0] = 0x1b;
2719 cmd[1] = 0xd2;
2720 cmdLen = 2;
2721 stat[0] = 0;
2722 statLen = 1;
2723
2724 ret = do_cmd(
2725 s, 0,
2726 cmd, cmdLen,
2727 NULL, 0,
2728 stat, &statLen
2729 );
2730 if(ret){
2731 DBG (5, "coarsecal_get_line: error sending d2 cmd\n");
2732 return ret;
2733 }
2734 if(stat[0] != 6){
2735 DBG (5, "coarsecal_get_line: cmd bad d2 status?\n");
2736 return SANE_STATUS_IO_ERROR;
2737 }
2738
2739 s->cal_image.image = img;
2740 update_transfer_totals(&s->cal_image);
2741
2742 while(!s->cal_image.done){
2743 ret = read_from_scanner(s,&s->cal_image);
2744 if(ret){
2745 DBG (5, "coarsecal_get_line: can't read from scanner\n");
2746 return ret;
2747 }
2748 }
2749 /* convert the raw data into normal packed pixel data */
2750 descramble_raw(s, &s->cal_image);
2751
2752 DBG (10, "coarsecal_get_line: finish\n");
2753 return ret;
2754 }
2755
2756 static SANE_Status
coarsecal_dark(struct scanner *s, unsigned char *pay)2757 coarsecal_dark(struct scanner *s, unsigned char *pay)
2758 {
2759 SANE_Status ret = SANE_STATUS_GOOD;
2760
2761 int try_count, cal_good[2], x, j;
2762 int param[2], zcount[2], high_param[2], low_param[2], avg[2], maxval[2];
2763
2764 DBG (10, "coarsecal_dark: start\n");
2765
2766 /* dark cal, lamp off */
2767 ret = lamp(s,0);
2768 if(ret){
2769 DBG (5, "coarsecal_dark: error lamp off\n");
2770 return ret;
2771 }
2772
2773 try_count = 8;
2774 param[0] = 63;
2775 param[1] = 63;
2776 low_param[0] = low_param[1] = -64; /* The S300 will accept coarse offsets from -128 to 127 */
2777 high_param[0] = high_param[1] = 63; /* By our range is limited to converge faster */
2778 cal_good[0] = cal_good[1] = 0;
2779
2780 while (try_count > 0){
2781 try_count--;
2782
2783 /* update the coarsecal payload to use our new dark offset parameters */
2784 if (s->model == MODEL_S300 || s->model == MODEL_S1300i)
2785 {
2786 pay[5] = param[0];
2787 pay[7] = param[1];
2788 }
2789 else /* MODEL_S1100 or MODEL_FI60F or MODEL_FI65F */
2790 {
2791 pay[5] = param[0];
2792 pay[7] = param[0];
2793 pay[9] = param[0];
2794 }
2795
2796 ret = coarsecal_send_cal(s, pay);
2797
2798 DBG(15, "coarsecal_dark offset: parameter front: %i back: %i\n", param[0], param[1]);
2799
2800 ret = coarsecal_get_line(s, &s->coarsecal);
2801
2802 /* gather statistics: count the proportion of 0-valued pixels */
2803 /* since the lamp is off, there's no point in looking at the green or blue data - they're all from the same sensor anyway */
2804 zcount[0] = zcount[1] = 0;
2805 avg[0] = avg[1] = 0;
2806 maxval[0] = maxval[1] = 0;
2807 for (j = 0; j < s->coarsecal.pages; j++)
2808 {
2809 int page_offset = j * s->coarsecal.width_bytes * s->coarsecal.height;
2810 for (x = 0; x < s->coarsecal.width_bytes; x++)
2811 {
2812 int val = s->coarsecal.buffer[page_offset + x];
2813 avg[j] += val;
2814 if (val == 0) zcount[j]++;
2815 if (val > maxval[j]) maxval[j] = val;
2816 }
2817 }
2818 /* convert the zero counts from a pixel count to a proportion in tenths of a percent */
2819 for (j = 0; j < s->coarsecal.pages; j++)
2820 {
2821 avg[j] /= s->coarsecal.width_bytes;
2822 zcount[j] = zcount[j] * 1000 / s->coarsecal.width_bytes;
2823 }
2824 DBG(15, "coarsecal_dark offset: average pixel values front: %i back: %i\n", avg[0], avg[1]);
2825 DBG(15, "coarsecal_dark offset: maximum pixel values front: %i back: %i\n", maxval[0], maxval[1]);
2826 DBG(15, "coarsecal_dark offset: 0-valued pixel count front: %f%% back: %f%%\n", zcount[0] / 10.0f, zcount[1] / 10.0f);
2827
2828 /* check the values, adjust parameters if they are not within the target range */
2829 for (j = 0; j < s->coarsecal.pages; j++)
2830 {
2831 if (!cal_good[j])
2832 {
2833 if (avg[j] > COARSE_OFFSET_TARGET)
2834 {
2835 high_param[j] = param[j];
2836 param[j] = (low_param[j] + high_param[j]) / 2;
2837 }
2838 else if (avg[j] < COARSE_OFFSET_TARGET)
2839 {
2840 low_param[j] = param[j];
2841 param[j] = (low_param[j] + high_param[j]) / 2;
2842 }
2843 else cal_good[j] = 1;
2844 }
2845 }
2846 if (cal_good[0] + cal_good[1] == s->coarsecal.pages) break;
2847
2848 } /* continue looping for up to 8 tries */
2849
2850 DBG (10, "coarsecal_dark: finish\n");
2851 return ret;
2852 }
2853
2854 static SANE_Status
coarsecal_light(struct scanner *s, unsigned char *pay)2855 coarsecal_light(struct scanner *s, unsigned char *pay)
2856 {
2857 SANE_Status ret = SANE_STATUS_GOOD;
2858
2859 int try_count, cal_good[2], x, i, j;
2860 int param[2], zcount[2], high_param[2], low_param[2], avg[2];
2861 int rgb_avg[2][3], rgb_hicount[2][3];
2862
2863 DBG (10, "coarsecal_light: start\n");
2864
2865 /* light cal, lamp on */
2866 ret = lamp(s,1);
2867 if(ret){
2868 DBG (5, "coarsecal_light: error lamp on\n");
2869 return ret;
2870 }
2871
2872 try_count = 8;
2873 param[0] = pay[11];
2874 param[1] = pay[13];
2875 low_param[0] = low_param[1] = 0;
2876 high_param[0] = high_param[1] = 63;
2877 cal_good[0] = cal_good[1] = 0;
2878
2879 while (try_count > 0){
2880 try_count--;
2881
2882 ret = coarsecal_send_cal(s, pay);
2883
2884 DBG(15, "coarsecal_light gain: parameter front: %i back: %i\n", param[0], param[1]);
2885
2886 ret = coarsecal_get_line(s, &s->coarsecal);
2887
2888 /* gather statistics: count the proportion of 255-valued pixels in each color channel */
2889 /* count the average pixel value in each color channel */
2890 for (i = 0; i < s->coarsecal.pages; i++)
2891 for (j = 0; j < 3; j++)
2892 rgb_avg[i][j] = rgb_hicount[i][j] = 0;
2893 for (i = 0; i < s->coarsecal.pages; i++)
2894 {
2895 for (x = 0; x < s->coarsecal.width_pix; x++)
2896 {
2897 /* get color channel values and count of pixels pegged at 255 */
2898 unsigned char *rgbpix = s->coarsecal.buffer + (i * s->coarsecal.width_bytes * s->coarsecal.height) + x * 3;
2899 for (j = 0; j < 3; j++)
2900 {
2901 rgb_avg[i][j] += rgbpix[j];
2902 if (rgbpix[j] == 255)
2903 rgb_hicount[i][j]++;
2904 }
2905 }
2906 }
2907 /* apply the color correction factors to the averages */
2908 for (i = 0; i < s->coarsecal.pages; i++)
2909 for (j = 0; j < 3; j++)
2910 rgb_avg[i][j] *= s->white_factor[j];
2911 /* set the gain so that none of the color channels are clipping, ie take the highest channel values */
2912 for (i = 0; i < s->coarsecal.pages; i++)
2913 {
2914 avg[i] = MAX3(rgb_avg[i][0], rgb_avg[i][1], rgb_avg[i][2]) / s->coarsecal.width_pix;
2915 for (j = 0; j < 3; j++)
2916 rgb_avg[i][j] /= s->coarsecal.width_pix;
2917 }
2918 /* convert the 255-counts from a pixel count to a proportion in tenths of a percent */
2919 for (i = 0; i < s->coarsecal.pages; i++)
2920 {
2921 for (j = 0; j < 3; j++)
2922 {
2923 rgb_hicount[i][j] = rgb_hicount[i][j] * 1000 / s->coarsecal.width_pix;
2924 }
2925 zcount[i] = MAX3(rgb_hicount[i][0], rgb_hicount[i][1], rgb_hicount[i][2]);
2926 }
2927 DBG(15, "coarsecal_light gain: average RGB values front: (%i,%i,%i) back: (%i,%i,%i)\n",
2928 rgb_avg[0][0], rgb_avg[0][1], rgb_avg[0][2], rgb_avg[1][0], rgb_avg[1][1], rgb_avg[1][2]);
2929 DBG(15, "coarsecal_light gain: 255-valued pixel count front: (%g,%g,%g) back: (%g,%g,%g)\n",
2930 rgb_hicount[0][0]/10.0f, rgb_hicount[0][1]/10.0f, rgb_hicount[0][2]/10.0f,
2931 rgb_hicount[1][0]/10.0f, rgb_hicount[1][1]/10.0f, rgb_hicount[1][2]/10.0f);
2932
2933 /* check the values, adjust parameters if they are not within the target range */
2934 for (x = 0; x < s->coarsecal.pages; x++)
2935 {
2936 if (!cal_good[x])
2937 {
2938 if (zcount[x] > 9 || avg[x] > coarse_gain_max[x])
2939 {
2940 high_param[x] = param[x];
2941 param[x] = (low_param[x] + high_param[x]) / 2;
2942 }
2943 else if (avg[x] < coarse_gain_min[x])
2944 {
2945 low_param[x] = param[x];
2946 param[x] = (low_param[x] + high_param[x]) / 2;
2947 }
2948 else cal_good[x] = 1;
2949 }
2950 }
2951 if (cal_good[0] + cal_good[1] == s->coarsecal.pages) break;
2952
2953 /* update the coarsecal payload to use the new gain parameters */
2954 if (s->model == MODEL_S300 || s->model == MODEL_S1300i)
2955 {
2956 pay[11] = param[0];
2957 pay[13] = param[1];
2958 }
2959 else /* MODEL_S1100 or MODEL_FI60F or MODEL_FI65F */
2960 {
2961 pay[11] = param[0];
2962 pay[13] = param[0];
2963 pay[15] = param[0];
2964 }
2965 }
2966
2967 DBG (10, "coarsecal_light: finish\n");
2968 return ret;
2969 }
2970
2971 static SANE_Status
coarsecal(struct scanner *s)2972 coarsecal(struct scanner *s)
2973 {
2974 SANE_Status ret = SANE_STATUS_GOOD;
2975 unsigned char pay[28];
2976 size_t payLen;
2977
2978 DBG (10, "coarsecal: start\n");
2979
2980 payLen = sizeof(pay);
2981
2982 if(s->model == MODEL_S300){
2983 memcpy(pay,coarseCalData_S300,payLen);
2984 }
2985 else if(s->model == MODEL_S1300i){
2986 memcpy(pay,coarseCalData_S1300i,payLen);
2987 }
2988 else if(s->model == MODEL_S1100){
2989 memcpy(pay,coarseCalData_S1100,payLen);
2990 }
2991 else{
2992 memcpy(pay,coarseCalData_FI60F,payLen);
2993 }
2994
2995 /* ask for 1 line */
2996 ret = set_window(s, WINDOW_COARSECAL);
2997 if(ret){
2998 DBG (5, "coarsecal: error sending setwindow\n");
2999 return ret;
3000 }
3001
3002 if(s->model == MODEL_S1100){
3003 ret = coarsecal_send_cal(s, pay);
3004 }
3005 else{
3006 ret = coarsecal_dark(s, pay);
3007 ret = coarsecal_light(s, pay);
3008 }
3009
3010 DBG (10, "coarsecal: finish\n");
3011 return ret;
3012 }
3013
3014 static SANE_Status
finecal_send_cal(struct scanner *s)3015 finecal_send_cal(struct scanner *s)
3016 {
3017 SANE_Status ret = SANE_STATUS_GOOD;
3018
3019 size_t cmdLen = 2;
3020 unsigned char cmd[2];
3021
3022 size_t statLen = 1;
3023 unsigned char stat[2];
3024
3025 int i, j, k;
3026 unsigned char *p_out, *p_in = s->sendcal.buffer;
3027 int planes;
3028
3029 DBG (10, "finecal_send_cal: start\n");
3030
3031 if(s->model == MODEL_FI60F || s->model == MODEL_FI65F)
3032 planes = 3;
3033 if(s->model == MODEL_S300 || s->model == MODEL_S1300i)
3034 planes = 2;
3035
3036 /* scramble the raster buffer data into scanner raw format */
3037 /* this is reverse of descramble_raw */
3038 memset(s->cal_data.raw_data, 0, s->cal_data.line_stride);
3039
3040 if(s->model == MODEL_S1100){
3041 planes = 1;
3042
3043 for (k = 0; k < s->sendcal.width_pix; k++){ /* column (x) */
3044
3045 /* input is RrGgBb (capital is offset, small is gain) */
3046 /* output is Bb...BbRr...RrGg...Gg*/
3047
3048 /*red*/
3049 p_out = s->cal_data.raw_data + s->cal_data.plane_stride + k*2;
3050 *p_out = *p_in;
3051 p_out++;
3052 p_in++;
3053 *p_out = *p_in;
3054 p_in++;
3055
3056 /*green*/
3057 p_out = s->cal_data.raw_data + 2*s->cal_data.plane_stride + k*2;
3058 *p_out = *p_in;
3059 p_out++;
3060 p_in++;
3061 *p_out = *p_in;
3062 p_in++;
3063
3064 /*blue*/
3065 p_out = s->cal_data.raw_data + k*2;
3066 *p_out = *p_in;
3067 p_out++;
3068 p_in++;
3069 *p_out = *p_in;
3070 p_in++;
3071 }
3072 }
3073
3074 else{
3075 for (i = 0; i < planes; i++)
3076 for (j = 0; j < s->cal_data.plane_width; j++)
3077 for (k = 0; k < 3; k++)
3078 {
3079 p_out = (s->cal_data.raw_data + k * s->cal_data.plane_stride + j * 6 + i * 2);
3080 *p_out = *p_in++; /* dark offset */
3081 p_out++;
3082 *p_out = *p_in++; /* gain */
3083 }
3084 }
3085
3086 ret = set_window(s, WINDOW_SENDCAL);
3087 if(ret){
3088 DBG (5, "finecal_send_cal: error sending setwindow\n");
3089 return ret;
3090 }
3091
3092 /*first unknown cal block*/
3093 cmd[0] = 0x1b;
3094 cmd[1] = 0xc3;
3095 stat[0] = 0;
3096 statLen = 1;
3097
3098 ret = do_cmd(
3099 s, 0,
3100 cmd, cmdLen,
3101 NULL, 0,
3102 stat, &statLen
3103 );
3104 if(ret){
3105 DBG (5, "finecal_send_cal: error sending c3 cmd\n");
3106 return ret;
3107 }
3108 if(stat[0] != 6){
3109 DBG (5, "finecal_send_cal: cmd bad c3 status?\n");
3110 return SANE_STATUS_IO_ERROR;
3111 }
3112
3113 /*send header*/
3114 /*send payload*/
3115 statLen = 1;
3116
3117 ret = do_cmd(
3118 s, 0,
3119 s->sendCal1Header, s->sendCal1HeaderLen,
3120 s->cal_data.raw_data, s->cal_data.line_stride,
3121 stat, &statLen
3122 );
3123
3124 if(ret){
3125 DBG (5, "finecal_send_cal: error sending c3 payload\n");
3126 return ret;
3127 }
3128 if(stat[0] != 6){
3129 DBG (5, "finecal_send_cal: payload bad c3 status?\n");
3130 return SANE_STATUS_IO_ERROR;
3131 }
3132
3133 /*second unknown cal block*/
3134 cmd[1] = 0xc4;
3135 statLen = 1;
3136
3137 ret = do_cmd(
3138 s, 0,
3139 cmd, cmdLen,
3140 NULL, 0,
3141 stat, &statLen
3142 );
3143
3144 if(ret){
3145 DBG (5, "finecal_send_cal: error sending c4 cmd\n");
3146 return ret;
3147 }
3148 if(stat[0] != 6){
3149 DBG (5, "finecal_send_cal: cmd bad c4 status?\n");
3150 return SANE_STATUS_IO_ERROR;
3151 }
3152
3153 /*send header*/
3154 /*send payload*/
3155 statLen = 1;
3156
3157 ret = do_cmd(
3158 s, 0,
3159 s->sendCal2Header, s->sendCal2HeaderLen,
3160 s->cal_data.raw_data, s->cal_data.line_stride,
3161 stat, &statLen
3162 );
3163
3164 if(ret){
3165 DBG (5, "finecal_send_cal: error sending c4 payload\n");
3166 return ret;
3167 }
3168 if(stat[0] != 6){
3169 DBG (5, "finecal_send_cal: payload bad c4 status?\n");
3170 return SANE_STATUS_IO_ERROR;
3171 }
3172
3173 DBG (10, "finecal_send_cal: finish\n");
3174 return ret;
3175 }
3176
3177 static SANE_Status
finecal_get_line(struct scanner *s, struct image *img)3178 finecal_get_line(struct scanner *s, struct image *img)
3179 {
3180 SANE_Status ret = SANE_STATUS_GOOD;
3181
3182 size_t cmdLen = 2;
3183 unsigned char cmd[2];
3184
3185 size_t statLen = 1;
3186 unsigned char stat[2];
3187
3188 int round_offset = img->height / 2;
3189 int i, j, k;
3190
3191 DBG (10, "finecal_get_line: start\n");
3192
3193 /* ask for 16 lines */
3194 ret = set_window(s, WINDOW_FINECAL);
3195 if(ret){
3196 DBG (5, "finecal_get_line: error sending setwindowcal\n");
3197 return ret;
3198 }
3199
3200 /* send scan d2 command */
3201 cmd[0] = 0x1b;
3202 cmd[1] = 0xd2;
3203 stat[0] = 0;
3204 statLen = 1;
3205
3206 ret = do_cmd(
3207 s, 0,
3208 cmd, cmdLen,
3209 NULL, 0,
3210 stat, &statLen
3211 );
3212 if(ret){
3213 DBG (5, "finecal_get_line: error sending d2 cmd\n");
3214 return ret;
3215 }
3216 if(stat[0] != 6){
3217 DBG (5, "finecal_get_line: cmd bad d2 status?\n");
3218 return SANE_STATUS_IO_ERROR;
3219 }
3220
3221 s->cal_image.image = img;
3222 update_transfer_totals(&s->cal_image);
3223
3224 while(!s->cal_image.done){
3225 ret = read_from_scanner(s,&s->cal_image);
3226 if(ret){
3227 DBG (5, "finecal_get_line: can't read from scanner\n");
3228 return ret;
3229 }
3230 }
3231 /* convert the raw data into normal packed pixel data */
3232 descramble_raw(s, &s->cal_image);
3233
3234 /* average the columns of pixels together and put the results in the top line(s) */
3235 for (i = 0; i < img->pages; i++)
3236 {
3237 unsigned char *linepix = img->buffer + i * img->width_bytes * img->height;
3238 unsigned char *avgpix = img->buffer + i * img->width_bytes;
3239 for (j = 0; j < img->width_bytes; j++)
3240 {
3241 int total = 0;
3242
3243 for (k = 0; k < img->height; k++)
3244 total += linepix[j + k * img->width_bytes];
3245
3246 avgpix[j] = (total + round_offset) / img->height;
3247 }
3248 }
3249
3250 DBG (10, "finecal_get_line: finish\n");
3251 return ret;
3252 }
3253
3254 /* roundf() is c99, so we provide our own, though this version won't return -0 */
3255 static float
round2(float x)3256 round2(float x)
3257 {
3258 return (float)(x >= 0.0) ? (int)(x+0.5) : (int)(x-0.5);
3259 }
3260
3261 static SANE_Status
finecal(struct scanner *s)3262 finecal(struct scanner *s)
3263 {
3264 SANE_Status ret = SANE_STATUS_GOOD;
3265
3266 int max_pages;
3267 int gain_delta = 0xff - 0xbf;
3268 float *gain_slope, *last_error;
3269 int i, j, k, idx, try_count, cal_good;
3270
3271 DBG (10, "finecal: start\n");
3272
3273 if (s->model == MODEL_S300 || s->model == MODEL_S1300i) { /* S300, S1300 */
3274 max_pages = 2;
3275 }
3276 else /* fi-60f, S1100 */
3277 {
3278 max_pages = 1;
3279 }
3280
3281 /* set fine dark offset to 0 and fix all fine gains to lowest parameter (0xFF) */
3282 for (i = 0; i < s->sendcal.width_bytes * s->sendcal.pages / 2; i++)
3283 {
3284 s->sendcal.buffer[i*2] = 0;
3285 s->sendcal.buffer[i*2+1] = 0xff;
3286 }
3287 ret = finecal_send_cal(s);
3288 if(ret) return ret;
3289
3290 /* grab rows with lamp on */
3291 ret = lamp(s,1);
3292 if(ret){
3293 DBG (5, "finecal: error lamp on\n");
3294 return ret;
3295 }
3296
3297 /* read the low-gain average of 16 lines */
3298 ret = finecal_get_line(s, &s->darkcal);
3299 if(ret) return ret;
3300
3301 /* set fine dark offset to 0 and fine gain to a fixed higher-gain parameter (0xBF) */
3302 for (i = 0; i < s->sendcal.width_bytes * s->sendcal.pages / 2; i++)
3303 {
3304 s->sendcal.buffer[i*2] = 0;
3305 s->sendcal.buffer[i*2+1] = 0xbf;
3306 }
3307 ret = finecal_send_cal(s);
3308 if(ret) return ret;
3309
3310 /* read the high-gain average of 16 lines */
3311 ret = finecal_get_line(s, &s->lightcal);
3312 if(ret) return ret;
3313
3314 /* calculate the per pixel slope of pixel value delta over gain delta */
3315 gain_slope = malloc(s->lightcal.width_bytes * s->lightcal.pages * sizeof(float));
3316 if (!gain_slope)
3317 return SANE_STATUS_NO_MEM;
3318 idx = 0;
3319 for (i = 0; i < s->lightcal.pages; i++)
3320 {
3321 for (j = 0; j < s->lightcal.width_pix; j++)
3322 {
3323 for (k = 0; k < 3; k++)
3324 {
3325 int value_delta = s->lightcal.buffer[idx] - s->darkcal.buffer[idx];
3326 /* limit this slope to 1 or less, to avoid overshoot if the lightcal ref input is clipped at 255 */
3327 if (value_delta < gain_delta)
3328 gain_slope[idx] = -1.0;
3329 else
3330 gain_slope[idx] = (float) -gain_delta / value_delta;
3331 idx++;
3332 }
3333 }
3334 }
3335
3336 /* keep track of the last iteration's pixel error. If we overshoot, we can reduce the value of the gain slope */
3337 last_error = malloc(s->lightcal.width_bytes * s->lightcal.pages * sizeof(float));
3338 if (!last_error)
3339 {
3340 free(gain_slope);
3341 return SANE_STATUS_NO_MEM;
3342 }
3343 for (i = 0; i < s->lightcal.width_bytes * s->lightcal.pages; i++)
3344 last_error[i] = 0.0;
3345
3346 /* fine calibration feedback loop */
3347 try_count = 8;
3348 while (try_count > 0)
3349 {
3350 int min_value[2][3], max_value[2][3];
3351 float avg_value[2][3], variance[2][3];
3352 int high_pegs = 0, low_pegs = 0;
3353 try_count--;
3354
3355 /* clear statistics arrays */
3356 for (i = 0; i < max_pages; i++)
3357 {
3358 for (k = 0; k < 3; k++)
3359 {
3360 min_value[i][k] = 0xff;
3361 max_value[i][k] = 0;
3362 avg_value[i][k] = 0;
3363 variance[i][k] = 0;
3364 }
3365 }
3366
3367 /* gather statistics and calculate new fine gain parameters based on observed error and the value/gain slope */
3368 idx = 0;
3369 for (i = 0; i < max_pages; i++)
3370 {
3371 for (j = 0; j < s->lightcal.width_pix; j++)
3372 {
3373 for (k = 0; k < 3; k++)
3374 {
3375 int pixvalue = s->lightcal.buffer[idx];
3376 float pixerror = (fine_gain_target[i] * s->white_factor[k] - pixvalue);
3377 int oldgain = s->sendcal.buffer[idx * 2 + 1];
3378 int newgain;
3379 /* if we overshot the last correction, reduce the gain_slope */
3380 if (pixerror * last_error[idx] < 0.0)
3381 gain_slope[idx] *= 0.75;
3382 last_error[idx] = pixerror;
3383 /* set the new gain */
3384 newgain = oldgain + (int) round2(pixerror * gain_slope[idx]);
3385 if (newgain < 0)
3386 {
3387 low_pegs++;
3388 s->sendcal.buffer[idx * 2 + 1] = 0;
3389 }
3390 else if (newgain > 0xff)
3391 {
3392 high_pegs++;
3393 s->sendcal.buffer[idx * 2 + 1] = 0xff;
3394 }
3395 else
3396 s->sendcal.buffer[idx * 2 + 1] = newgain;
3397 /* update statistics */
3398 min_value[i][k] = MIN(min_value[i][k], pixvalue);
3399 max_value[i][k] = MAX(max_value[i][k], pixvalue);
3400 avg_value[i][k] += pixerror;
3401 variance[i][k] += (pixerror * pixerror);
3402 idx++;
3403 }
3404 }
3405 }
3406 /* finish the statistics calculations */
3407 cal_good = 1;
3408 for (i = 0; i < max_pages; i++)
3409 {
3410 for (k = 0; k < 3; k++)
3411 {
3412 float sum = avg_value[i][k];
3413 float sum2 = variance[i][k];
3414 avg_value[i][k] = sum / s->lightcal.width_pix;
3415 variance[i][k] = ((sum2 - (sum * sum / s->lightcal.width_pix)) / s->lightcal.width_pix);
3416 /* if any color channel is too far out of whack, set cal_good to 0 so we'll iterate again */
3417 if (fabs(avg_value[i][k]) > 1.0 || variance[i][k] > 3.0)
3418 cal_good = 0;
3419 }
3420 }
3421
3422 /* print debug info */
3423 DBG (15, "finecal: -------------------- Gain\n");
3424 DBG (15, "finecal: RGB Average Error - Front: (%.1f,%.1f,%.1f) - Back: (%.1f,%.1f,%.1f)\n",
3425 avg_value[0][0], avg_value[0][1], avg_value[0][2], avg_value[1][0], avg_value[1][1], avg_value[1][2]);
3426 DBG (15, "finecal: RGB Maximum - Front: (%i,%i,%i) - Back: (%i,%i,%i)\n",
3427 max_value[0][0], max_value[0][1], max_value[0][2], max_value[1][0], max_value[1][1], max_value[1][2]);
3428 DBG (15, "finecal: RGB Minimum - Front: (%i,%i,%i) - Back: (%i,%i,%i)\n",
3429 min_value[0][0], min_value[0][1], min_value[0][2], min_value[1][0], min_value[1][1], min_value[1][2]);
3430 DBG (15, "finecal: Variance - Front: (%.1f,%.1f,%.1f) - Back: (%.1f,%.1f,%.1f)\n",
3431 variance[0][0], variance[0][1], variance[0][2], variance[1][0], variance[1][1], variance[1][2]);
3432 DBG (15, "finecal: Pegged gain parameters - High (0xff): %i - Low (0): %i\n", high_pegs, low_pegs);
3433
3434 /* break out of the loop if our calibration is done */
3435 if (cal_good) break;
3436
3437 /* send the new calibration and read a new line */
3438 ret = finecal_send_cal(s);
3439 if(ret) { free(gain_slope); free(last_error); return ret; }
3440 ret = finecal_get_line(s, &s->lightcal);
3441 if(ret) { free(gain_slope); free(last_error); return ret; }
3442 }
3443
3444 /* release the memory for the reference slope data */
3445 free(gain_slope);
3446 free(last_error);
3447
3448 DBG (10, "finecal: finish\n");
3449 return ret;
3450 }
3451
3452 /*
3453 * set scanner lamp brightness
3454 */
3455 static SANE_Status
lamp(struct scanner *s, unsigned char set)3456 lamp(struct scanner *s, unsigned char set)
3457 {
3458 SANE_Status ret = SANE_STATUS_GOOD;
3459 unsigned char cmd[2];
3460 size_t cmdLen = 2;
3461 unsigned char stat[1];
3462 size_t statLen = 1;
3463
3464 DBG (10, "lamp: start (%d)\n", set);
3465
3466 /*send cmd*/
3467 cmd[0] = 0x1b;
3468 cmd[1] = 0xd0;
3469
3470 ret = do_cmd(
3471 s, 0,
3472 cmd, cmdLen,
3473 NULL, 0,
3474 stat, &statLen
3475 );
3476 if(ret){
3477 DBG (5, "lamp: error sending cmd\n");
3478 return ret;
3479 }
3480 if(stat[0] != 6){
3481 DBG (5, "lamp: cmd bad status?\n");
3482 return SANE_STATUS_IO_ERROR;
3483 }
3484
3485 /*send payload*/
3486 cmd[0] = set;
3487 cmdLen = 1;
3488 statLen = 1;
3489
3490 ret = do_cmd(
3491 s, 0,
3492 cmd, cmdLen,
3493 NULL, 0,
3494 stat, &statLen
3495 );
3496 if(ret){
3497 DBG (5, "lamp: error sending payload\n");
3498 return ret;
3499 }
3500 if(stat[0] != 6){
3501 DBG (5, "lamp: payload bad status?\n");
3502 return SANE_STATUS_IO_ERROR;
3503 }
3504
3505 DBG (10, "lamp: finish\n");
3506 return ret;
3507 }
3508
3509 static SANE_Status
set_window(struct scanner *s, int window)3510 set_window(struct scanner *s, int window)
3511 {
3512 SANE_Status ret = SANE_STATUS_GOOD;
3513
3514 unsigned char cmd[] = {0x1b, 0xd1};
3515 size_t cmdLen = sizeof(cmd);
3516 unsigned char stat[] = {0};
3517 size_t statLen = sizeof(stat);
3518 unsigned char * payload;
3519 size_t paylen = SET_WINDOW_LEN;
3520
3521 DBG (10, "set_window: start, window %d\n",window);
3522
3523 switch (window) {
3524 case WINDOW_COARSECAL:
3525 payload = s->setWindowCoarseCal;
3526 paylen = s->setWindowCoarseCalLen;
3527 break;
3528 case WINDOW_FINECAL:
3529 payload = s->setWindowFineCal;
3530 paylen = s->setWindowFineCalLen;
3531 break;
3532 case WINDOW_SENDCAL:
3533 payload = s->setWindowSendCal;
3534 paylen = s->setWindowSendCalLen;
3535 break;
3536 case WINDOW_SCAN:
3537 payload = s->setWindowScan;
3538 paylen = s->setWindowScanLen;
3539 set_SW_ypix(payload,s->fullscan.height);
3540 break;
3541 default:
3542 DBG (5, "set_window: unknown window\n");
3543 return SANE_STATUS_INVAL;
3544 }
3545
3546 /*send cmd*/
3547 ret = do_cmd(
3548 s, 0,
3549 cmd, cmdLen,
3550 NULL, 0,
3551 stat, &statLen
3552 );
3553 if(ret){
3554 DBG (5, "set_window: error sending cmd\n");
3555 return ret;
3556 }
3557 if(stat[0] != 6){
3558 DBG (5, "set_window: cmd bad status?\n");
3559 return SANE_STATUS_IO_ERROR;
3560 }
3561
3562 /*send payload*/
3563 statLen = 1;
3564
3565 ret = do_cmd(
3566 s, 0,
3567 payload, paylen,
3568 NULL, 0,
3569 stat, &statLen
3570 );
3571 if(ret){
3572 DBG (5, "set_window: error sending payload\n");
3573 return ret;
3574 }
3575 if(stat[0] != 6){
3576 DBG (5, "set_window: payload bad status?\n");
3577 return SANE_STATUS_IO_ERROR;
3578 }
3579
3580 DBG (10, "set_window: finish\n");
3581 return ret;
3582 }
3583
3584 /* instead of internal brightness/contrast/gamma
3585 scanners uses 12bit x 12bit LUT
3586 default is linear table of slope 1
3587 brightness and contrast inputs are -127 to +127
3588
3589 contrast rotates slope of line around central input val
3590
3591 high low
3592 . x .
3593 . x . xx
3594 out . x . xxxxxxxx
3595 . x xx
3596 ....x....... ............
3597 in in
3598
3599 then brightness moves line vertically, and clamps to 8bit
3600
3601 bright dark
3602 . xxxxxxxx .
3603 . x .
3604 out x . x
3605 . . x
3606 ............ xxxxxxxx....
3607 in in
3608 */
3609 static SANE_Status
send_lut(struct scanner *s)3610 send_lut (struct scanner *s)
3611 {
3612 SANE_Status ret=SANE_STATUS_GOOD;
3613
3614 unsigned char cmd[] = {0x1b, 0xc5};
3615 size_t cmdLen = 2;
3616 unsigned char stat[1];
3617 size_t statLen = 1;
3618 unsigned char *out;
3619 size_t outLen;
3620
3621 int i, j;
3622 double b, slope, offset;
3623 int width;
3624 int height;
3625
3626 DBG (10, "send_lut: start\n");
3627
3628 if (s->model == MODEL_S1100){
3629 outLen = 0x200;
3630 width = outLen / 2; /* 1 color, 2 bytes */
3631 height = width; /* square table */
3632 }
3633 else if (s->model == MODEL_FI65F){
3634 outLen = 0x600;
3635 width = outLen / 6; /* 3 color, 2 bytes */
3636 height = width; /* square table */
3637 }
3638 else {
3639 outLen = 0x6000;
3640 width = outLen / 6; /* 3 colors, 2 bytes */
3641 height = width; /* square table */
3642 }
3643 out = ( unsigned char *)malloc(outLen*sizeof(unsigned char));
3644 if (out == NULL){
3645 return SANE_STATUS_NO_MEM;
3646 }
3647
3648 /* contrast is converted to a slope [0,90] degrees:
3649 * first [-127,127] to [0,254] then to [0,1]
3650 * then multiply by PI/2 to convert to radians
3651 * then take the tangent to get slope (T.O.A)
3652 * then multiply by the normal linear slope
3653 * because the table may not be square, i.e. 1024x256*/
3654 slope = tan(((double)s->contrast+127)/254 * M_PI/2);
3655
3656 /* contrast slope must stay centered, so figure
3657 * out vertical offset at central input value */
3658 offset = height/2 - slope*width/2;
3659
3660 /* convert the user brightness setting (-127 to +127)
3661 * into a scale that covers the range required
3662 * to slide the contrast curve entirely off the table */
3663 b = ((double)s->brightness/127) * (slope*(width-1) + offset);
3664
3665 DBG (15, "send_lut: %d %f %d %f %f\n", s->brightness, b,
3666 s->contrast, slope, offset);
3667
3668 for(i=0;i<width;i++){
3669 j=slope*i + offset + b;
3670
3671 j = MAX(j, 0);
3672 j = MIN(j, height-1);
3673
3674 if (s->model == MODEL_S1100){
3675 /*only one table, be order*/
3676 out[i*2] = (j >> 8) & 0xff;
3677 out[i*2+1] = j & 0xff;
3678 }
3679 else if (s->model == MODEL_FI65F){
3680 /*first table, be order*/
3681 out[i*2] = (j >> 8) & 0xff;
3682 out[i*2+1] = j & 0xff;
3683
3684 /*second table, be order*/
3685 out[width*2 + i*2] = (j >> 8) & 0xff;
3686 out[width*2 + i*2+1] = j & 0xff;
3687
3688 /*third table, be order*/
3689 out[width*4 + i*2] = (j >> 8) & 0xff;
3690 out[width*4 + i*2+1] = j & 0xff;
3691 }
3692 else {
3693 /*first table, le order*/
3694 out[i*2] = j & 0xff;
3695 out[i*2+1] = (j >> 8) & 0x0f;
3696
3697 /*second table, le order*/
3698 out[width*2 + i*2] = j & 0xff;
3699 out[width*2 + i*2+1] = (j >> 8) & 0x0f;
3700
3701 /*third table, le order*/
3702 out[width*4 + i*2] = j & 0xff;
3703 out[width*4 + i*2+1] = (j >> 8) & 0x0f;
3704 }
3705 }
3706
3707 ret = do_cmd(
3708 s, 0,
3709 cmd, cmdLen,
3710 NULL, 0,
3711 stat, &statLen
3712 );
3713 if(ret){
3714 DBG (5, "send_lut: error sending cmd\n");
3715 return ret;
3716 }
3717 if(stat[0] != 6){
3718 DBG (5, "send_lut: cmd bad status?\n");
3719 return SANE_STATUS_IO_ERROR;
3720 }
3721
3722 statLen = 1;
3723 ret = do_cmd(
3724 s, 0,
3725 out, outLen,
3726 NULL, 0,
3727 stat, &statLen
3728 );
3729 if(ret){
3730 DBG (5, "send_lut: error sending out\n");
3731 return ret;
3732 }
3733 if(stat[0] != 6){
3734 DBG (5, "send_lut: out bad status?\n");
3735 return SANE_STATUS_IO_ERROR;
3736 }
3737
3738 DBG (10, "send_lut: finish\n");
3739
3740 return ret;
3741 }
3742
3743 static SANE_Status
get_hardware_status(struct scanner *s)3744 get_hardware_status (struct scanner *s)
3745 {
3746 SANE_Status ret = SANE_STATUS_GOOD;
3747
3748 DBG (10, "get_hardware_status: start\n");
3749
3750 /* only run this once every second */
3751 if (s->last_ghs < time(NULL)) {
3752
3753 unsigned char cmd[2];
3754 size_t cmdLen = sizeof(cmd);
3755 unsigned char pay[4];
3756 size_t payLen = sizeof(pay);
3757
3758 DBG (15, "get_hardware_status: running\n");
3759
3760 cmd[0] = 0x1b;
3761 cmd[1] = 0x33;
3762
3763 ret = do_cmd(
3764 s, 0,
3765 cmd, cmdLen,
3766 NULL, 0,
3767 pay, &payLen
3768 );
3769 if(ret){
3770 DBG (5, "get_hardware_status: error sending cmd\n");
3771 return ret;
3772 }
3773
3774 hexdump(5,"ghspayload: ", pay, payLen);
3775
3776 s->last_ghs = time(NULL);
3777
3778 s->hw_top = ((pay[0] >> 7) & 0x01);
3779 s->hw_hopper = !((pay[0] >> 6) & 0x01);
3780 s->hw_adf_open = ((pay[0] >> 5) & 0x01);
3781
3782 s->hw_sleep = ((pay[1] >> 7) & 0x01);
3783 s->hw_scan_sw = ((pay[1] >> 0) & 0x01);
3784 }
3785
3786 DBG (10, "get_hardware_status: finish\n");
3787
3788 return ret;
3789 }
3790
3791 static SANE_Status
object_position(struct scanner *s, int ingest)3792 object_position(struct scanner *s, int ingest)
3793 {
3794 SANE_Status ret = SANE_STATUS_GOOD;
3795 int i;
3796 unsigned char cmd[2];
3797 size_t cmdLen = sizeof(cmd);
3798 unsigned char stat[1];
3799 size_t statLen = sizeof(stat);
3800 unsigned char pay[2];
3801 size_t payLen = sizeof(pay);
3802
3803 DBG (10, "object_position: start\n");
3804
3805 i = (ingest)?5:1;
3806
3807 while(i--){
3808 /*send paper load cmd*/
3809 cmd[0] = 0x1b;
3810 cmd[1] = 0xd4;
3811 statLen = 1;
3812
3813 ret = do_cmd(
3814 s, 0,
3815 cmd, cmdLen,
3816 NULL, 0,
3817 stat, &statLen
3818 );
3819 if(ret){
3820 DBG (5, "object_position: error sending cmd\n");
3821 return ret;
3822 }
3823 if(stat[0] != 6){
3824 DBG (5, "object_position: cmd bad status? %d\n",stat[0]);
3825 continue;
3826 }
3827
3828 /*send payload*/
3829 statLen = 1;
3830 payLen = 1;
3831 pay[0] = ingest;
3832
3833 ret = do_cmd(
3834 s, 0,
3835 pay, payLen,
3836 NULL, 0,
3837 stat, &statLen
3838 );
3839 if(ret){
3840 DBG (5, "object_position: error sending payload\n");
3841 return ret;
3842 }
3843 if(stat[0] == 6){
3844 DBG (5, "object_position: found paper?\n");
3845 break;
3846 }
3847 else if(stat[0] == 0x15 || stat[0] == 0){
3848 DBG (5, "object_position: no paper?\n");
3849 ret=SANE_STATUS_NO_DOCS;
3850 continue;
3851 }
3852 else{
3853 DBG (5, "object_position: payload bad status?\n");
3854 return SANE_STATUS_IO_ERROR;
3855 }
3856 }
3857
3858 DBG (10, "object_position: finish\n");
3859 return ret;
3860 }
3861
3862 static SANE_Status
scan(struct scanner *s)3863 scan(struct scanner *s)
3864 {
3865 SANE_Status ret=SANE_STATUS_GOOD;
3866 unsigned char cmd[] = {0x1b, 0xd2};
3867 size_t cmdLen = 2;
3868 unsigned char stat[1];
3869 size_t statLen = 1;
3870
3871 DBG (10, "scan: start\n");
3872
3873 if(s->model == MODEL_S300 || s->model == MODEL_S1100 || s->model == MODEL_S1300i){
3874 cmd[1] = 0xd6;
3875 }
3876
3877 ret = do_cmd(
3878 s, 0,
3879 cmd, cmdLen,
3880 NULL, 0,
3881 stat, &statLen
3882 );
3883 if(ret){
3884 DBG (5, "scan: error sending cmd\n");
3885 return ret;
3886 }
3887 if(stat[0] != 6){
3888 DBG (5, "scan: cmd bad status?\n");
3889 return SANE_STATUS_IO_ERROR;
3890 }
3891
3892 DBG (10, "scan: finish\n");
3893
3894 return ret;
3895 }
3896
3897 /*
3898 * Called by SANE to read data.
3899 *
3900 * From the SANE spec:
3901 * This function is used to read image data from the device
3902 * represented by handle h. Argument buf is a pointer to a memory
3903 * area that is at least maxlen bytes long. The number of bytes
3904 * returned is stored in *len. A backend must set this to zero when
3905 * the call fails (i.e., when a status other than SANE_STATUS_GOOD is
3906 * returned).
3907 *
3908 * When the call succeeds, the number of bytes returned can be
3909 * anywhere in the range from 0 to maxlen bytes.
3910 */
3911 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len)3912 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len)
3913 {
3914 struct scanner *s = (struct scanner *) handle;
3915 SANE_Status ret=SANE_STATUS_GOOD;
3916 struct page * page;
3917
3918 DBG (10, "sane_read: start si:%d len:%d max:%d\n",s->side,*len,max_len);
3919
3920 *len = 0;
3921
3922 /* cancelled? */
3923 if(!s->started){
3924 DBG (5, "sane_read: call sane_start first\n");
3925 return SANE_STATUS_CANCELLED;
3926 }
3927
3928 page = &s->pages[s->side];
3929
3930 /* have sent all of current buffer */
3931 if(s->fullscan.done && page->done){
3932 DBG (10, "sane_read: returning eof\n");
3933
3934 /*S1100 needs help to turn off button*/
3935 if(s->model == MODEL_S1100){
3936 usleep(15000);
3937
3938 /* eject paper */
3939 ret = object_position(s,EPJITSU_PAPER_EJECT);
3940 if (ret != SANE_STATUS_GOOD && ret != SANE_STATUS_NO_DOCS) {
3941 DBG (5, "sane_read: ERROR: failed to eject\n");
3942 return ret;
3943 }
3944
3945 /* reset flashing button? */
3946 ret = six5(s);
3947 if (ret != SANE_STATUS_GOOD) {
3948 DBG (5, "sane_read: ERROR: failed to six5\n");
3949 return ret;
3950 }
3951 }
3952
3953 return SANE_STATUS_EOF;
3954 }
3955
3956 /* scan not finished, get more into block buffer */
3957 if(!s->fullscan.done)
3958 {
3959 /* block buffer currently empty, clean up */
3960 if(!s->block_xfr.rx_bytes)
3961 {
3962 /* block buffer bigger than remainder of scan, shrink block */
3963 int remainTotal = s->fullscan.total_bytes - s->fullscan.rx_bytes;
3964 if(remainTotal < s->block_xfr.total_bytes)
3965 {
3966 DBG (15, "sane_read: shrinking block to %lu\n", (unsigned long)remainTotal);
3967 s->block_xfr.total_bytes = remainTotal;
3968 }
3969 /* send d3 cmd for S300, S1100, S1300 */
3970 if(s->model == MODEL_S300 || s->model == MODEL_S1100 || s->model == MODEL_S1300i)
3971 {
3972 unsigned char cmd[] = {0x1b, 0xd3};
3973 size_t cmdLen = 2;
3974 unsigned char stat[1];
3975 size_t statLen = 1;
3976
3977 DBG (15, "sane_read: d3\n");
3978
3979 ret = do_cmd(
3980 s, 0,
3981 cmd, cmdLen,
3982 NULL, 0,
3983 stat, &statLen
3984 );
3985 if(ret){
3986 DBG (5, "sane_read: error sending d3 cmd\n");
3987 return ret;
3988 }
3989 if(stat[0] != 6){
3990 DBG (5, "sane_read: cmd bad status?\n");
3991 return SANE_STATUS_IO_ERROR;
3992 }
3993 }
3994 }
3995
3996 ret = read_from_scanner(s, &s->block_xfr);
3997 if(ret){
3998 DBG (5, "sane_read: can't read from scanner\n");
3999 return ret;
4000 }
4001
4002 /* block filled, copy to front/back */
4003 if(s->block_xfr.done)
4004 {
4005 DBG (15, "sane_read: block buffer full\n");
4006
4007 /* convert the raw color data into normal packed pixel data */
4008 descramble_raw(s, &s->block_xfr);
4009
4010 s->block_xfr.done = 0;
4011
4012 /* get the 0x43 cmd for the S300, S1100, S1300 */
4013 if(s->model == MODEL_S300 || s->model == MODEL_S1100 || s->model == MODEL_S1300i){
4014
4015 unsigned char cmd[] = {0x1b, 0x43};
4016 size_t cmdLen = 2;
4017 unsigned char in[10];
4018 size_t inLen = 10;
4019
4020 ret = do_cmd(
4021 s, 0,
4022 cmd, cmdLen,
4023 NULL, 0,
4024 in, &inLen
4025 );
4026 hexdump(15, "cmd 43: ", in, inLen);
4027
4028 if(ret){
4029 DBG (5, "sane_read: error sending 43 cmd\n");
4030 return ret;
4031 }
4032
4033 /*copy backside data into buffer*/
4034 if( s->source == SOURCE_ADF_DUPLEX || s->source == SOURCE_ADF_BACK )
4035 ret = copy_block_to_page(s, SIDE_BACK);
4036
4037 /*copy frontside data into buffer*/
4038 if( s->source != SOURCE_ADF_BACK )
4039 ret = copy_block_to_page(s, SIDE_FRONT);
4040
4041 if(ret){
4042 DBG (5, "sane_read: can't copy to front/back\n");
4043 return ret;
4044 }
4045
4046 s->fullscan.rx_bytes += s->block_xfr.rx_bytes;
4047
4048 /* autodetect mode, check for change length */
4049 if( s->source != SOURCE_FLATBED && !s->page_height ){
4050 int get = (in[6] << 8) | in[7];
4051
4052 /*always have to get full blocks*/
4053 if(get % s->block_img.height){
4054 get += s->block_img.height - (get % s->block_img.height);
4055 }
4056
4057 if(get < s->fullscan.height){
4058 DBG (15, "sane_read: paper out? %d\n",get);
4059 s->fullscan.total_bytes = s->fullscan.width_bytes * get;
4060 }
4061 }
4062 }
4063
4064 else { /*fi-60f*/
4065 ret = copy_block_to_page(s, SIDE_FRONT);
4066 if(ret){
4067 DBG (5, "sane_read: can't copy to front/back\n");
4068 return ret;
4069 }
4070
4071 s->fullscan.rx_bytes += s->block_xfr.rx_bytes;
4072 }
4073
4074 /* reset for next pass */
4075 update_transfer_totals(&s->block_xfr);
4076
4077 /* scan now finished */
4078 if(s->fullscan.rx_bytes == s->fullscan.total_bytes){
4079 DBG (15, "sane_read: last block\n");
4080 s->fullscan.done = 1;
4081 }
4082 }
4083 }
4084
4085 *len = page->bytes_scanned - page->bytes_read;
4086 *len = MIN(*len, max_len);
4087
4088 if(*len){
4089 DBG (10, "sane_read: copy rx:%d tx:%d tot:%d len:%d\n",
4090 page->bytes_scanned, page->bytes_read, page->bytes_total,*len);
4091
4092 memcpy(buf, page->image->buffer + page->bytes_read, *len);
4093 page->bytes_read += *len;
4094 }
4095
4096 /* sent it all, return eof on next read */
4097 if(page->bytes_read == page->bytes_scanned && s->fullscan.done){
4098 DBG (10, "sane_read: side done\n");
4099 page->done = 1;
4100 }
4101
4102 DBG (10, "sane_read: finish si:%d len:%d max:%d\n",s->side,*len,max_len);
4103
4104 return ret;
4105 }
4106
4107 static SANE_Status
six5(struct scanner *s)4108 six5 (struct scanner *s)
4109 {
4110 SANE_Status ret = SANE_STATUS_GOOD;
4111
4112 unsigned char cmd[2];
4113 size_t cmdLen = sizeof(cmd);
4114 unsigned char stat[1];
4115 size_t statLen = sizeof(stat);
4116
4117 DBG (10, "six5: start\n");
4118
4119 cmd[0] = 0x1b;
4120 cmd[1] = 0x65;
4121 statLen = 1;
4122
4123 ret = do_cmd(
4124 s, 0,
4125 cmd, cmdLen,
4126 NULL, 0,
4127 stat, &statLen
4128 );
4129 if(ret){
4130 DBG (5, "six5: error sending cmd\n");
4131 return ret;
4132 }
4133 if(stat[0] != 6){
4134 DBG (5, "six5: cmd bad status? %d\n",stat[0]);
4135 return SANE_STATUS_IO_ERROR;
4136 }
4137
4138 DBG (10, "six5: finish\n");
4139
4140 return ret;
4141 }
4142
4143 /* de-scrambles the raw data from the scanner into the image buffer */
4144 /* the output image might be lower dpi than input image, so we scale horizontally */
4145 /* if the input image is mirrored left to right, we do not correct it here */
4146 /* if the input image has padding (at the end or between heads), it is removed here */
4147 static SANE_Status
descramble_raw(struct scanner *s, struct transfer * tp)4148 descramble_raw(struct scanner *s, struct transfer * tp)
4149 {
4150 SANE_Status ret = SANE_STATUS_GOOD;
4151 unsigned char *p_out = tp->image->buffer;
4152 int height = tp->total_bytes / tp->line_stride;
4153 int i, j, k;
4154
4155 /* raw gray data handled in another function */
4156 if(tp->mode == MODE_GRAYSCALE){
4157 return descramble_raw_gray(s, tp);
4158 }
4159
4160 DBG(15, "descramble_raw: start\n");
4161
4162 if (s->model == MODEL_S300 || s->model == MODEL_S1300i) {
4163 for (i = 0; i < 2; i++){ /* page, front/back */
4164 for (j = 0; j < height; j++){ /* row (y)*/
4165 int curr_col = 0;
4166 int r=0, g=0, b=0, ppc=0;
4167 int g_offset=0, b_offset=0;
4168
4169 for (k = 0; k <= tp->plane_width; k++){ /* column (x) */
4170 int this_col = k*tp->image->x_res/tp->x_res;
4171
4172 /* going to change output pixel, dump rgb and reset */
4173 if(ppc && curr_col != this_col){
4174 *p_out = r/ppc;
4175 p_out++;
4176
4177 *p_out = g/ppc;
4178 p_out++;
4179
4180 *p_out = b/ppc;
4181 p_out++;
4182
4183 r = g = b = ppc = 0;
4184
4185 curr_col = this_col;
4186 }
4187
4188 if(k == tp->plane_width || this_col >= tp->image->width_pix){
4189 break;
4190 }
4191
4192 /* if we're using an S1300i with scan resolution 225 or 300, on AC power, the color planes are shifted */
4193 if(s->model == MODEL_S1300i && !s->usb_power && (tp->x_res == 225 || tp->x_res == 300) && tp != &s->cal_image && k + 2 <= tp->plane_width){
4194 g_offset = 3;
4195 b_offset = 6;
4196 }
4197
4198 /*red is first*/
4199 r += tp->raw_data[j*tp->line_stride + k*3 + i];
4200
4201 /*green is second*/
4202 g += tp->raw_data[j*tp->line_stride + tp->plane_stride + k*3 + i + g_offset];
4203
4204 /*blue is third*/
4205 b += tp->raw_data[j*tp->line_stride + 2*tp->plane_stride + k*3 + i + b_offset];
4206
4207 ppc++;
4208 }
4209 }
4210 }
4211 }
4212 else if (s->model == MODEL_S1100){
4213 for (j = 0; j < height; j++){ /* row (y)*/
4214 int curr_col = 0;
4215 int r=0, g=0, b=0, ppc=0;
4216
4217 for (k = 0; k <= tp->plane_width; k++){ /* column (x) */
4218 int this_col = k*tp->image->x_res/tp->x_res;
4219
4220 /* going to change output pixel, dump rgb and reset */
4221 if(ppc && curr_col != this_col){
4222 *p_out = r/ppc;
4223 p_out++;
4224
4225 *p_out = g/ppc;
4226 p_out++;
4227
4228 *p_out = b/ppc;
4229 p_out++;
4230
4231 r = g = b = ppc = 0;
4232
4233 curr_col = this_col;
4234 }
4235
4236 if(k == tp->plane_width || this_col >= tp->image->width_pix){
4237 break;
4238 }
4239
4240 /*red is second*/
4241 r += tp->raw_data[j*tp->line_stride + tp->plane_stride + k];
4242
4243 /*green is third*/
4244 g += tp->raw_data[j*tp->line_stride + 2*tp->plane_stride + k];
4245
4246 /*blue is first*/
4247 b += tp->raw_data[j*tp->line_stride + k];
4248
4249 ppc++;
4250 }
4251 }
4252 }
4253 else { /* MODEL_FI60F or MODEL_FI65F */
4254
4255 for (j = 0; j < height; j++){ /* row (y)*/
4256 int curr_col = 0;
4257
4258 for (i = 0; i < 3; i++){ /* read head */
4259 int r=0, g=0, b=0, ppc=0;
4260
4261 for (k = 0; k <= tp->plane_width; k++){ /* column (x) within the read head */
4262 int this_col = (k+i*tp->plane_width)*tp->image->x_res/tp->x_res;
4263
4264 /* going to change output pixel, dump rgb and reset */
4265 if(ppc && curr_col != this_col){
4266 *p_out = r/ppc;
4267 p_out++;
4268
4269 *p_out = g/ppc;
4270 p_out++;
4271
4272 *p_out = b/ppc;
4273 p_out++;
4274
4275 r = g = b = ppc = 0;
4276
4277 curr_col = this_col;
4278 }
4279
4280 if(k == tp->plane_width || this_col >= tp->image->width_pix){
4281 break;
4282 }
4283
4284 /*red is first*/
4285 r += tp->raw_data[j*tp->line_stride + k*3 + i];
4286
4287 /*green is second*/
4288 g += tp->raw_data[j*tp->line_stride + tp->plane_stride + k*3 + i];
4289
4290 /*blue is third*/
4291 b += tp->raw_data[j*tp->line_stride + 2*tp->plane_stride + k*3 + i];
4292
4293 ppc++;
4294 }
4295 }
4296 }
4297 }
4298
4299 DBG(15, "descramble_raw: finish %d\n", ret);
4300
4301 return ret;
4302 }
4303
4304 /* de-scrambles the raw gray data from the scanner into the image buffer */
4305 /* the output image might be lower dpi than input image, so we scale horizontally */
4306 /* if the input image is mirrored left to right, we do not correct it here */
4307 /* if the input image has padding (at the end or between heads), it is removed here */
4308 static SANE_Status
descramble_raw_gray(struct scanner *s, struct transfer * tp)4309 descramble_raw_gray(struct scanner *s, struct transfer * tp)
4310 {
4311 SANE_Status ret = SANE_STATUS_GOOD;
4312 int height = tp->total_bytes / tp->line_stride;
4313 int row, col_out;
4314
4315 DBG(15, "descramble_raw_gray: start\n");
4316
4317 if (s->model == MODEL_FI60F || s->model == MODEL_FI65F) {
4318 for (row = 0; row < height; row++){
4319
4320 unsigned char *p_in = tp->raw_data + row * tp->line_stride;
4321 unsigned char *p_out = tp->image->buffer + row * tp->image->width_pix;
4322
4323 for (col_out = 0; col_out < tp->image->width_pix; col_out++){
4324 int col_in = col_out * tp->x_res/tp->image->x_res;
4325 int offset = col_in%tp->plane_width;
4326 int step = col_in/tp->plane_width;
4327
4328 *p_out = *(p_in + offset*3 + step);
4329 p_out++;
4330 }
4331 }
4332 }
4333
4334 else{
4335 DBG(5, "internal error: descramble_raw_gray not supported\n");
4336 ret = SANE_STATUS_INVAL;
4337 }
4338
4339 DBG(15, "descramble_raw_gray: finish %d\n", ret);
4340 return ret;
4341 }
4342
4343 /* fills block buffer a little per pass */
4344 static SANE_Status
read_from_scanner(struct scanner *s, struct transfer * tp)4345 read_from_scanner(struct scanner *s, struct transfer * tp)
4346 {
4347 SANE_Status ret=SANE_STATUS_GOOD;
4348 size_t bytes = MAX_IMG_PASS;
4349 size_t remainBlock = tp->total_bytes - tp->rx_bytes + 8;
4350 unsigned char * buf;
4351 size_t bufLen;
4352
4353 /* determine amount to ask for, S1300i wants big requests */
4354 if(s->model != MODEL_S1300i){
4355 bytes = MIN(bytes, remainBlock);
4356 }
4357
4358 if (tp->image == NULL)
4359 {
4360 DBG(5, "internal error: read_from_scanner called with no destination image.\n");
4361 return SANE_STATUS_INVAL;
4362 }
4363
4364 DBG (10, "read_from_scanner: start rB:%lu len:%lu\n",
4365 (unsigned long)remainBlock, (unsigned long)bytes);
4366
4367 if(!bytes){
4368 DBG(10, "read_from_scanner: no bytes!\n");
4369 return SANE_STATUS_INVAL;
4370 }
4371
4372 bufLen = bytes;
4373 buf = malloc(bufLen);
4374 if(!buf){
4375 DBG (5, "read_from_scanner: failed to alloc mem\n");
4376 return SANE_STATUS_NO_MEM;
4377 }
4378
4379 ret = do_cmd(
4380 s, 0,
4381 NULL, 0,
4382 NULL, 0,
4383 buf, &bytes
4384 );
4385
4386 /* full read or short read */
4387 if (ret == SANE_STATUS_GOOD || (ret == SANE_STATUS_EOF && bytes) ) {
4388
4389 DBG(15,"read_from_scanner: got GOOD/EOF (%lu)\n",(unsigned long)bytes);
4390
4391 if(bytes > remainBlock){
4392 DBG(15,"read_from_scanner: block too big?\n");
4393 bytes = remainBlock;
4394 }
4395
4396 if(bytes == remainBlock){
4397 DBG(15,"read_from_scanner: block done, ignoring trailer\n");
4398 bytes -= 8;
4399 tp->done = 1;
4400 }
4401
4402 memcpy(tp->raw_data + tp->rx_bytes, buf, bytes);
4403 tp->rx_bytes += bytes;
4404
4405 ret = SANE_STATUS_GOOD;
4406 }
4407 else {
4408 DBG(5, "read_from_scanner: error reading status = %d\n", ret);
4409 }
4410
4411 free(buf);
4412
4413 DBG (10, "read_from_scanner: finish rB:%lu len:%lu\n",
4414 (unsigned long)(tp->total_bytes - tp->rx_bytes + 8), (unsigned long)bytes);
4415
4416 return ret;
4417 }
4418
4419 /* copies block buffer into front or back image buffer */
4420 /* converts pixel data from input mode (color/gray) to output mode (color/gray/binary) */
4421 /* the output image might be lower dpi than input image, so we scale vertically */
4422 /* the input is already scaled horizontally and padding skipped if required */
4423 /* if the input is mirrored left to right, we fix it here */
4424 static SANE_Status
copy_block_to_page(struct scanner *s,int side)4425 copy_block_to_page(struct scanner *s,int side)
4426 {
4427 SANE_Status ret = SANE_STATUS_GOOD;
4428 struct transfer * block = &s->block_xfr;
4429 struct page * page = &s->pages[side];
4430 int image_height = block->total_bytes / block->line_stride;
4431 int page_width = page->image->width_pix;
4432 int block_page_stride = block->image->width_bytes * block->image->height;
4433 int line_reverse = (side == SIDE_BACK) || (s->model == MODEL_FI60F) || (s->model == MODEL_FI65F);
4434 int i,j,k=0;
4435
4436 int curr_in_row = s->fullscan.rx_bytes/s->fullscan.width_bytes;
4437 int last_out_row = (page->bytes_scanned / page->image->width_bytes) - 1;
4438
4439 DBG (10, "copy_block_to_page: start\n");
4440
4441 /* skip padding and tl_y */
4442 if (s->fullscan.rx_bytes + s->block_xfr.rx_bytes <= block->line_stride * page->image->y_skip_offset)
4443 {
4444 DBG (10, "copy_block_to_page: before the start? %d\n", side);
4445 return ret;
4446 }
4447 else if (s->fullscan.rx_bytes < block->line_stride * page->image->y_skip_offset)
4448 {
4449 k = page->image->y_skip_offset - s->fullscan.rx_bytes / block->line_stride;
4450 DBG (10, "copy_block_to_page: k start? %d\n", k);
4451 }
4452
4453 /* loop over all the lines in the block */
4454 for (i = k; i < image_height; i++)
4455 {
4456 /* determine source and dest rows (dpi scaling) */
4457 int this_in_row = curr_in_row + i;
4458 int this_out_row = (this_in_row - page->image->y_skip_offset) * page->image->y_res / s->fullscan.y_res;
4459 DBG (15, "copy_block_to_page: in %d out %d lastout %d\n", this_in_row, this_out_row, last_out_row);
4460 DBG (15, "copy_block_to_page: bs %d wb %d\n", page->bytes_scanned, page->image->width_bytes);
4461
4462 /* don't walk off the end of the output buffer */
4463 if(this_out_row >= page->image->height || this_out_row < 0){
4464 DBG (10, "copy_block_to_page: out of space? %d\n", side);
4465 DBG (10, "copy_block_to_page: rx:%d tx:%d tot:%d line:%d\n",
4466 page->bytes_scanned, page->bytes_read, page->bytes_total,page->image->width_bytes);
4467 return ret;
4468 }
4469
4470 /* ok, different output row, so we do the math */
4471 if(this_out_row > last_out_row){
4472
4473 unsigned char * p_in = block->image->buffer + (side * block_page_stride)
4474 + (i * block->image->width_bytes) + page->image->x_start_offset * 3;
4475 unsigned char * p_out = page->image->buffer + this_out_row * page->image->width_bytes;
4476 unsigned char * lineStart = p_out;
4477
4478 last_out_row = this_out_row;
4479
4480 if (block->mode == MODE_COLOR){
4481
4482 /* reverse order for back side or FI-60F scanner */
4483 if (line_reverse)
4484 p_in += (page_width - 1) * 3;
4485
4486 /* convert all of the pixels in this row */
4487 for (j = 0; j < page_width; j++)
4488 {
4489 unsigned char r, g, b;
4490 if (s->model == MODEL_S300 || s->model == MODEL_S1300i)
4491 { r = p_in[1]; g = p_in[2]; b = p_in[0]; }
4492 else /* MODEL_FI60F or MODEL_FI65F or MODEL_S1100 */
4493 { r = p_in[0]; g = p_in[1]; b = p_in[2]; }
4494 if (s->mode == MODE_COLOR)
4495 {
4496 *p_out++ = r;
4497 *p_out++ = g;
4498 *p_out++ = b;
4499 }
4500 else if (s->mode == MODE_GRAYSCALE)
4501 {
4502 *p_out++ = (r + g + b) / 3;
4503 }
4504 else if (s->mode == MODE_LINEART)
4505 {
4506 s->dt.buffer[j] = (r + g + b) / 3; /* stores dt temp image buffer and binarize afterward */
4507 }
4508 if (line_reverse)
4509 p_in -= 3;
4510 else
4511 p_in += 3;
4512 }
4513 }
4514
4515 /* grayscale input */
4516 else{
4517 unsigned char * p_in = block->image->buffer + (side * block_page_stride)
4518 + (i * block->image->width_bytes) + page->image->x_start_offset;
4519
4520 /* reverse order for back side or FI-60F scanner */
4521 if (line_reverse)
4522 p_in += (page_width - 1);
4523
4524 //memcpy(p_out,p_in,page->image->width_bytes);
4525
4526 for (j = 0; j < page_width; j++)
4527 {
4528 if (s->mode == MODE_GRAYSCALE)
4529 {
4530 *p_out++ = *p_in;
4531 }
4532 else if (s->mode == MODE_LINEART)
4533 {
4534 s->dt.buffer[j] = *p_in; /* stores dt temp image buffer and binarize afterward */
4535 }
4536 if (line_reverse)
4537 p_in--;
4538 else
4539 p_in++;
4540 }
4541 }
4542
4543 /* skip non-transfer pixels in block image buffer */
4544 if (line_reverse)
4545 p_in -= page->image->x_offset_bytes;
4546 else
4547 p_in += page->image->x_offset_bytes;
4548
4549 /* for MODE_LINEART, binarize the gray line stored in the temp image buffer(dt) */
4550 /* because dt.width = page_width, we pass page_width */
4551 if (s->mode == MODE_LINEART)
4552 binarize_line(s, lineStart, page_width);
4553
4554 page->bytes_scanned += page->image->width_bytes;
4555 }
4556 }
4557
4558 DBG (10, "copy_block_to_page: finish\n");
4559
4560 return ret;
4561 }
4562
4563 /*uses the threshold/threshold_curve to control binarization*/
4564 static SANE_Status
binarize_line(struct scanner *s, unsigned char *lineOut, int width)4565 binarize_line(struct scanner *s, unsigned char *lineOut, int width)
4566 {
4567 SANE_Status ret = SANE_STATUS_GOOD;
4568 int j, windowX, sum = 0;
4569
4570 /* ~1mm works best, but the window needs to have odd # of pixels */
4571 windowX = 6 * s->resolution / 150;
4572 if (!(windowX % 2)) windowX++;
4573
4574 /*second, prefill the sliding sum*/
4575 for (j = 0; j < windowX; j++)
4576 sum += s->dt.buffer[j];
4577
4578 /* third, walk the dt buffer, update the sliding sum, */
4579 /* determine threshold, output bits */
4580 for (j = 0; j < width; j++)
4581 {
4582 /*output image location*/
4583 int offset = j % 8;
4584 unsigned char mask = 0x80 >> offset;
4585 int thresh = s->threshold;
4586
4587 /* move sum/update threshold only if there is a curve*/
4588 if (s->threshold_curve)
4589 {
4590 int addCol = j + windowX/2;
4591 int dropCol = addCol - windowX;
4592
4593 if (dropCol >= 0 && addCol < width)
4594 {
4595 sum -= s->dt.buffer[dropCol];
4596 sum += s->dt.buffer[addCol];
4597 }
4598 thresh = s->dt_lut[sum/windowX];
4599 }
4600
4601 /*use average to lookup threshold*/
4602 if (s->dt.buffer[j] > thresh)
4603 *lineOut &= ~mask; /* white */
4604 else
4605 *lineOut |= mask; /* black */
4606
4607 if (offset == 7)
4608 lineOut++;
4609 }
4610
4611 return ret;
4612 }
4613
4614 /*
4615 * @@ Section 4 - SANE cleanup functions
4616 */
4617 /*
4618 * Cancels a scan.
4619 *
4620 * From the SANE spec:
4621 * This function is used to immediately or as quickly as possible
4622 * cancel the currently pending operation of the device represented by
4623 * handle h. This function can be called at any time (as long as
4624 * handle h is a valid handle) but usually affects long-running
4625 * operations only (such as image is acquisition). It is safe to call
4626 * this function asynchronously (e.g., from within a signal handler).
4627 * It is important to note that completion of this operation does not
4628 * imply that the currently pending operation has been cancelled. It
4629 * only guarantees that cancellation has been initiated. Cancellation
4630 * completes only when the cancelled call returns (typically with a
4631 * status value of SANE_STATUS_CANCELLED). Since the SANE API does
4632 * not require any other operations to be re-entrant, this implies
4633 * that a frontend must not call any other operation until the
4634 * cancelled operation has returned.
4635 */
4636 void
sane_cancel(SANE_Handle handle)4637 sane_cancel (SANE_Handle handle)
4638 {
4639 /*FIXME: actually ask the scanner to stop?*/
4640 struct scanner * s = (struct scanner *) handle;
4641 DBG (10, "sane_cancel: start\n");
4642 s->started = 0;
4643 DBG (10, "sane_cancel: finish\n");
4644 }
4645
4646 /*
4647 * Ends use of the scanner.
4648 *
4649 * From the SANE spec:
4650 * This function terminates the association between the device handle
4651 * passed in argument h and the device it represents. If the device is
4652 * presently active, a call to sane_cancel() is performed first. After
4653 * this function returns, handle h must not be used anymore.
4654 */
4655 void
sane_close(SANE_Handle handle)4656 sane_close (SANE_Handle handle)
4657 {
4658 struct scanner * s = (struct scanner *) handle;
4659
4660 DBG (10, "sane_close: start\n");
4661
4662 /* still connected- drop it */
4663 if(s->fd >= 0){
4664 sane_cancel(handle);
4665 lamp(s, 0);
4666 disconnect_fd(s);
4667 }
4668
4669 DBG (10, "sane_close: finish\n");
4670 }
4671
4672 static SANE_Status
disconnect_fd(struct scanner *s)4673 disconnect_fd (struct scanner *s)
4674 {
4675 DBG (10, "disconnect_fd: start\n");
4676
4677 if(s->fd > -1){
4678 DBG (15, "disconnecting usb device\n");
4679 sanei_usb_close (s->fd);
4680 s->fd = -1;
4681 }
4682
4683 DBG (10, "disconnect_fd: finish\n");
4684
4685 return SANE_STATUS_GOOD;
4686 }
4687
4688 static SANE_Status
destroy(struct scanner *s)4689 destroy(struct scanner *s)
4690 {
4691 SANE_Status ret = SANE_STATUS_GOOD;
4692
4693 DBG (10, "destroy: start\n");
4694
4695 teardown_buffers(s);
4696
4697 if(s->sane.name){
4698 free((void *) s->sane.name);
4699 }
4700 if(s->sane.vendor){
4701 free((void *) s->sane.vendor);
4702 }
4703 if(s->sane.model){
4704 free((void *) s->sane.model);
4705 }
4706
4707 free(s);
4708
4709 DBG (10, "destroy: finish\n");
4710 return ret;
4711 }
4712
4713 static SANE_Status
teardown_buffers(struct scanner *s)4714 teardown_buffers(struct scanner *s)
4715 {
4716 SANE_Status ret = SANE_STATUS_GOOD;
4717
4718 DBG (10, "teardown_buffers: start\n");
4719
4720 /* temporary cal data */
4721 if(s->coarsecal.buffer){
4722 free(s->coarsecal.buffer);
4723 s->coarsecal.buffer = NULL;
4724 }
4725
4726 if(s->darkcal.buffer){
4727 free(s->darkcal.buffer);
4728 s->darkcal.buffer = NULL;
4729 }
4730
4731 if(s->sendcal.buffer){
4732 free(s->sendcal.buffer);
4733 s->sendcal.buffer = NULL;
4734 }
4735
4736 if(s->cal_image.raw_data){
4737 free(s->cal_image.raw_data);
4738 s->cal_image.raw_data = NULL;
4739 }
4740
4741 if(s->cal_data.raw_data){
4742 free(s->cal_data.raw_data);
4743 s->cal_data.raw_data = NULL;
4744 }
4745
4746 /* image slice */
4747 if(s->block_img.buffer){
4748 free(s->block_img.buffer);
4749 s->block_img.buffer = NULL;
4750 }
4751 if(s->block_xfr.raw_data){
4752 free(s->block_xfr.raw_data);
4753 s->block_xfr.raw_data = NULL;
4754 }
4755
4756 /* dynamic thresh slice */
4757 if(s->dt.buffer){
4758 free(s->dt.buffer);
4759 s->dt.buffer = NULL;
4760 }
4761
4762 /* image buffer to hold frontside data */
4763 if(s->front.buffer){
4764 free(s->front.buffer);
4765 s->front.buffer = NULL;
4766 }
4767
4768 /* image buffer to hold backside data */
4769 if(s->back.buffer){
4770 free(s->back.buffer);
4771 s->back.buffer = NULL;
4772 }
4773
4774 DBG (10, "teardown_buffers: finish\n");
4775 return ret;
4776 }
4777
4778 /*
4779 * Terminates the backend.
4780 *
4781 * From the SANE spec:
4782 * This function must be called to terminate use of a backend. The
4783 * function will first close all device handles that still might be
4784 * open (it is recommended to close device handles explicitly through
4785 * a call to sane_close(), but backends are required to release all
4786 * resources upon a call to this function). After this function
4787 * returns, no function other than sane_init() may be called
4788 * (regardless of the status value returned by sane_exit(). Neglecting
4789 * to call this function may result in some resources not being
4790 * released properly.
4791 */
4792 void
sane_exit(void)4793 sane_exit (void)
4794 {
4795 struct scanner *dev, *next;
4796
4797 DBG (10, "sane_exit: start\n");
4798
4799 for (dev = scanner_devList; dev; dev = next) {
4800 next = dev->next;
4801 destroy(dev);
4802 }
4803
4804 if (sane_devArray)
4805 free (sane_devArray);
4806
4807 scanner_devList = NULL;
4808 sane_devArray = NULL;
4809
4810 DBG (10, "sane_exit: finish\n");
4811 }
4812
4813 /*
4814 * @@ Section 5 - misc helper functions
4815 */
4816 /*
4817 * take a bunch of pointers, send commands to scanner
4818 */
4819 static SANE_Status
do_cmd(struct scanner *s, int shortTime, unsigned char * cmdBuff, size_t cmdLen, unsigned char * outBuff, size_t outLen, unsigned char * inBuff, size_t * inLen )4820 do_cmd(struct scanner *s, int shortTime,
4821 unsigned char * cmdBuff, size_t cmdLen,
4822 unsigned char * outBuff, size_t outLen,
4823 unsigned char * inBuff, size_t * inLen
4824 )
4825 {
4826 /* sanei_usb overwrites the transfer size, so make some local copies */
4827 size_t loc_cmdLen = cmdLen;
4828 size_t loc_outLen = outLen;
4829 size_t loc_inLen = 0;
4830
4831 int cmdTime = USB_COMMAND_TIME;
4832 int outTime = USB_DATA_TIME;
4833 int inTime = USB_DATA_TIME;
4834
4835 int ret = 0;
4836
4837 DBG (10, "do_cmd: start\n");
4838
4839 if(shortTime){
4840 cmdTime /= 20;
4841 outTime /= 20;
4842 inTime /= 20;
4843 }
4844
4845 /* this command has a cmd component, and a place to get it */
4846 if(cmdBuff && cmdLen && cmdTime){
4847
4848 /* change timeout */
4849 sanei_usb_set_timeout(cmdTime);
4850
4851 /* write the command out */
4852 DBG(25, "cmd: writing %ld bytes, timeout %d\n", (long)cmdLen, cmdTime);
4853 hexdump(30, "cmd: >>", cmdBuff, cmdLen);
4854 ret = sanei_usb_write_bulk(s->fd, cmdBuff, &cmdLen);
4855 DBG(25, "cmd: wrote %ld bytes, retVal %d\n", (long)cmdLen, ret);
4856
4857 if(ret == SANE_STATUS_EOF){
4858 DBG(5,"cmd: got EOF, returning IO_ERROR\n");
4859 return SANE_STATUS_IO_ERROR;
4860 }
4861 if(ret != SANE_STATUS_GOOD){
4862 DBG(5,"cmd: return error '%s'\n",sane_strstatus(ret));
4863 return ret;
4864 }
4865 if(loc_cmdLen != cmdLen){
4866 DBG(5,"cmd: wrong size %ld/%ld\n", (long)loc_cmdLen, (long)cmdLen);
4867 return SANE_STATUS_IO_ERROR;
4868 }
4869 }
4870
4871 /* this command has a write component, and a place to get it */
4872 if(outBuff && outLen && outTime){
4873
4874 /* change timeout */
4875 sanei_usb_set_timeout(outTime);
4876
4877 DBG(25, "out: writing %ld bytes, timeout %d\n", (long)outLen, outTime);
4878 hexdump(30, "out: >>", outBuff, outLen);
4879 ret = sanei_usb_write_bulk(s->fd, outBuff, &outLen);
4880 DBG(25, "out: wrote %ld bytes, retVal %d\n", (long)outLen, ret);
4881
4882 if(ret == SANE_STATUS_EOF){
4883 DBG(5,"out: got EOF, returning IO_ERROR\n");
4884 return SANE_STATUS_IO_ERROR;
4885 }
4886 if(ret != SANE_STATUS_GOOD){
4887 DBG(5,"out: return error '%s'\n",sane_strstatus(ret));
4888 return ret;
4889 }
4890 if(loc_outLen != outLen){
4891 DBG(5,"out: wrong size %ld/%ld\n", (long)loc_outLen, (long)outLen);
4892 return SANE_STATUS_IO_ERROR;
4893 }
4894 }
4895
4896 /* this command has a read component, and a place to put it */
4897 if(inBuff && inLen && inTime){
4898
4899 loc_inLen = *inLen;
4900 DBG(25, "in: memset %ld bytes\n", (long)*inLen);
4901 memset(inBuff,0,*inLen);
4902
4903 /* change timeout */
4904 sanei_usb_set_timeout(inTime);
4905
4906 DBG(25, "in: reading %ld bytes, timeout %d\n", (long)*inLen, inTime);
4907 ret = sanei_usb_read_bulk(s->fd, inBuff, inLen);
4908 DBG(25, "in: retVal %d\n", ret);
4909
4910 if(ret == SANE_STATUS_EOF){
4911 DBG(5,"in: got EOF, continuing\n");
4912 }
4913 else if(ret != SANE_STATUS_GOOD){
4914 DBG(5,"in: return error '%s'\n",sane_strstatus(ret));
4915 return ret;
4916 }
4917
4918 DBG(25, "in: read %ld bytes\n", (long)*inLen);
4919 if(*inLen){
4920 hexdump(30, "in: <<", inBuff, *inLen);
4921 }
4922
4923 if(loc_inLen != *inLen){
4924 ret = SANE_STATUS_EOF;
4925 DBG(5,"in: short read %ld/%ld\n", (long)loc_inLen, (long)*inLen);
4926 }
4927 }
4928
4929 DBG (10, "do_cmd: finish\n");
4930
4931 return ret;
4932 }
4933
4934 /**
4935 * Convenience method to determine longest string size in a list.
4936 */
4937 static size_t
maxStringSize(const SANE_String_Const strings[])4938 maxStringSize (const SANE_String_Const strings[])
4939 {
4940 size_t size, max_size = 0;
4941 int i;
4942
4943 for (i = 0; strings[i]; ++i) {
4944 size = strlen (strings[i]) + 1;
4945 max_size = MAX(max_size, size);
4946 }
4947
4948 return max_size;
4949 }
4950
4951 /**
4952 * Prints a hex dump of the given buffer onto the debug output stream.
4953 */
4954 static void
hexdump(int level, char *comment, unsigned char *p, int l)4955 hexdump (int level, char *comment, unsigned char *p, int l)
4956 {
4957 int i;
4958 char line[128];
4959 char *ptr;
4960
4961 if(DBG_LEVEL < level)
4962 return;
4963
4964 DBG (level, "%s\n", comment);
4965 ptr = line;
4966 for (i = 0; i < l; i++, p++)
4967 {
4968 if ((i % 16) == 0)
4969 {
4970 if (ptr != line)
4971 {
4972 *ptr = '\0';
4973 DBG (level, "%s\n", line);
4974 ptr = line;
4975 }
4976 sprintf (ptr, "%3.3x:", i);
4977 ptr += 4;
4978 }
4979 sprintf (ptr, " %2.2x", *p);
4980 ptr += 3;
4981 }
4982 *ptr = '\0';
4983 DBG (level, "%s\n", line);
4984 }
4985
4986 /**
4987 * An advanced method we don't support but have to define.
4988 */
4989 SANE_Status
sane_set_io_mode(SANE_Handle h, SANE_Bool non_blocking)4990 sane_set_io_mode (SANE_Handle h, SANE_Bool non_blocking)
4991 {
4992 DBG (10, "sane_set_io_mode\n");
4993 DBG (15, "%d %p\n", non_blocking, h);
4994 return SANE_STATUS_UNSUPPORTED;
4995 }
4996
4997 /**
4998 * An advanced method we don't support but have to define.
4999 */
5000 SANE_Status
sane_get_select_fd(SANE_Handle h, SANE_Int *fdp)5001 sane_get_select_fd (SANE_Handle h, SANE_Int *fdp)
5002 {
5003 DBG (10, "sane_get_select_fd\n");
5004 DBG (15, "%p %d\n", h, *fdp);
5005 return SANE_STATUS_UNSUPPORTED;
5006 }
5007
5008 /* s->page_width stores the user setting
5009 * for the paper width in adf. sometimes,
5010 * we need a value that differs from this
5011 * due to using FB
5012 */
5013 static int
get_page_width(struct scanner *s)5014 get_page_width(struct scanner *s)
5015 {
5016 /* scanner max for fb */
5017 if(s->source == SOURCE_FLATBED){
5018 return s->max_x;
5019 }
5020
5021 return s->page_width;
5022 }
5023
5024 /* s->page_height stores the user setting
5025 * for the paper height in adf. sometimes,
5026 * we need a value that differs from this
5027 * due to using FB.
5028 */
5029 static int
get_page_height(struct scanner *s)5030 get_page_height(struct scanner *s)
5031 {
5032 /* scanner max for fb */
5033 if(s->source == SOURCE_FLATBED){
5034 return s->max_y;
5035 }
5036
5037 return s->page_height;
5038 }
5039