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