1 /* ========================================================================= */
2 /*
3 SANE - Scanner Access Now Easy.
4 coolscan2.c , version 0.1.8
5
6 This file is part of the SANE package.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <https://www.gnu.org/licenses/>.
20
21 As a special exception, the authors of SANE give permission for
22 additional uses of the libraries contained in this release of SANE.
23
24 The exception is that, if you link a SANE library with other files
25 to produce an executable, this does not by itself cause the
26 resulting executable to be covered by the GNU General Public
27 License. Your use of that executable is in no way restricted on
28 account of linking the SANE library code into it.
29
30 This exception does not, however, invalidate any other reasons why
31 the executable file might be covered by the GNU General Public
32 License.
33
34 If you submit changes to SANE to the maintainers to be included in
35 a subsequent release, you agree by submitting the changes that
36 those changes may be distributed with this exception intact.
37
38 If you write modifications of your own for SANE, it is your choice
39 whether to permit this exception to apply to your modifications.
40 If you do not wish that, delete this exception notice.
41
42 This file implements a SANE backend for Nikon Coolscan film scanners.
43
44 Written by András Major (andras@users.sourceforge.net), 2001-2002.
45
46 The developers wish to express their thanks to Nikon Corporation
47 for providing technical information and thus making this backend
48 possible.
49 */
50 /* ========================================================================= */
51
52
53 /* ========================================================================= */
54 /*
55 Revision log:
56
57 0.1.9, 20/10/2005, ariel: added support for the LS-50/5000
58 0.1.8, 27/09/2002, andras: added subframe and load options
59 0.1.7, 22/08/2002, andras: added exposure correction option
60 and hack for LS-40 IR readout
61 0.1.6, 14/06/2002, andras: types etc. fixed, fixes for LS-8000
62 0.1.5, 26/04/2002, andras: lots of minor fixes related to saned
63 0.1.4, 22/04/2002, andras: first version to be included in SANE CVS
64
65 */
66 /* ========================================================================= */
67
68 #ifdef _AIX
69 # include "../include/lalloca.h" /* MUST come first for AIX! */
70 #endif
71 #include "../include/sane/config.h"
72 #include "../include/lalloca.h"
73
74 #include <math.h>
75 #include <stdio.h>
76 #include <stdlib.h>
77 #include <string.h>
78 #include <ctype.h>
79 #include <unistd.h>
80 #include <time.h>
81 /*
82 #include <limits.h>
83 #include <sys/types.h>
84 */
85
86 #include "../include/_stdint.h"
87
88 #include "../include/sane/sane.h"
89 #include "../include/sane/sanei.h"
90 #include "../include/sane/saneopts.h"
91 #include "../include/sane/sanei_scsi.h"
92 #include "../include/sane/sanei_usb.h"
93 #include "../include/sane/sanei_debug.h"
94 #include "../include/sane/sanei_config.h"
95 #define BACKEND_NAME coolscan2
96 #include "../include/sane/sanei_backend.h" /* must be last */
97
98 #define CS2_VERSION_MAJOR 0
99 #define CS2_VERSION_MINOR 1
100 #define CS2_REVISION 8
101 #define CS2_CONFIG_FILE "coolscan2.conf"
102
103 #define WSIZE (sizeof (SANE_Word))
104
105 /*
106 #define CS2_BLEEDING_EDGE
107 */
108
109
110 /* ========================================================================= */
111 /* typedefs */
112
113 typedef enum
114 {
115 CS2_TYPE_UNKOWN,
116 CS2_TYPE_LS30,
117 CS2_TYPE_LS40,
118 CS2_TYPE_LS50,
119 CS2_TYPE_LS2000,
120 CS2_TYPE_LS4000,
121 CS2_TYPE_LS5000,
122 CS2_TYPE_LS8000
123 }
124 cs2_type_t;
125
126 typedef enum
127 {
128 CS2_INTERFACE_UNKNOWN,
129 CS2_INTERFACE_SCSI, /* includes IEEE1394 via SBP2 */
130 CS2_INTERFACE_USB
131 }
132 cs2_interface_t;
133
134 typedef enum
135 {
136 CS2_PHASE_NONE = 0x00,
137 CS2_PHASE_STATUS = 0x01,
138 CS2_PHASE_OUT = 0x02,
139 CS2_PHASE_IN = 0x03,
140 CS2_PHASE_BUSY = 0x04
141 }
142 cs2_phase_t;
143
144 typedef enum
145 {
146 CS2_SCAN_NORMAL,
147 CS2_SCAN_AE,
148 CS2_SCAN_AE_WB
149 }
150 cs2_scan_t;
151
152 typedef enum
153 {
154 CS2_INFRARED_OFF,
155 CS2_INFRARED_IN,
156 CS2_INFRARED_OUT
157 }
158 cs2_infrared_t;
159
160 typedef enum
161 {
162 CS2_STATUS_READY = 0,
163 CS2_STATUS_BUSY = 1,
164 CS2_STATUS_NO_DOCS = 2,
165 CS2_STATUS_PROCESSING = 4,
166 CS2_STATUS_ERROR = 8,
167 CS2_STATUS_REISSUE = 16,
168 CS2_STATUS_ALL = 31 /* sum of all others */
169 }
170 cs2_status_t;
171
172 typedef enum
173 {
174 CS2_OPTION_NUM = 0,
175
176 CS2_OPTION_PREVIEW,
177
178 CS2_OPTION_NEGATIVE,
179
180 CS2_OPTION_INFRARED,
181
182 CS2_OPTION_SAMPLES_PER_SCAN,
183
184 CS2_OPTION_DEPTH,
185
186 CS2_OPTION_EXPOSURE,
187 CS2_OPTION_EXPOSURE_R,
188 CS2_OPTION_EXPOSURE_G,
189 CS2_OPTION_EXPOSURE_B,
190 CS2_OPTION_SCAN_AE,
191 CS2_OPTION_SCAN_AE_WB,
192
193 CS2_OPTION_LUT_R,
194 CS2_OPTION_LUT_G,
195 CS2_OPTION_LUT_B,
196
197 CS2_OPTION_RES,
198 CS2_OPTION_RESX,
199 CS2_OPTION_RESY,
200 CS2_OPTION_RES_INDEPENDENT,
201
202 CS2_OPTION_PREVIEW_RESOLUTION,
203
204 CS2_OPTION_FRAME,
205 CS2_OPTION_SUBFRAME,
206 CS2_OPTION_XMIN,
207 CS2_OPTION_XMAX,
208 CS2_OPTION_YMIN,
209 CS2_OPTION_YMAX,
210
211 CS2_OPTION_LOAD,
212 CS2_OPTION_EJECT,
213 CS2_OPTION_RESET,
214
215 CS2_OPTION_FOCUS_ON_CENTRE,
216 CS2_OPTION_FOCUS,
217 CS2_OPTION_AUTOFOCUS,
218 CS2_OPTION_FOCUSX,
219 CS2_OPTION_FOCUSY,
220
221 CS2_N_OPTIONS /* must be last -- counts number of enum items */
222 }
223 cs2_option_t;
224
225 typedef unsigned int cs2_pixel_t;
226
227 typedef struct
228 {
229 /* interface */
230 cs2_interface_t interface;
231 int fd;
232 SANE_Byte *send_buf, *recv_buf;
233 size_t send_buf_size, recv_buf_size;
234 size_t n_cmd, n_send, n_recv;
235
236 /* device characteristics */
237 char vendor_string[9], product_string[17], revision_string[5];
238 cs2_type_t type;
239 int maxbits;
240 unsigned int resx_optical, resx_min, resx_max, *resx_list, resx_n_list;
241 unsigned int resy_optical, resy_min, resy_max, *resy_list, resy_n_list;
242 unsigned long boundaryx, boundaryy;
243 unsigned long frame_offset;
244 unsigned int unit_dpi;
245 double unit_mm;
246 int n_frames;
247
248 int focus_min, focus_max;
249
250 /* settings */
251 SANE_Bool preview, negative, infrared;
252 int samples_per_scan, depth, real_depth, bytes_per_pixel, shift_bits,
253 n_colour_in, n_colour_out;
254 cs2_pixel_t n_lut;
255 cs2_pixel_t *lut_r, *lut_g, *lut_b, *lut_neutral;
256 unsigned long resx, resy, res, res_independent, res_preview;
257 unsigned long xmin, xmax, ymin, ymax;
258 int i_frame;
259 double subframe;
260
261 unsigned int real_resx, real_resy, real_pitchx, real_pitchy;
262 unsigned long real_xoffset, real_yoffset, real_width, real_height,
263 logical_width, logical_height;
264 int odd_padding;
265 int block_padding;
266
267 double exposure, exposure_r, exposure_g, exposure_b;
268 unsigned long real_exposure[10];
269
270 SANE_Bool focus_on_centre;
271 unsigned long focusx, focusy, real_focusx, real_focusy;
272 int focus;
273
274 /* status */
275 SANE_Bool scanning;
276 cs2_infrared_t infrared_stage, infrared_next;
277 SANE_Byte *infrared_buf;
278 size_t n_infrared_buf, infrared_index;
279 SANE_Byte *line_buf;
280 ssize_t n_line_buf, i_line_buf;
281 unsigned long sense_key, sense_asc, sense_ascq, sense_info;
282 unsigned long sense_code;
283 cs2_status_t status;
284 size_t xfer_position, xfer_bytes_total;
285
286 /* SANE stuff */
287 SANE_Option_Descriptor option_list[CS2_N_OPTIONS];
288 }
289 cs2_t;
290
291
292 /* ========================================================================= */
293 /* prototypes */
294
295 static SANE_Status cs2_open (const char *device, cs2_interface_t interface,
296 cs2_t ** sp);
297 static void cs2_close (cs2_t * s);
298 static SANE_Status cs2_attach (const char *dev);
299 static SANE_Status cs2_scsi_sense_handler (int fd, u_char * sense_buffer,
300 void *arg);
301 static SANE_Status cs2_parse_sense_data (cs2_t * s);
302 static void cs2_init_buffer (cs2_t * s);
303 static SANE_Status cs2_pack_byte (cs2_t * s, SANE_Byte byte);
304 static SANE_Status cs2_parse_cmd (cs2_t * s, char *text);
305 static SANE_Status cs2_grow_send_buffer (cs2_t * s);
306 static SANE_Status cs2_issue_cmd (cs2_t * s);
307 static cs2_phase_t cs2_phase_check (cs2_t * s);
308 static SANE_Status cs2_set_boundary (cs2_t *s);
309 static SANE_Status cs2_scanner_ready (cs2_t * s, int flags);
310 static SANE_Status cs2_page_inquiry (cs2_t * s, int page);
311 static SANE_Status cs2_full_inquiry (cs2_t * s);
312 static SANE_Status cs2_execute (cs2_t * s);
313 static SANE_Status cs2_load (cs2_t * s);
314 static SANE_Status cs2_eject (cs2_t * s);
315 static SANE_Status cs2_reset (cs2_t * s);
316 static SANE_Status cs2_focus (cs2_t * s);
317 static SANE_Status cs2_autofocus (cs2_t * s);
318 static SANE_Status cs2_get_exposure (cs2_t * s);
319 static SANE_Status cs2_convert_options (cs2_t * s);
320 static SANE_Status cs2_scan (cs2_t * s, cs2_scan_t type);
321 static void *cs2_xmalloc (size_t size);
322 static void *cs2_xrealloc (void *p, size_t size);
323 static void cs2_xfree (const void *p);
324
325
326 /* ========================================================================= */
327 /* global variables */
328
329 static int cs2_colour_list[] = { 1, 2, 3, 9 };
330
331 static SANE_Device **device_list = NULL;
332 static int n_device_list = 0;
333 static cs2_interface_t try_interface = CS2_INTERFACE_UNKNOWN;
334 static int open_devices = 0;
335
336
337 /* ========================================================================= */
338 /* SANE entry points */
339
340 SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)341 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
342 {
343 DBG_INIT ();
344 DBG (10, "sane_init() called.\n");
345 DBG (1, "coolscan2 backend, version %i.%i.%i initializing.\n", CS2_VERSION_MAJOR, CS2_VERSION_MINOR, CS2_REVISION);
346
347 (void) authorize; /* to shut up compiler */
348
349 if (version_code)
350 *version_code =
351 SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
352
353 sanei_usb_init ();
354
355 return SANE_STATUS_GOOD;
356 }
357
358 void
sane_exit(void)359 sane_exit (void)
360 {
361 int i;
362
363 DBG (10, "sane_exit() called.\n");
364
365 for (i = 0; i < n_device_list; i++)
366 {
367 cs2_xfree (device_list[i]->name);
368 cs2_xfree (device_list[i]->vendor);
369 cs2_xfree (device_list[i]->model);
370 cs2_xfree (device_list[i]);
371 }
372 cs2_xfree (device_list);
373 }
374
375 SANE_Status
sane_get_devices(const SANE_Device *** list, SANE_Bool local_only)376 sane_get_devices (const SANE_Device *** list, SANE_Bool local_only)
377 {
378 char line[PATH_MAX], *p;
379 FILE *config;
380
381 (void) local_only; /* to shut up compiler */
382
383 DBG (10, "sane_get_devices() called.\n");
384
385 if (device_list)
386 DBG (6,
387 "sane_get_devices(): Device list already populated, not probing again.\n");
388 else
389 {
390 if (open_devices)
391 {
392 DBG (4,
393 "sane_get_devices(): Devices open, not scanning for scanners.\n");
394 return SANE_STATUS_IO_ERROR;
395 }
396
397 config = sanei_config_open (CS2_CONFIG_FILE);
398 if (config)
399 {
400 DBG (4, "sane_get_devices(): Reading config file.\n");
401 while (sanei_config_read (line, sizeof (line), config))
402 {
403 p = line;
404 p += strspn (line, " \t");
405 if (strlen (p) && (p[0] != '\n') && (p[0] != '#'))
406 cs2_open (line, CS2_INTERFACE_UNKNOWN, NULL);
407 }
408 fclose (config);
409 }
410 else
411 {
412 DBG (4, "sane_get_devices(): No config file found.\n");
413 cs2_open ("auto", CS2_INTERFACE_UNKNOWN, NULL);
414 }
415
416 switch (n_device_list)
417 {
418 case 0:
419 DBG (6, "sane_get_devices(): No devices detected.\n");
420 break;
421 case 1:
422 DBG (6, "sane_get_devices(): 1 device detected.\n");
423 break;
424 default:
425 DBG (6, "sane_get_devices(): %i devices detected.\n",
426 n_device_list);
427 break;
428 }
429 }
430
431 *list = (const SANE_Device **) device_list;
432
433 return SANE_STATUS_GOOD;
434 }
435
436 SANE_Status
sane_open(SANE_String_Const name, SANE_Handle * h)437 sane_open (SANE_String_Const name, SANE_Handle * h)
438 {
439 SANE_Status status;
440 cs2_t *s;
441 int i_option;
442 unsigned int i_list;
443 SANE_Option_Descriptor o;
444 SANE_Word *word_list;
445 SANE_Range *range = NULL;
446 int alloc_failed = 0;
447
448 DBG (10, "sane_open() called.\n");
449
450 status = cs2_open (name, CS2_INTERFACE_UNKNOWN, &s);
451 if (status)
452 return status;
453
454 *h = (SANE_Handle) s;
455
456 /* get device properties */
457
458 s->lut_r = s->lut_g = s->lut_b = s->lut_neutral = NULL;
459 s->resx_list = s->resy_list = NULL;
460 s->resx_n_list = s->resy_n_list = 0;
461
462 status = cs2_full_inquiry (s);
463 if (status)
464 return status;
465
466 /* option descriptors */
467
468 for (i_option = 0; i_option < CS2_N_OPTIONS; i_option++)
469 {
470 o.name = o.title = o.desc = NULL;
471 o.type = SANE_TYPE_BOOL;
472 o.unit = SANE_UNIT_NONE;
473 o.size = o.cap = 0;
474 o.constraint_type = SANE_CONSTRAINT_NONE;
475 o.constraint.range = NULL; /* only one union member needs to be NULLed */
476 switch (i_option)
477 {
478 case CS2_OPTION_NUM:
479 o.name = "";
480 o.title = SANE_TITLE_NUM_OPTIONS;
481 o.desc = SANE_DESC_NUM_OPTIONS;
482 o.type = SANE_TYPE_INT;
483 o.size = WSIZE;
484 o.cap = SANE_CAP_SOFT_DETECT;
485 break;
486 case CS2_OPTION_PREVIEW:
487 o.name = "preview";
488 o.title = "Preview mode";
489 o.desc = "Preview mode";
490 o.type = SANE_TYPE_BOOL;
491 o.size = WSIZE;
492 o.cap =
493 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
494 break;
495 case CS2_OPTION_NEGATIVE:
496 o.name = "negative";
497 o.title = "Negative";
498 o.desc = "Negative film: make scanner invert colours";
499 o.type = SANE_TYPE_BOOL;
500 o.size = WSIZE;
501 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
502 #ifndef CS2_BLEEDING_EDGE
503 o.cap |= SANE_CAP_INACTIVE;
504 #endif
505 break;
506 case CS2_OPTION_INFRARED:
507 o.name = "infrared";
508 o.title = "Read infrared channel";
509 o.desc = "Read infrared channel in addition to scan colours";
510 o.type = SANE_TYPE_BOOL;
511 o.size = WSIZE;
512 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
513 break;
514 case CS2_OPTION_SAMPLES_PER_SCAN:
515 o.name = "samples-per-scan";
516 o.title = "Samples per Scan";
517 o.desc = "Number of samples per scan";
518 o.type = SANE_TYPE_INT;
519 o.unit = SANE_UNIT_NONE;
520 o.size = WSIZE;
521 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
522 if (s->type != CS2_TYPE_LS2000 && s->type != CS2_TYPE_LS4000
523 && s->type != CS2_TYPE_LS5000 && s->type != CS2_TYPE_LS8000)
524 o.cap |= SANE_CAP_INACTIVE;
525 o.constraint_type = SANE_CONSTRAINT_RANGE;
526 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
527 if (! range)
528 alloc_failed = 1;
529 else
530 {
531 range->min = 1;
532 range->max = 16;
533 range->quant = 1;
534 o.constraint.range = range;
535 }
536 break;
537 case CS2_OPTION_DEPTH:
538 o.name = "depth";
539 o.title = "Bit depth per channel";
540 o.desc = "Number of bits output by scanner for each channel";
541 o.type = SANE_TYPE_INT;
542 o.unit = SANE_UNIT_NONE;
543 o.size = WSIZE;
544 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
545 o.constraint_type = SANE_CONSTRAINT_WORD_LIST;
546 word_list = (SANE_Word *) cs2_xmalloc (2 * sizeof (SANE_Word));
547 if (!word_list)
548 alloc_failed = 1;
549 else
550 {
551 word_list[1] = 8;
552 word_list[2] = s->maxbits;
553 word_list[0] = 2;
554 o.constraint.word_list = word_list;
555 }
556 break;
557 case CS2_OPTION_EXPOSURE:
558 o.name = "exposure";
559 o.title = "Exposure multiplier";
560 o.desc = "Exposure multiplier for all channels";
561 o.type = SANE_TYPE_FIXED;
562 o.unit = SANE_UNIT_NONE;
563 o.size = WSIZE;
564 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
565 o.constraint_type = SANE_CONSTRAINT_RANGE;
566 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
567 if (!range)
568 alloc_failed = 1;
569 else
570 {
571 range->min = SANE_FIX (0.);
572 range->max = SANE_FIX (10.);
573 range->quant = SANE_FIX (0.1);
574 o.constraint.range = range;
575 }
576 break;
577 case CS2_OPTION_EXPOSURE_R:
578 o.name = "red-exposure";
579 o.title = "Red exposure time";
580 o.desc = "Exposure time for red channel";
581 o.type = SANE_TYPE_FIXED;
582 o.unit = SANE_UNIT_MICROSECOND;
583 o.size = WSIZE;
584 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
585 o.constraint_type = SANE_CONSTRAINT_RANGE;
586 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
587 if (!range)
588 alloc_failed = 1;
589 else
590 {
591 range->min = SANE_FIX (50.);
592 range->max = SANE_FIX (20000.);
593 range->quant = SANE_FIX (10.);
594 o.constraint.range = range;
595 }
596 break;
597 case CS2_OPTION_EXPOSURE_G:
598 o.name = "green-exposure";
599 o.title = "Green exposure time";
600 o.desc = "Exposure time for green channel";
601 o.type = SANE_TYPE_FIXED;
602 o.unit = SANE_UNIT_MICROSECOND;
603 o.size = WSIZE;
604 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
605 o.constraint_type = SANE_CONSTRAINT_RANGE;
606 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
607 if (!range)
608 alloc_failed = 1;
609 else
610 {
611 range->min = SANE_FIX (50.);
612 range->max = SANE_FIX (20000.);
613 range->quant = SANE_FIX (10.);
614 o.constraint.range = range;
615 }
616 break;
617 case CS2_OPTION_EXPOSURE_B:
618 o.name = "blue-exposure";
619 o.title = "Blue exposure time";
620 o.desc = "Exposure time for blue channel";
621 o.type = SANE_TYPE_FIXED;
622 o.unit = SANE_UNIT_MICROSECOND;
623 o.size = WSIZE;
624 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
625 o.constraint_type = SANE_CONSTRAINT_RANGE;
626 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
627 if (!range)
628 alloc_failed = 1;
629 else
630 {
631 range->min = SANE_FIX (50.);
632 range->max = SANE_FIX (20000.);
633 range->quant = SANE_FIX (10.);
634 o.constraint.range = range;
635 }
636 break;
637 case CS2_OPTION_LUT_R:
638 o.name = "red-gamma-table";
639 o.title = "LUT for red channel";
640 o.desc = "LUT for red channel";
641 o.type = SANE_TYPE_INT;
642 o.size = s->n_lut * WSIZE;
643 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
644 o.constraint_type = SANE_CONSTRAINT_RANGE;
645 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
646 if (!range)
647 alloc_failed = 1;
648 else
649 {
650 range->min = 0;
651 range->max = s->n_lut - 1;
652 range->quant = 1;
653 o.constraint.range = range;
654 }
655 break;
656 case CS2_OPTION_LUT_G:
657 o.name = "green-gamma-table";
658 o.title = "LUT for green channel";
659 o.desc = "LUT for green channel";
660 o.type = SANE_TYPE_INT;
661 o.size = s->n_lut * WSIZE;
662 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
663 o.constraint_type = SANE_CONSTRAINT_RANGE;
664 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
665 if (!range)
666 alloc_failed = 1;
667 else
668 {
669 range->min = 0;
670 range->max = s->n_lut - 1;
671 range->quant = 1;
672 o.constraint.range = range;
673 }
674 break;
675 case CS2_OPTION_LUT_B:
676 o.name = "blue-gamma-table";
677 o.title = "LUT for blue channel";
678 o.desc = "LUT for blue channel";
679 o.type = SANE_TYPE_INT;
680 o.size = s->n_lut * WSIZE;
681 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
682 o.constraint_type = SANE_CONSTRAINT_RANGE;
683 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
684 if (!range)
685 alloc_failed = 1;
686 else
687 {
688 range->min = 0;
689 range->max = s->n_lut - 1;
690 range->quant = 1;
691 o.constraint.range = range;
692 }
693 break;
694 case CS2_OPTION_LOAD:
695 o.name = "load";
696 o.title = "Load";
697 o.desc = "Load next slide";
698 o.type = SANE_TYPE_BUTTON;
699 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
700 break;
701 case CS2_OPTION_EJECT:
702 o.name = "eject";
703 o.title = "Eject";
704 o.desc = "Eject loaded medium";
705 o.type = SANE_TYPE_BUTTON;
706 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
707 break;
708 case CS2_OPTION_RESET:
709 o.name = "reset";
710 o.title = "Reset scanner";
711 o.desc = "Initialize scanner";
712 o.type = SANE_TYPE_BUTTON;
713 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
714 break;
715 case CS2_OPTION_RESX:
716 case CS2_OPTION_RES:
717 case CS2_OPTION_PREVIEW_RESOLUTION:
718 if (i_option == CS2_OPTION_PREVIEW_RESOLUTION)
719 {
720 o.name = "preview-resolution";
721 o.title = "Preview resolution";
722 o.desc =
723 "Scanning resolution for preview mode in dpi, affecting both x and y directions";
724 }
725 else if (i_option == CS2_OPTION_RES)
726 {
727 o.name = "resolution";
728 o.title = "Resolution";
729 o.desc =
730 "Scanning resolution in dpi, affecting both x and y directions";
731 }
732 else
733 {
734 o.name = "x-resolution";
735 o.title = "X resolution";
736 o.desc =
737 "Scanning resolution in dpi, affecting x direction only";
738 }
739 o.type = SANE_TYPE_INT;
740 o.unit = SANE_UNIT_DPI;
741 o.size = WSIZE;
742 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
743 if (i_option == CS2_OPTION_RESX)
744 o.cap |= SANE_CAP_INACTIVE | SANE_CAP_ADVANCED;
745 if (i_option == CS2_OPTION_PREVIEW_RESOLUTION)
746 o.cap |= SANE_CAP_ADVANCED;
747 o.constraint_type = SANE_CONSTRAINT_WORD_LIST;
748 word_list =
749 (SANE_Word *) cs2_xmalloc ((s->resx_n_list + 1) *
750 sizeof (SANE_Word));
751 if (!word_list)
752 alloc_failed = 1;
753 else
754 {
755 for (i_list = 0; i_list < s->resx_n_list; i_list++)
756 word_list[i_list + 1] = s->resx_list[i_list];
757 word_list[0] = s->resx_n_list;
758 o.constraint.word_list = word_list;
759 }
760 break;
761 case CS2_OPTION_RESY:
762 o.name = "y-resolution";
763 o.title = "Y resolution";
764 o.desc = "Scanning resolution in dpi, affecting y direction only";
765 o.type = SANE_TYPE_INT;
766 o.unit = SANE_UNIT_DPI;
767 o.size = WSIZE;
768 o.cap =
769 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE |
770 SANE_CAP_ADVANCED;
771 o.constraint_type = SANE_CONSTRAINT_WORD_LIST;
772 word_list =
773 (SANE_Word *) cs2_xmalloc ((s->resy_n_list + 1) *
774 sizeof (SANE_Word));
775 if (!word_list)
776 alloc_failed = 1;
777 else
778 {
779 for (i_list = 0; i_list < s->resy_n_list; i_list++)
780 word_list[i_list + 1] = s->resy_list[i_list];
781 word_list[0] = s->resy_n_list;
782 o.constraint.word_list = word_list;
783 }
784 break;
785 case CS2_OPTION_RES_INDEPENDENT:
786 o.name = "independent-res";
787 o.title = "Independent x/y resolutions";
788 o.desc =
789 "Enable independent controls for scanning resolution in x and y direction";
790 o.type = SANE_TYPE_BOOL;
791 o.size = WSIZE;
792 o.cap =
793 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE |
794 SANE_CAP_ADVANCED;
795 break;
796 case CS2_OPTION_FRAME:
797 o.name = "frame";
798 o.title = "Frame number";
799 o.desc = "Number of frame to be scanned, starting with 1";
800 o.type = SANE_TYPE_INT;
801 o.unit = SANE_UNIT_NONE;
802 o.size = WSIZE;
803 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
804 if (s->n_frames <= 1)
805 o.cap |= SANE_CAP_INACTIVE;
806 o.constraint_type = SANE_CONSTRAINT_RANGE;
807 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
808 if (!range)
809 alloc_failed = 1;
810 else
811 {
812 range->min = 1;
813 range->max = s->n_frames;
814 range->quant = 1;
815 o.constraint.range = range;
816 }
817 break;
818 case CS2_OPTION_SUBFRAME:
819 o.name = "subframe";
820 o.title = "Frame shift";
821 o.desc = "Fine position within the selected frame";
822 o.type = SANE_TYPE_FIXED;
823 o.unit = SANE_UNIT_MM;
824 o.size = WSIZE;
825 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
826 o.constraint_type = SANE_CONSTRAINT_RANGE;
827 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
828 if (!range)
829 alloc_failed = 1;
830 else
831 {
832 range->min = SANE_FIX (0.);
833 range->max = SANE_FIX ((s->boundaryy - 1) * s->unit_mm);
834 range->quant = SANE_FIX (0.);
835 o.constraint.range = range;
836 }
837 break;
838 case CS2_OPTION_XMIN:
839 o.name = "tl-x";
840 o.title = "Left x value of scan area";
841 o.desc = "Left x value of scan area";
842 o.type = SANE_TYPE_INT;
843 o.unit = SANE_UNIT_PIXEL;
844 o.size = WSIZE;
845 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
846 o.constraint_type = SANE_CONSTRAINT_RANGE;
847 if (!range)
848 alloc_failed = 1;
849 else
850 {
851 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
852 range->min = 0;
853 range->max = s->boundaryx - 1;
854 range->quant = 1;
855 o.constraint.range = range;
856 }
857 break;
858 case CS2_OPTION_XMAX:
859 o.name = "br-x";
860 o.title = "Right x value of scan area";
861 o.desc = "Right x value of scan area";
862 o.type = SANE_TYPE_INT;
863 o.unit = SANE_UNIT_PIXEL;
864 o.size = WSIZE;
865 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
866 o.constraint_type = SANE_CONSTRAINT_RANGE;
867 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
868 if (!range)
869 alloc_failed = 1;
870 else
871 {
872 range->min = 0;
873 range->max = s->boundaryx - 1;
874 range->quant = 1;
875 o.constraint.range = range;
876 }
877 break;
878 case CS2_OPTION_YMIN:
879 o.name = "tl-y";
880 o.title = "Top y value of scan area";
881 o.desc = "Top y value of scan area";
882 o.type = SANE_TYPE_INT;
883 o.unit = SANE_UNIT_PIXEL;
884 o.size = WSIZE;
885 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
886 o.constraint_type = SANE_CONSTRAINT_RANGE;
887 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
888 if (!range)
889 alloc_failed = 1;
890 else
891 {
892 range->min = 0;
893 range->max = s->boundaryy - 1;
894 range->quant = 1;
895 o.constraint.range = range;
896 }
897 break;
898 case CS2_OPTION_YMAX:
899 o.name = "br-y";
900 o.title = "Bottom y value of scan area";
901 o.desc = "Bottom y value of scan area";
902 o.type = SANE_TYPE_INT;
903 o.unit = SANE_UNIT_PIXEL;
904 o.size = WSIZE;
905 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
906 o.constraint_type = SANE_CONSTRAINT_RANGE;
907 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
908 if (!range)
909 alloc_failed = 1;
910 else
911 {
912 range->min = 0;
913 range->max = s->boundaryy - 1;
914 range->quant = 1;
915 o.constraint.range = range;
916 }
917 break;
918 case CS2_OPTION_FOCUS_ON_CENTRE:
919 o.name = "focus-on-centre";
920 o.title = "Use centre of scan area as AF point";
921 o.desc =
922 "Use centre of scan area as AF point instead of manual AF point selection";
923 o.type = SANE_TYPE_BOOL;
924 o.size = WSIZE;
925 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
926 break;
927 case CS2_OPTION_FOCUS:
928 o.name = SANE_NAME_FOCUS;
929 o.title = SANE_TITLE_FOCUS;
930 o.desc = SANE_DESC_FOCUS;
931 o.type = SANE_TYPE_INT;
932 o.unit = SANE_UNIT_NONE;
933 o.size = WSIZE;
934 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
935 o.constraint_type = SANE_CONSTRAINT_RANGE;
936 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
937 if (!range)
938 alloc_failed = 1;
939 else
940 {
941 range->min = s->focus_min;
942 range->max = s->focus_max;
943 range->quant = 1;
944 o.constraint.range = range;
945 }
946 break;
947 case CS2_OPTION_AUTOFOCUS:
948 o.name = SANE_NAME_AUTOFOCUS;
949 o.title = SANE_TITLE_AUTOFOCUS;
950 o.desc = SANE_DESC_AUTOFOCUS;
951 o.type = SANE_TYPE_BUTTON;
952 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
953 break;
954 case CS2_OPTION_FOCUSX:
955 o.name = "focusx";
956 o.title = "X coordinate of AF point";
957 o.desc = "X coordinate of AF point";
958 o.type = SANE_TYPE_INT;
959 o.unit = SANE_UNIT_PIXEL;
960 o.size = WSIZE;
961 o.cap =
962 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE;
963 o.constraint_type = SANE_CONSTRAINT_RANGE;
964 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
965 if (!range)
966 alloc_failed = 1;
967 else
968 {
969 range->min = 0;
970 range->max = s->boundaryx - 1;
971 range->quant = 1;
972 o.constraint.range = range;
973 }
974 break;
975 case CS2_OPTION_FOCUSY:
976 o.name = "focusy";
977 o.title = "Y coordinate of AF point";
978 o.desc = "Y coordinate of AF point";
979 o.type = SANE_TYPE_INT;
980 o.unit = SANE_UNIT_PIXEL;
981 o.size = WSIZE;
982 o.cap =
983 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE;
984 o.constraint_type = SANE_CONSTRAINT_RANGE;
985 range = (SANE_Range *) cs2_xmalloc (sizeof (SANE_Range));
986 if (!range)
987 alloc_failed = 1;
988 else
989 {
990 range->min = 0;
991 range->max = s->boundaryy - 1;
992 range->quant = 1;
993 o.constraint.range = range;
994 }
995 break;
996 case CS2_OPTION_SCAN_AE:
997 o.name = "ae";
998 o.title = "Auto-exposure scan now";
999 o.desc = "Perform auto-exposure scan";
1000 o.type = SANE_TYPE_BUTTON;
1001 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1002 break;
1003 case CS2_OPTION_SCAN_AE_WB:
1004 o.name = "ae-wb";
1005 o.title = "Auto-exposure scan with white balance now";
1006 o.desc = "Perform auto-exposure scan with white balance";
1007 o.type = SANE_TYPE_BUTTON;
1008 o.cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1009 break;
1010 default:
1011 DBG (1, "BUG: sane_open(): Unknown option number.\n");
1012 return SANE_STATUS_INVAL;
1013 break;
1014 }
1015 s->option_list[i_option] = o;
1016 }
1017
1018 s->scanning = SANE_FALSE;
1019 s->preview = SANE_FALSE;
1020 s->negative = SANE_FALSE;
1021 s->depth = 8;
1022 s->infrared = 0;
1023 s->samples_per_scan = 1;
1024 s->i_frame = 1;
1025 s->subframe = 0.;
1026 s->res = s->resx = s->resx_max;
1027 s->resy = s->resy_max;
1028 s->res_independent = SANE_FALSE;
1029 s->res_preview = s->resx_max / 10;
1030 if (s->res_preview < s->resx_min)
1031 s->res_preview = s->resx_min;
1032 s->xmin = 0;
1033 s->xmax = s->boundaryx - 1;
1034 s->ymin = 0;
1035 s->ymax = s->boundaryy - 1;
1036 s->focus_on_centre = SANE_TRUE;
1037 s->focus = 0;
1038 s->focusx = 0;
1039 s->focusy = 0;
1040 s->exposure = 1.;
1041 s->exposure_r = 1200.;
1042 s->exposure_g = 1200.;
1043 s->exposure_b = 1000.;
1044 s->infrared_stage = CS2_INFRARED_OFF;
1045 s->infrared_next = CS2_INFRARED_OFF;
1046 s->infrared_buf = NULL;
1047 s->n_infrared_buf = 0;
1048 s->line_buf = NULL;
1049 s->n_line_buf = 0;
1050
1051 if (alloc_failed)
1052 {
1053 cs2_close (s);
1054 return SANE_STATUS_NO_MEM;
1055 }
1056
1057 return SANE_STATUS_GOOD;
1058 }
1059
1060 void
sane_close(SANE_Handle h)1061 sane_close (SANE_Handle h)
1062 {
1063 cs2_t *s = (cs2_t *) h;
1064
1065 DBG (10, "sane_close() called.\n");
1066
1067 cs2_close (s);
1068 }
1069
1070 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle h, SANE_Int n)1071 sane_get_option_descriptor (SANE_Handle h, SANE_Int n)
1072 {
1073 cs2_t *s = (cs2_t *) h;
1074
1075 DBG (10, "sane_get_option_descriptor() called, option #%i.\n", n);
1076
1077 if ((n >= 0) && (n < CS2_N_OPTIONS))
1078 return &s->option_list[n];
1079 else
1080 return NULL;
1081 }
1082
1083 SANE_Status
sane_control_option(SANE_Handle h, SANE_Int n, SANE_Action a, void *v, SANE_Int * i)1084 sane_control_option (SANE_Handle h, SANE_Int n, SANE_Action a, void *v,
1085 SANE_Int * i)
1086 {
1087 cs2_t *s = (cs2_t *) h;
1088 SANE_Int flags = 0;
1089 cs2_pixel_t pixel;
1090 SANE_Status status;
1091 SANE_Option_Descriptor o = s->option_list[n];
1092
1093 DBG (10, "sane_control_option() called, option #%i, action #%i.\n", n, a);
1094
1095 switch (a)
1096 {
1097 case SANE_ACTION_GET_VALUE:
1098
1099 switch (n)
1100 {
1101 case CS2_OPTION_NUM:
1102 *(SANE_Word *) v = CS2_N_OPTIONS;
1103 break;
1104 case CS2_OPTION_NEGATIVE:
1105 *(SANE_Word *) v = s->negative;
1106 break;
1107 case CS2_OPTION_INFRARED:
1108 *(SANE_Word *) v = s->infrared;
1109 break;
1110 case CS2_OPTION_SAMPLES_PER_SCAN:
1111 *(SANE_Word *) v = s->samples_per_scan;
1112 break;
1113 case CS2_OPTION_DEPTH:
1114 *(SANE_Word *) v = s->depth;
1115 break;
1116 case CS2_OPTION_PREVIEW:
1117 *(SANE_Word *) v = s->preview;
1118 break;
1119 case CS2_OPTION_EXPOSURE:
1120 *(SANE_Word *) v = SANE_FIX (s->exposure);
1121 break;
1122 case CS2_OPTION_EXPOSURE_R:
1123 *(SANE_Word *) v = SANE_FIX (s->exposure_r);
1124 break;
1125 case CS2_OPTION_EXPOSURE_G:
1126 *(SANE_Word *) v = SANE_FIX (s->exposure_g);
1127 break;
1128 case CS2_OPTION_EXPOSURE_B:
1129 *(SANE_Word *) v = SANE_FIX (s->exposure_b);
1130 break;
1131 case CS2_OPTION_LUT_R:
1132 if (!(s->lut_r))
1133 return SANE_STATUS_INVAL;
1134 for (pixel = 0; pixel < s->n_lut; pixel++)
1135 ((SANE_Word *) v)[pixel] = s->lut_r[pixel];
1136 break;
1137 case CS2_OPTION_LUT_G:
1138 if (!(s->lut_g))
1139 return SANE_STATUS_INVAL;
1140 for (pixel = 0; pixel < s->n_lut; pixel++)
1141 ((SANE_Word *) v)[pixel] = s->lut_g[pixel];
1142 break;
1143 case CS2_OPTION_LUT_B:
1144 if (!(s->lut_b))
1145 return SANE_STATUS_INVAL;
1146 for (pixel = 0; pixel < s->n_lut; pixel++)
1147 ((SANE_Word *) v)[pixel] = s->lut_b[pixel];
1148 break;
1149 case CS2_OPTION_EJECT:
1150 break;
1151 case CS2_OPTION_LOAD:
1152 break;
1153 case CS2_OPTION_RESET:
1154 break;
1155 case CS2_OPTION_FRAME:
1156 *(SANE_Word *) v = s->i_frame;
1157 break;
1158 case CS2_OPTION_SUBFRAME:
1159 *(SANE_Word *) v = SANE_FIX (s->subframe);
1160 break;
1161 case CS2_OPTION_RES:
1162 *(SANE_Word *) v = s->res;
1163 break;
1164 case CS2_OPTION_RESX:
1165 *(SANE_Word *) v = s->resx;
1166 break;
1167 case CS2_OPTION_RESY:
1168 *(SANE_Word *) v = s->resy;
1169 break;
1170 case CS2_OPTION_RES_INDEPENDENT:
1171 *(SANE_Word *) v = s->res_independent;
1172 break;
1173 case CS2_OPTION_PREVIEW_RESOLUTION:
1174 *(SANE_Word *) v = s->res_preview;
1175 break;
1176 case CS2_OPTION_XMIN:
1177 *(SANE_Word *) v = s->xmin;
1178 break;
1179 case CS2_OPTION_XMAX:
1180 *(SANE_Word *) v = s->xmax;
1181 break;
1182 case CS2_OPTION_YMIN:
1183 *(SANE_Word *) v = s->ymin;
1184 break;
1185 case CS2_OPTION_YMAX:
1186 *(SANE_Word *) v = s->ymax;
1187 break;
1188 case CS2_OPTION_FOCUS_ON_CENTRE:
1189 *(SANE_Word *) v = s->focus_on_centre;
1190 break;
1191 case CS2_OPTION_FOCUS:
1192 *(SANE_Word *) v = s->focus;
1193 break;
1194 case CS2_OPTION_AUTOFOCUS:
1195 break;
1196 case CS2_OPTION_FOCUSX:
1197 *(SANE_Word *) v = s->focusx;
1198 break;
1199 case CS2_OPTION_FOCUSY:
1200 *(SANE_Word *) v = s->focusy;
1201 break;
1202 case CS2_OPTION_SCAN_AE:
1203 break;
1204 case CS2_OPTION_SCAN_AE_WB:
1205 break;
1206 default:
1207 DBG (4, "Error: sane_control_option(): Unknown option (bug?).\n");
1208 return SANE_STATUS_INVAL;
1209 }
1210 break;
1211
1212 case SANE_ACTION_SET_VALUE:
1213 if (s->scanning)
1214 return SANE_STATUS_INVAL;
1215 /* XXXXXXXXXXXXXXXXX do this for all elements of arrays */
1216 switch (o.type)
1217 {
1218 case SANE_TYPE_BOOL:
1219 if ((*(SANE_Word *) v != SANE_TRUE)
1220 && (*(SANE_Word *) v != SANE_FALSE))
1221 return SANE_STATUS_INVAL;
1222 break;
1223 case SANE_TYPE_INT:
1224 case SANE_TYPE_FIXED:
1225 switch (o.constraint_type)
1226 {
1227 case SANE_CONSTRAINT_RANGE:
1228 if (*(SANE_Word *) v < o.constraint.range->min)
1229 {
1230 *(SANE_Word *) v = o.constraint.range->min;
1231 flags |= SANE_INFO_INEXACT;
1232 }
1233 else if (*(SANE_Word *) v > o.constraint.range->max)
1234 {
1235 *(SANE_Word *) v = o.constraint.range->max;
1236 flags |= SANE_INFO_INEXACT;
1237 }
1238 break;
1239 case SANE_CONSTRAINT_WORD_LIST:
1240 break;
1241 default:
1242 break;
1243 }
1244 break;
1245 case SANE_TYPE_STRING:
1246 break;
1247 case SANE_TYPE_BUTTON:
1248 break;
1249 case SANE_TYPE_GROUP:
1250 break;
1251 }
1252 switch (n)
1253 {
1254 case CS2_OPTION_NUM:
1255 return SANE_STATUS_INVAL;
1256 break;
1257 case CS2_OPTION_NEGATIVE:
1258 s->negative = *(SANE_Word *) v;
1259 break;
1260 case CS2_OPTION_INFRARED:
1261 s->infrared = *(SANE_Word *) v;
1262 /* flags |= SANE_INFO_RELOAD_PARAMS; XXXXXXXXXXXXXXXXX */
1263 break;
1264 case CS2_OPTION_SAMPLES_PER_SCAN:
1265 s->samples_per_scan = *(SANE_Word *) v;
1266 break;
1267 case CS2_OPTION_DEPTH:
1268 s->depth = *(SANE_Word *) v;
1269 flags |= SANE_INFO_RELOAD_PARAMS;
1270 break;
1271 case CS2_OPTION_PREVIEW:
1272 s->preview = *(SANE_Word *) v;
1273 break;
1274 case CS2_OPTION_EXPOSURE:
1275 s->exposure = SANE_UNFIX (*(SANE_Word *) v);
1276 break;
1277 case CS2_OPTION_EXPOSURE_R:
1278 s->exposure_r = SANE_UNFIX (*(SANE_Word *) v);
1279 break;
1280 case CS2_OPTION_EXPOSURE_G:
1281 s->exposure_g = SANE_UNFIX (*(SANE_Word *) v);
1282 break;
1283 case CS2_OPTION_EXPOSURE_B:
1284 s->exposure_b = SANE_UNFIX (*(SANE_Word *) v);
1285 break;
1286 case CS2_OPTION_LUT_R:
1287 if (!(s->lut_r))
1288 return SANE_STATUS_INVAL;
1289 for (pixel = 0; pixel < s->n_lut; pixel++)
1290 s->lut_r[pixel] = ((SANE_Word *) v)[pixel];
1291 break;
1292 case CS2_OPTION_LUT_G:
1293 if (!(s->lut_g))
1294 return SANE_STATUS_INVAL;
1295 for (pixel = 0; pixel < s->n_lut; pixel++)
1296 s->lut_g[pixel] = ((SANE_Word *) v)[pixel];
1297 break;
1298 case CS2_OPTION_LUT_B:
1299 if (!(s->lut_b))
1300 return SANE_STATUS_INVAL;
1301 for (pixel = 0; pixel < s->n_lut; pixel++)
1302 s->lut_b[pixel] = ((SANE_Word *) v)[pixel];
1303 break;
1304 case CS2_OPTION_LOAD:
1305 cs2_load (s);
1306 break;
1307 case CS2_OPTION_EJECT:
1308 cs2_eject (s);
1309 break;
1310 case CS2_OPTION_RESET:
1311 cs2_reset (s);
1312 break;
1313 case CS2_OPTION_FRAME:
1314 s->i_frame = *(SANE_Word *) v;
1315 break;
1316 case CS2_OPTION_SUBFRAME:
1317 s->subframe = SANE_UNFIX (*(SANE_Word *) v);
1318 break;
1319 case CS2_OPTION_RES:
1320 s->res = *(SANE_Word *) v;
1321 flags |= SANE_INFO_RELOAD_PARAMS;
1322 break;
1323 case CS2_OPTION_RESX:
1324 s->resx = *(SANE_Word *) v;
1325 flags |= SANE_INFO_RELOAD_PARAMS;
1326 break;
1327 case CS2_OPTION_RESY:
1328 s->resy = *(SANE_Word *) v;
1329 flags |= SANE_INFO_RELOAD_PARAMS;
1330 break;
1331 case CS2_OPTION_RES_INDEPENDENT:
1332 s->res_independent = *(SANE_Word *) v;
1333 flags |= SANE_INFO_RELOAD_PARAMS;
1334 break;
1335 case CS2_OPTION_PREVIEW_RESOLUTION:
1336 s->res_preview = *(SANE_Word *) v;
1337 flags |= SANE_INFO_RELOAD_PARAMS;
1338 break;
1339 case CS2_OPTION_XMIN:
1340 s->xmin = *(SANE_Word *) v;
1341 flags |= SANE_INFO_RELOAD_PARAMS;
1342 break;
1343 case CS2_OPTION_XMAX:
1344 s->xmax = *(SANE_Word *) v;
1345 flags |= SANE_INFO_RELOAD_PARAMS;
1346 break;
1347 case CS2_OPTION_YMIN:
1348 s->ymin = *(SANE_Word *) v;
1349 flags |= SANE_INFO_RELOAD_PARAMS;
1350 break;
1351 case CS2_OPTION_YMAX:
1352 s->ymax = *(SANE_Word *) v;
1353 flags |= SANE_INFO_RELOAD_PARAMS;
1354 break;
1355 case CS2_OPTION_FOCUS_ON_CENTRE:
1356 s->focus_on_centre = *(SANE_Word *) v;
1357 if (s->focus_on_centre)
1358 {
1359 s->option_list[CS2_OPTION_FOCUSX].cap |= SANE_CAP_INACTIVE;
1360 s->option_list[CS2_OPTION_FOCUSY].cap |= SANE_CAP_INACTIVE;
1361 }
1362 else
1363 {
1364 s->option_list[CS2_OPTION_FOCUSX].cap &= ~SANE_CAP_INACTIVE;
1365 s->option_list[CS2_OPTION_FOCUSY].cap &= ~SANE_CAP_INACTIVE;
1366 }
1367 flags |= SANE_INFO_RELOAD_OPTIONS;
1368 break;
1369 case CS2_OPTION_FOCUS:
1370 s->focus = *(SANE_Word *) v;
1371 break;
1372 case CS2_OPTION_AUTOFOCUS:
1373 cs2_autofocus (s);
1374 flags |= SANE_INFO_RELOAD_OPTIONS;
1375 break;
1376 case CS2_OPTION_FOCUSX:
1377 s->focusx = *(SANE_Word *) v;
1378 break;
1379 case CS2_OPTION_FOCUSY:
1380 s->focusy = *(SANE_Word *) v;
1381 break;
1382 case CS2_OPTION_SCAN_AE:
1383 cs2_scanner_ready (s, CS2_STATUS_NO_DOCS);
1384 status = cs2_scan (s, CS2_SCAN_AE);
1385 if (status)
1386 return status;
1387 status = cs2_get_exposure (s);
1388 if (status)
1389 return status;
1390 s->exposure = 1.;
1391 s->exposure_r = s->real_exposure[1] / 100.;
1392 s->exposure_g = s->real_exposure[2] / 100.;
1393 s->exposure_b = s->real_exposure[3] / 100.;
1394 flags |= SANE_INFO_RELOAD_OPTIONS;
1395 break;
1396 case CS2_OPTION_SCAN_AE_WB:
1397 cs2_scanner_ready (s, CS2_STATUS_NO_DOCS);
1398 status = cs2_scan (s, CS2_SCAN_AE_WB);
1399 if (status)
1400 return status;
1401 status = cs2_get_exposure (s);
1402 if (status)
1403 return status;
1404 s->exposure = 1.;
1405 s->exposure_r = s->real_exposure[1] / 100.;
1406 s->exposure_g = s->real_exposure[2] / 100.;
1407 s->exposure_b = s->real_exposure[3] / 100.;
1408 flags |= SANE_INFO_RELOAD_OPTIONS;
1409 break;
1410 default:
1411 DBG (4,
1412 "Error: sane_control_option(): Unknown option number (bug?).\n");
1413 return SANE_STATUS_INVAL;
1414 break;
1415 }
1416 break;
1417
1418 default:
1419 DBG (1, "BUG: sane_control_option(): Unknown action number.\n");
1420 return SANE_STATUS_INVAL;
1421 break;
1422 }
1423
1424 if (i)
1425 *i = flags;
1426
1427 return SANE_STATUS_GOOD;
1428 }
1429
1430 SANE_Status
sane_get_parameters(SANE_Handle h, SANE_Parameters * p)1431 sane_get_parameters (SANE_Handle h, SANE_Parameters * p)
1432 {
1433 cs2_t *s = (cs2_t *) h;
1434 SANE_Status status;
1435
1436 DBG (10, "sane_get_parameters() called.\n");
1437
1438 if (!s->scanning) /* only recalculate when not scanning */
1439 {
1440 status = cs2_convert_options (s);
1441 if (status)
1442 return status;
1443 }
1444
1445 if (s->infrared_stage == CS2_INFRARED_OUT)
1446 {
1447 p->format = SANE_FRAME_GRAY;
1448 p->bytes_per_line = s->logical_width * s->bytes_per_pixel;
1449 }
1450 else
1451 {
1452 p->format = SANE_FRAME_RGB; /* XXXXXXXX CCCCCCCCCC */
1453 p->bytes_per_line =
1454 s->n_colour_out * s->logical_width * s->bytes_per_pixel;
1455 }
1456 p->last_frame = SANE_TRUE;
1457 p->lines = s->logical_height;
1458 p->depth = 8 * s->bytes_per_pixel;
1459 p->pixels_per_line = s->logical_width;
1460
1461 return SANE_STATUS_GOOD;
1462 }
1463
1464 SANE_Status
sane_start(SANE_Handle h)1465 sane_start (SANE_Handle h)
1466 {
1467 cs2_t *s = (cs2_t *) h;
1468 SANE_Status status;
1469
1470 DBG (10, "sane_start() called.\n");
1471
1472 if (s->scanning)
1473 return SANE_STATUS_INVAL;
1474
1475 status = cs2_convert_options (s);
1476 if (status)
1477 return status;
1478
1479 s->infrared_index = 0;
1480 s->i_line_buf = 0;
1481 s->xfer_position = 0;
1482
1483 s->scanning = SANE_TRUE;
1484
1485 if (s->infrared_stage == CS2_INFRARED_OUT)
1486 return SANE_STATUS_GOOD;
1487 else
1488 return cs2_scan (s, CS2_SCAN_NORMAL);
1489 }
1490
1491 SANE_Status
sane_read(SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)1492 sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
1493 {
1494 cs2_t *s = (cs2_t *) h;
1495 SANE_Status status;
1496 ssize_t xfer_len_in, xfer_len_line, xfer_len_out;
1497 unsigned long index;
1498 int colour, n_colours, sample_pass;
1499 uint8_t *s8 = NULL;
1500 uint16_t *s16 = NULL;
1501 double m_avg_sum;
1502 SANE_Byte *line_buf_new;
1503
1504 DBG (10, "sane_read() called, maxlen = %i.\n", maxlen);
1505
1506 if (!s->scanning) {
1507 *len = 0;
1508 return SANE_STATUS_CANCELLED;
1509 }
1510
1511 if (s->infrared_stage == CS2_INFRARED_OUT)
1512 {
1513 xfer_len_out = maxlen;
1514
1515 if (s->xfer_position + xfer_len_out > s->n_infrared_buf)
1516 xfer_len_out = s->n_infrared_buf - s->xfer_position;
1517
1518 if (xfer_len_out == 0) /* no more data */
1519 {
1520 *len = 0;
1521 s->scanning = SANE_FALSE;
1522 return SANE_STATUS_EOF;
1523 }
1524
1525 memcpy (buf, &(s->infrared_buf[s->xfer_position]), xfer_len_out);
1526
1527 s->xfer_position += xfer_len_out;
1528
1529 if (s->xfer_position >= s->n_infrared_buf)
1530 s->infrared_next = CS2_INFRARED_OFF;
1531
1532 *len = xfer_len_out;
1533 return SANE_STATUS_GOOD;
1534 }
1535
1536 if (s->i_line_buf > 0)
1537 {
1538 xfer_len_out = s->n_line_buf - s->i_line_buf;
1539 if (xfer_len_out > maxlen)
1540 xfer_len_out = maxlen;
1541
1542 memcpy (buf, &(s->line_buf[s->i_line_buf]), xfer_len_out);
1543
1544 s->i_line_buf += xfer_len_out;
1545 if (s->i_line_buf >= s->n_line_buf)
1546 s->i_line_buf = 0;
1547
1548 *len = xfer_len_out;
1549 return SANE_STATUS_GOOD;
1550 }
1551
1552 xfer_len_line = s->n_colour_out * s->logical_width * s->bytes_per_pixel;
1553 xfer_len_in =
1554 s->n_colour_in * s->logical_width * s->bytes_per_pixel +
1555 s->n_colour_in * s->odd_padding;
1556 /* Do not change the behaviour of older models */
1557 if ((s->type == CS2_TYPE_LS50) || (s->type == CS2_TYPE_LS5000))
1558 {
1559 /* Ariel - Check, win driver uses multiple of 64, docu seems to say 512? */
1560 ssize_t i;
1561 xfer_len_in += s->block_padding;
1562 i = (xfer_len_in & 0x3f);
1563 if (i != 0)
1564 DBG (1, "BUG: sane_read(): Read size is not a multiple of 64. (0x%06lx)\n", (long) i);
1565 }
1566
1567 if (s->xfer_position + xfer_len_line > s->xfer_bytes_total)
1568 xfer_len_line = s->xfer_bytes_total - s->xfer_position; /* just in case */
1569
1570 if (xfer_len_line == 0) /* no more data */
1571 {
1572 *len = 0;
1573 s->scanning = SANE_FALSE;
1574 return SANE_STATUS_EOF;
1575 }
1576
1577 if (xfer_len_line != s->n_line_buf)
1578 {
1579 line_buf_new =
1580 (SANE_Byte *) cs2_xrealloc (s->line_buf,
1581 xfer_len_line * sizeof (SANE_Byte));
1582 if (!line_buf_new)
1583 {
1584 *len = 0;
1585 return SANE_STATUS_NO_MEM;
1586 }
1587 s->line_buf = line_buf_new;
1588 s->n_line_buf = xfer_len_line;
1589 }
1590
1591 /* adapt for multi-sampling */
1592 xfer_len_in *= s->samples_per_scan;
1593
1594 cs2_scanner_ready (s, CS2_STATUS_READY);
1595 cs2_init_buffer (s);
1596 cs2_parse_cmd (s, "28 00 00 00 00 00");
1597 cs2_pack_byte (s, (xfer_len_in >> 16) & 0xff);
1598 cs2_pack_byte (s, (xfer_len_in >> 8) & 0xff);
1599 cs2_pack_byte (s, xfer_len_in & 0xff);
1600 cs2_parse_cmd (s, "00");
1601 s->n_recv = xfer_len_in;
1602 status = cs2_issue_cmd (s);
1603
1604 if (status)
1605 {
1606 *len = 0;
1607 return status;
1608 }
1609
1610 n_colours = s->n_colour_out +
1611 (s->infrared_stage == CS2_INFRARED_IN ? 1 : 0);
1612
1613 for (index = 0; index < s->logical_width; index++)
1614 for (colour = 0; colour < n_colours; colour++) {
1615 m_avg_sum = 0.0;
1616 switch (s->bytes_per_pixel)
1617 {
1618 case 1:
1619 /* calculate target address */
1620 if ((s->infrared_stage == CS2_INFRARED_IN)
1621 && (colour == s->n_colour_out))
1622 s8 = (uint8_t *) & (s->infrared_buf[s->infrared_index++]);
1623 else
1624 s8 =
1625 (uint8_t *) & (s->line_buf[s->n_colour_out * index + colour]);
1626
1627 if (s->samples_per_scan > 1)
1628 {
1629 /* calculate average of multi samples */
1630 for (sample_pass = 0;
1631 sample_pass < s->samples_per_scan;
1632 sample_pass++)
1633 m_avg_sum += (double)
1634 s->recv_buf[s->logical_width *
1635 (sample_pass * n_colours + colour) +
1636 (colour + 1) * s->odd_padding + index];
1637
1638 *s8 = (uint8_t) (m_avg_sum / s->samples_per_scan + 0.5);
1639 }
1640 else
1641 /* shortcut for single sample */
1642 *s8 =
1643 s->recv_buf[colour * s->logical_width +
1644 (colour + 1) * s->odd_padding + index];
1645 break;
1646 case 2:
1647 /* calculate target address */
1648 if ((s->infrared_stage == CS2_INFRARED_IN)
1649 && (colour == s->n_colour_out))
1650 s16 =
1651 (uint16_t *) & (s->infrared_buf[2 * (s->infrared_index++)]);
1652 else
1653 s16 =
1654 (uint16_t *) & (s->
1655 line_buf[2 *
1656 (s->n_colour_out * index + colour)]);
1657
1658 if (s->samples_per_scan > 1)
1659 {
1660 /* calculate average of multi samples */
1661 for (sample_pass = 0;
1662 s->samples_per_scan > 1 && sample_pass < s->samples_per_scan;
1663 sample_pass++)
1664 m_avg_sum += (double)
1665 (s->recv_buf[2 * (s->logical_width * (sample_pass * n_colours + colour) + index)] * 256 +
1666 s->recv_buf[2 * (s->logical_width * (sample_pass * n_colours + colour) + index) + 1]);
1667
1668 *s16 = (uint16_t) (m_avg_sum / s->samples_per_scan + 0.5);
1669 }
1670 else
1671 /* shortcut for single sample */
1672 *s16 =
1673 s->recv_buf[2 * (colour * s->logical_width + index)] * 256 +
1674 s->recv_buf[2 * (colour * s->logical_width + index) + 1];
1675 *s16 <<= s->shift_bits;
1676 break;
1677 default:
1678 DBG (1, "BUG: sane_read(): Unknown number of bytes per pixel.\n");
1679 *len = 0;
1680 return SANE_STATUS_INVAL;
1681 break;
1682 }
1683 }
1684 s->xfer_position += xfer_len_line;
1685
1686 xfer_len_out = xfer_len_line;
1687 if (xfer_len_out > maxlen)
1688 xfer_len_out = maxlen;
1689
1690 memcpy (buf, s->line_buf, xfer_len_out);
1691 if (xfer_len_out < xfer_len_line)
1692 s->i_line_buf = xfer_len_out; /* data left in the line buffer, read out next time */
1693
1694 if ((s->infrared_stage == CS2_INFRARED_IN)
1695 && (s->xfer_position >= s->n_infrared_buf))
1696 s->infrared_next = CS2_INFRARED_OUT;
1697
1698 *len = xfer_len_out;
1699 return SANE_STATUS_GOOD;
1700 }
1701
1702 void
sane_cancel(SANE_Handle h)1703 sane_cancel (SANE_Handle h)
1704 {
1705 cs2_t *s = (cs2_t *) h;
1706
1707 if (s->scanning)
1708 DBG (10, "sane_cancel() called while scanning.\n");
1709 else
1710 DBG (10, "sane_cancel() called while not scanning.\n");
1711
1712 if (s->scanning && (s->infrared_stage != CS2_INFRARED_OUT))
1713 {
1714 cs2_init_buffer (s);
1715 cs2_parse_cmd (s, "c0 00 00 00 00 00");
1716 cs2_issue_cmd (s);
1717 }
1718
1719 s->scanning = SANE_FALSE;
1720 }
1721
1722 SANE_Status
sane_set_io_mode(SANE_Handle h, SANE_Bool m)1723 sane_set_io_mode (SANE_Handle h, SANE_Bool m)
1724 {
1725 cs2_t *s = (cs2_t *) h;
1726
1727 DBG (10, "sane_set_io_mode() called.\n");
1728
1729 if (!s->scanning)
1730 return SANE_STATUS_INVAL;
1731 if (m == SANE_FALSE)
1732 return SANE_STATUS_GOOD;
1733 else
1734 return SANE_STATUS_UNSUPPORTED;
1735 }
1736
1737 SANE_Status
sane_get_select_fd(SANE_Handle h, SANE_Int * fd)1738 sane_get_select_fd (SANE_Handle h, SANE_Int * fd)
1739 {
1740 cs2_t *s = (cs2_t *) h;
1741
1742 DBG (10, "sane_get_select_fd() called.\n");
1743
1744 (void) fd; /* to shut up compiler */
1745 (void) s; /* to shut up compiler */
1746
1747 return SANE_STATUS_UNSUPPORTED;
1748 }
1749
1750
1751 /* ========================================================================= */
1752 /* private functions */
1753
1754 static SANE_Status
cs2_open(const char *device, cs2_interface_t interface, cs2_t ** sp)1755 cs2_open (const char *device, cs2_interface_t interface, cs2_t ** sp)
1756 {
1757 SANE_Status status;
1758 cs2_t *s;
1759 char *prefix = NULL, *line;
1760 const char *device2;
1761 int i;
1762 int alloc_failed = 0;
1763 SANE_Device **device_list_new;
1764
1765 DBG (6, "cs2_open() called, with device = %s and interface = %i\n", device,
1766 interface);
1767
1768 if (!strncmp (device, "auto", 5))
1769 {
1770 try_interface = CS2_INTERFACE_SCSI;
1771 sanei_config_attach_matching_devices ("scsi Nikon *", cs2_attach);
1772 try_interface = CS2_INTERFACE_USB;
1773 sanei_usb_attach_matching_devices ("usb 0x04b0 0x4000", cs2_attach);
1774 sanei_usb_attach_matching_devices ("usb 0x04b0 0x4001", cs2_attach);
1775 sanei_usb_attach_matching_devices ("usb 0x04b0 0x4002", cs2_attach);
1776 return SANE_STATUS_GOOD;
1777 }
1778
1779 if ((s = (cs2_t *) cs2_xmalloc (sizeof (cs2_t))) == NULL)
1780 return SANE_STATUS_NO_MEM;
1781 memset (s, 0, sizeof (cs2_t));
1782 s->send_buf = s->recv_buf = NULL;
1783 s->send_buf_size = s->recv_buf_size = 0;
1784
1785 switch (interface)
1786 {
1787 case CS2_INTERFACE_UNKNOWN:
1788 for (i = 0; i < 2; i++)
1789 {
1790 switch (i)
1791 {
1792 case 1:
1793 prefix = "usb:";
1794 try_interface = CS2_INTERFACE_USB;
1795 break;
1796 default:
1797 prefix = "scsi:";
1798 try_interface = CS2_INTERFACE_SCSI;
1799 break;
1800 }
1801 if (!strncmp (device, prefix, strlen (prefix)))
1802 {
1803 device2 = device + strlen (prefix);
1804 cs2_xfree (s);
1805 return cs2_open (device2, try_interface, sp);
1806 }
1807 }
1808 cs2_xfree (s);
1809 return SANE_STATUS_INVAL;
1810 break;
1811 case CS2_INTERFACE_SCSI:
1812 s->interface = CS2_INTERFACE_SCSI;
1813 DBG (6,
1814 "cs2_open(): Trying to open %s, assuming SCSI or SBP2 interface ...\n",
1815 device);
1816 status = sanei_scsi_open (device, &s->fd, cs2_scsi_sense_handler, s);
1817 if (status)
1818 {
1819 DBG (6, "cs2_open(): ... failed: %s.\n", sane_strstatus (status));
1820 cs2_xfree (s);
1821 return status;
1822 }
1823 break;
1824 case CS2_INTERFACE_USB:
1825 s->interface = CS2_INTERFACE_USB;
1826 DBG (6, "cs2_open(): Trying to open %s, assuming USB interface ...\n",
1827 device);
1828 status = sanei_usb_open (device, &s->fd);
1829 if (status)
1830 {
1831 DBG (6, "cs2_open(): ... failed: %s.\n", sane_strstatus (status));
1832 cs2_xfree (s);
1833 return status;
1834 }
1835 break;
1836 }
1837
1838 open_devices++;
1839 DBG (6, "cs2_open(): ... looks OK, trying to identify device.\n");
1840
1841 /* identify scanner */
1842 status = cs2_page_inquiry (s, -1);
1843 if (status)
1844 {
1845 DBG (4, "Error: cs2_open(): failed to get page: %s.\n",
1846 sane_strstatus (status));
1847 cs2_close (s);
1848 return status;
1849 }
1850
1851 strncpy (s->vendor_string, (char *)s->recv_buf + 8, 8);
1852 s->vendor_string[8] = '\0';
1853 strncpy (s->product_string, (char *)s->recv_buf + 16, 16);
1854 s->product_string[16] = '\0';
1855 strncpy (s->revision_string, (char *)s->recv_buf + 32, 4);
1856 s->revision_string[4] = '\0';
1857
1858 DBG (10,
1859 "cs2_open(): Inquiry reveals: vendor = '%s', product = '%s', revision = '%s'.\n",
1860 s->vendor_string, s->product_string, s->revision_string);
1861
1862 if (!strncmp (s->product_string, "COOLSCANIII ", 16))
1863 s->type = CS2_TYPE_LS30;
1864 else if (!strncmp (s->product_string, "LS-40 ED ", 16))
1865 s->type = CS2_TYPE_LS40;
1866 else if (!strncmp (s->product_string, "LS-50 ED ", 16))
1867 s->type = CS2_TYPE_LS50;
1868 else if (!strncmp (s->product_string, "LS-2000 ", 16))
1869 s->type = CS2_TYPE_LS2000;
1870 else if (!strncmp (s->product_string, "LS-4000 ED ", 16))
1871 s->type = CS2_TYPE_LS4000;
1872 else if (!strncmp (s->product_string, "LS-5000 ED ", 16))
1873 s->type = CS2_TYPE_LS5000;
1874 else if (!strncmp (s->product_string, "LS-8000 ED ", 16))
1875 s->type = CS2_TYPE_LS8000;
1876
1877 if (s->type != CS2_TYPE_UNKOWN)
1878 DBG (10, "cs2_open(): Device identified as coolscan2 type #%i.\n",
1879 s->type);
1880 else
1881 {
1882 DBG (10, "cs2_open(): Device not identified.\n");
1883 cs2_close (s);
1884 return SANE_STATUS_UNSUPPORTED;
1885 }
1886
1887 if (sp)
1888 *sp = s;
1889 else
1890 {
1891 device_list_new =
1892 (SANE_Device **) cs2_xrealloc (device_list,
1893 (n_device_list +
1894 2) * sizeof (SANE_Device *));
1895 if (!device_list_new)
1896 return SANE_STATUS_NO_MEM;
1897 device_list = device_list_new;
1898 device_list[n_device_list] =
1899 (SANE_Device *) cs2_xmalloc (sizeof (SANE_Device));
1900 if (!device_list[n_device_list])
1901 return SANE_STATUS_NO_MEM;
1902 switch (interface)
1903 {
1904 case CS2_INTERFACE_UNKNOWN:
1905 DBG (1, "BUG: cs2_open(): unknown interface.\n");
1906 cs2_close (s);
1907 return SANE_STATUS_UNSUPPORTED;
1908 break;
1909 case CS2_INTERFACE_SCSI:
1910 prefix = "scsi:";
1911 break;
1912 case CS2_INTERFACE_USB:
1913 prefix = "usb:";
1914 break;
1915 }
1916
1917 line = (char *) cs2_xmalloc (strlen (device) + strlen (prefix) + 1);
1918 if (!line)
1919 alloc_failed = 1;
1920 else
1921 {
1922 strcpy (line, prefix);
1923 strcat (line, device);
1924 device_list[n_device_list]->name = line;
1925 }
1926
1927 line = (char *) cs2_xmalloc (strlen (s->vendor_string) + 1);
1928 if (!line)
1929 alloc_failed = 1;
1930 else
1931 {
1932 strcpy (line, s->vendor_string);
1933 device_list[n_device_list]->vendor = line;
1934 }
1935
1936 line = (char *) cs2_xmalloc (strlen (s->product_string) + 1);
1937 if (!line)
1938 alloc_failed = 1;
1939 else
1940 {
1941 strcpy (line, s->product_string);
1942 device_list[n_device_list]->model = line;
1943 }
1944
1945 device_list[n_device_list]->type = "film scanner";
1946
1947 if (alloc_failed)
1948 {
1949 cs2_xfree (device_list[n_device_list]->name);
1950 cs2_xfree (device_list[n_device_list]->vendor);
1951 cs2_xfree (device_list[n_device_list]->model);
1952 cs2_xfree (device_list[n_device_list]);
1953 }
1954 else
1955 n_device_list++;
1956 device_list[n_device_list] = NULL;
1957
1958 cs2_close (s);
1959 }
1960
1961 return SANE_STATUS_GOOD;
1962 }
1963
1964 void
cs2_close(cs2_t * s)1965 cs2_close (cs2_t * s)
1966 {
1967 cs2_xfree (s->lut_r);
1968 cs2_xfree (s->lut_g);
1969 cs2_xfree (s->lut_b);
1970 cs2_xfree (s->lut_neutral);
1971 cs2_xfree (s->infrared_buf);
1972 cs2_xfree (s->line_buf);
1973
1974 switch (s->interface)
1975 {
1976 case CS2_INTERFACE_UNKNOWN:
1977 DBG (1, "BUG: cs2_close(): Unknown interface number.\n");
1978 break;
1979 case CS2_INTERFACE_SCSI:
1980 sanei_scsi_close (s->fd);
1981 open_devices--;
1982 break;
1983 case CS2_INTERFACE_USB:
1984 sanei_usb_close (s->fd);
1985 open_devices--;
1986 break;
1987 }
1988
1989 cs2_xfree (s);
1990 }
1991
1992 static SANE_Status
cs2_attach(const char *dev)1993 cs2_attach (const char *dev)
1994 {
1995 SANE_Status status;
1996
1997 if (try_interface == CS2_INTERFACE_UNKNOWN)
1998 return SANE_STATUS_UNSUPPORTED;
1999
2000 status = cs2_open (dev, try_interface, NULL);
2001 return status;
2002 }
2003
2004 static SANE_Status
cs2_scsi_sense_handler(int fd, u_char * sense_buffer, void *arg)2005 cs2_scsi_sense_handler (int fd, u_char * sense_buffer, void *arg)
2006 {
2007 cs2_t *s = (cs2_t *) arg;
2008
2009 (void) fd; /* to shut up compiler */
2010
2011 /* sort this out ! XXXXXXXXX */
2012
2013 s->sense_key = sense_buffer[2] & 0x0f;
2014 s->sense_asc = sense_buffer[12];
2015 s->sense_ascq = sense_buffer[13];
2016 s->sense_info = sense_buffer[3];
2017
2018 return cs2_parse_sense_data (s);
2019 }
2020
2021 static SANE_Status
cs2_parse_sense_data(cs2_t * s)2022 cs2_parse_sense_data (cs2_t * s)
2023 {
2024 SANE_Status status = SANE_STATUS_GOOD;
2025
2026 s->sense_code =
2027 (s->sense_key << 24) + (s->sense_asc << 16) + (s->sense_ascq << 8) +
2028 s->sense_info;
2029
2030 if (s->sense_key)
2031 DBG (10, "Sense code: %02lx-%02lx-%02lx-%02lx\n", s->sense_key,
2032 s->sense_asc, s->sense_ascq, s->sense_info);
2033
2034 switch (s->sense_key)
2035 {
2036 case 0x00:
2037 s->status = CS2_STATUS_READY;
2038 break;
2039 case 0x02:
2040 switch (s->sense_asc)
2041 {
2042 case 0x04:
2043 s->status = CS2_STATUS_PROCESSING;
2044 break;
2045 case 0x3a:
2046 s->status = CS2_STATUS_NO_DOCS;
2047 break;
2048 default:
2049 s->status = CS2_STATUS_ERROR;
2050 status = SANE_STATUS_IO_ERROR;
2051 break;
2052 }
2053 break;
2054 default:
2055 s->status = CS2_STATUS_ERROR;
2056 status = SANE_STATUS_IO_ERROR;
2057 break;
2058 }
2059
2060 if ((s->sense_code == 0x09800600) || (s->sense_code == 0x09800601))
2061 s->status = CS2_STATUS_REISSUE;
2062
2063 return status;
2064 }
2065
2066 static void
cs2_init_buffer(cs2_t * s)2067 cs2_init_buffer (cs2_t * s)
2068 {
2069 s->n_cmd = 0;
2070 s->n_send = 0;
2071 s->n_recv = 0;
2072 }
2073
2074 static SANE_Status
cs2_pack_byte(cs2_t * s, SANE_Byte byte)2075 cs2_pack_byte (cs2_t * s, SANE_Byte byte)
2076 {
2077 while (s->send_buf_size <= s->n_send)
2078 {
2079 s->send_buf_size += 16;
2080 s->send_buf =
2081 (SANE_Byte *) cs2_xrealloc (s->send_buf, s->send_buf_size);
2082 if (!s->send_buf)
2083 return SANE_STATUS_NO_MEM;
2084 }
2085
2086 s->send_buf[s->n_send++] = byte;
2087
2088 return SANE_STATUS_GOOD;
2089 }
2090
2091 static SANE_Status
cs2_parse_cmd(cs2_t * s, char *text)2092 cs2_parse_cmd (cs2_t * s, char *text)
2093 {
2094 size_t i, j;
2095 char c, h;
2096 SANE_Status status;
2097
2098 for (i = 0; i < strlen (text); i += 2)
2099 if (text[i] == ' ')
2100 i--; /* a bit dirty... advance by -1+2=1 */
2101 else
2102 {
2103 if ((!isxdigit (text[i])) || (!isxdigit (text[i + 1])))
2104 DBG (1, "BUG: cs2_parse_cmd(): Parser got invalid character.\n");
2105 c = 0;
2106 for (j = 0; j < 2; j++)
2107 {
2108 h = tolower (text[i + j]);
2109 if ((h >= 'a') && (h <= 'f'))
2110 c += 10 + h - 'a';
2111 else
2112 c += h - '0';
2113 if (j == 0)
2114 c <<= 4;
2115 }
2116 status = cs2_pack_byte (s, c);
2117 if (status)
2118 return status;
2119 }
2120
2121 return SANE_STATUS_GOOD;
2122 }
2123
2124 static SANE_Status
cs2_grow_send_buffer(cs2_t * s)2125 cs2_grow_send_buffer (cs2_t * s)
2126 {
2127 if (s->n_send > s->send_buf_size)
2128 {
2129 s->send_buf_size = s->n_send;
2130 s->send_buf =
2131 (SANE_Byte *) cs2_xrealloc (s->send_buf, s->send_buf_size);
2132 if (!s->send_buf)
2133 return SANE_STATUS_NO_MEM;
2134 }
2135
2136 return SANE_STATUS_GOOD;
2137 }
2138
2139 static SANE_Status
cs2_issue_cmd(cs2_t * s)2140 cs2_issue_cmd (cs2_t * s)
2141 {
2142 SANE_Status status = SANE_STATUS_INVAL;
2143 size_t n_data, n_status;
2144 static SANE_Byte status_buf[8];
2145 int status_only = 0;
2146
2147 DBG (20, "cs2_issue_cmd(): opcode = 0x%02x, n_send = %lu, n_recv = %lu.\n",
2148 s->send_buf[0], (unsigned long) s->n_send, (unsigned long) s->n_recv);
2149
2150 s->status = CS2_STATUS_READY;
2151
2152 if (!s->n_cmd)
2153 switch (s->send_buf[0])
2154 {
2155 case 0x00:
2156 case 0x12:
2157 case 0x15:
2158 case 0x16:
2159 case 0x17:
2160 case 0x1a:
2161 case 0x1b:
2162 case 0x1c:
2163 case 0x1d:
2164 case 0xc0:
2165 case 0xc1:
2166 s->n_cmd = 6;
2167 break;
2168 case 0x24:
2169 case 0x25:
2170 case 0x28:
2171 case 0x2a:
2172 case 0xe0:
2173 case 0xe1:
2174 s->n_cmd = 10;
2175 break;
2176 default:
2177 DBG (1, "BUG: cs2_issue_cmd(): Unknown command opcode 0x%02x.\n",
2178 s->send_buf[0]);
2179 break;
2180 }
2181
2182 if (s->n_send < s->n_cmd)
2183 {
2184 DBG (1,
2185 "BUG: cs2_issue_cmd(): Negative number of data out bytes requested.\n");
2186 return SANE_STATUS_INVAL;
2187 }
2188
2189 n_data = s->n_send - s->n_cmd;
2190 if (s->n_recv > 0)
2191 {
2192 if (n_data > 0)
2193 {
2194 DBG (1,
2195 "BUG: cs2_issue_cmd(): Both data in and data out requested.\n");
2196 return SANE_STATUS_INVAL;
2197 }
2198 else
2199 {
2200 n_data = s->n_recv;
2201 }
2202 }
2203
2204 s->recv_buf = (SANE_Byte *) cs2_xrealloc (s->recv_buf, s->n_recv);
2205 if (!s->recv_buf)
2206 return SANE_STATUS_NO_MEM;
2207
2208 switch (s->interface)
2209 {
2210 case CS2_INTERFACE_UNKNOWN:
2211 DBG (1,
2212 "BUG: cs2_issue_cmd(): Unknown or uninitialized interface number.\n");
2213 break;
2214 case CS2_INTERFACE_SCSI:
2215 sanei_scsi_cmd2 (s->fd, s->send_buf, s->n_cmd, s->send_buf + s->n_cmd,
2216 s->n_send - s->n_cmd, s->recv_buf, &s->n_recv);
2217 status = SANE_STATUS_GOOD;
2218 break;
2219 case CS2_INTERFACE_USB:
2220 status = sanei_usb_write_bulk (s->fd, s->send_buf, &s->n_cmd);
2221 if (status != SANE_STATUS_GOOD)
2222 {
2223 DBG (1, "Error: cs2_issue_cmd(): Could not write command.\n");
2224 return SANE_STATUS_IO_ERROR;
2225 }
2226 switch (cs2_phase_check (s))
2227 {
2228 case CS2_PHASE_OUT:
2229 if (s->n_send - s->n_cmd < n_data || !n_data)
2230 {
2231 DBG (4, "Error: cs2_issue_cmd(): Unexpected data out phase.\n");
2232 return SANE_STATUS_IO_ERROR;
2233 }
2234 status =
2235 sanei_usb_write_bulk (s->fd, s->send_buf + s->n_cmd, &n_data);
2236 break;
2237 case CS2_PHASE_IN:
2238 if (s->n_recv < n_data || !n_data)
2239 {
2240 DBG (4, "Error: cs2_issue_cmd(): Unexpected data in phase.\n");
2241 return SANE_STATUS_IO_ERROR;
2242 }
2243 status = sanei_usb_read_bulk (s->fd, s->recv_buf, &n_data);
2244 s->n_recv = n_data;
2245 break;
2246 case CS2_PHASE_NONE:
2247 DBG (4, "Error: cs2_issue_cmd(): No command received!\n");
2248 return SANE_STATUS_IO_ERROR;
2249 default:
2250 if (n_data)
2251 {
2252 DBG (4,
2253 "Error: cs2_issue_cmd(): Unexpected non-data phase, but n_data != 0.\n");
2254 status_only = 1;
2255 }
2256 break;
2257 }
2258 n_status = 8;
2259 status = sanei_usb_read_bulk (s->fd, status_buf, &n_status);
2260 if (n_status != 8)
2261 {
2262 DBG (4,
2263 "Error: cs2_issue_cmd(): Failed to read 8 status bytes from USB.\n");
2264 return SANE_STATUS_IO_ERROR;
2265 }
2266 s->sense_key = status_buf[1] & 0x0f;
2267 s->sense_asc = status_buf[2] & 0xff;
2268 s->sense_ascq = status_buf[3] & 0xff;
2269 s->sense_info = status_buf[4] & 0xff;
2270 cs2_parse_sense_data (s);
2271 break;
2272 }
2273
2274 if (status_only)
2275 return SANE_STATUS_IO_ERROR;
2276 else
2277 return status;
2278 }
2279
2280 static cs2_phase_t
cs2_phase_check(cs2_t * s)2281 cs2_phase_check (cs2_t * s)
2282 {
2283 static SANE_Byte phase_send_buf[1] = { 0xd0 }, phase_recv_buf[1];
2284 SANE_Status status = 0;
2285 size_t n = 1;
2286
2287 status = sanei_usb_write_bulk (s->fd, phase_send_buf, &n);
2288 status |= sanei_usb_read_bulk (s->fd, phase_recv_buf, &n);
2289
2290 DBG (6, "cs2_phase_check(): Phase check returned phase = 0x%02x.\n",
2291 phase_recv_buf[0]);
2292
2293 if (status)
2294 return -1;
2295 else
2296 return phase_recv_buf[0];
2297 }
2298
2299 static SANE_Status
cs2_scanner_ready(cs2_t * s, int flags)2300 cs2_scanner_ready (cs2_t * s, int flags)
2301 {
2302 SANE_Status status = SANE_STATUS_GOOD;
2303 int i = -1;
2304 unsigned long count = 0;
2305 int retry = 3;
2306
2307 do
2308 {
2309 if (i >= 0) /* dirty !!! */
2310 usleep (500000);
2311 cs2_init_buffer (s);
2312 for (i = 0; i < 6; i++)
2313 cs2_pack_byte (s, 0x00);
2314 status = cs2_issue_cmd (s);
2315 if (status)
2316 if (--retry < 0)
2317 return status;
2318 if (++count > 240)
2319 { /* 120s timeout */
2320 DBG (4, "Error: cs2_scanner_ready(): Timeout expired.\n");
2321 status = SANE_STATUS_IO_ERROR;
2322 break;
2323 }
2324 }
2325 while (s->status & ~flags); /* until all relevant bits are 0 */
2326
2327 return status;
2328 }
2329
2330 static SANE_Status
cs2_page_inquiry(cs2_t * s, int page)2331 cs2_page_inquiry (cs2_t * s, int page)
2332 {
2333 SANE_Status status;
2334
2335 size_t n;
2336
2337 if (page >= 0)
2338 {
2339
2340 cs2_scanner_ready (s, CS2_STATUS_NO_DOCS);
2341 cs2_init_buffer (s);
2342 cs2_parse_cmd (s, "12 01");
2343 cs2_pack_byte (s, page);
2344 cs2_parse_cmd (s, "00 04 00");
2345 s->n_recv = 4;
2346 status = cs2_issue_cmd (s);
2347 if (status)
2348 {
2349 DBG (4,
2350 "Error: cs2_page_inquiry(): Inquiry of page size failed: %s.\n",
2351 sane_strstatus (status));
2352 return status;
2353 }
2354
2355 n = s->recv_buf[3] + 4;
2356
2357 }
2358 else
2359 n = 36;
2360
2361 cs2_scanner_ready (s, CS2_STATUS_NO_DOCS);
2362 cs2_init_buffer (s);
2363 if (page >= 0)
2364 {
2365 cs2_parse_cmd (s, "12 01");
2366 cs2_pack_byte (s, page);
2367 cs2_parse_cmd (s, "00");
2368 }
2369 else
2370 cs2_parse_cmd (s, "12 00 00 00");
2371 cs2_pack_byte (s, n);
2372 cs2_parse_cmd (s, "00");
2373 s->n_recv = n;
2374 status = cs2_issue_cmd (s);
2375 if (status)
2376 {
2377 DBG (4, "Error: cs2_page_inquiry(): Inquiry of page failed: %s.\n",
2378 sane_strstatus (status));
2379 return status;
2380 }
2381
2382 return SANE_STATUS_GOOD;
2383 }
2384
2385 static SANE_Status
cs2_full_inquiry(cs2_t * s)2386 cs2_full_inquiry (cs2_t * s)
2387 {
2388 SANE_Status status;
2389 int pitch, pitch_max;
2390 cs2_pixel_t pixel;
2391
2392 status = cs2_page_inquiry (s, 0xc1);
2393 if (status)
2394 {
2395 DBG (4, "Error: cs2_full_inquiry(): Failed to get page: %s\n",
2396 sane_strstatus (status));
2397 return status;
2398 }
2399
2400 s->maxbits = s->recv_buf[82];
2401 if (s->type == CS2_TYPE_LS30) /* must be overridden, LS-30 claims to have 12 bits */
2402 s->maxbits = 10;
2403
2404 s->n_lut = 1;
2405 s->n_lut <<= s->maxbits;
2406 s->lut_r =
2407 (cs2_pixel_t *) cs2_xrealloc (s->lut_r, s->n_lut * sizeof (cs2_pixel_t));
2408 s->lut_g =
2409 (cs2_pixel_t *) cs2_xrealloc (s->lut_g, s->n_lut * sizeof (cs2_pixel_t));
2410 s->lut_b =
2411 (cs2_pixel_t *) cs2_xrealloc (s->lut_b, s->n_lut * sizeof (cs2_pixel_t));
2412 s->lut_neutral =
2413 (cs2_pixel_t *) cs2_xrealloc (s->lut_neutral,
2414 s->n_lut * sizeof (cs2_pixel_t));
2415
2416 if (!s->lut_r || !s->lut_g || !s->lut_b || !s->lut_neutral)
2417 {
2418 cs2_xfree (s->lut_r);
2419 cs2_xfree (s->lut_g);
2420 cs2_xfree (s->lut_b);
2421 cs2_xfree (s->lut_neutral);
2422 return SANE_STATUS_NO_MEM;
2423 }
2424
2425 for (pixel = 0; pixel < s->n_lut; pixel++)
2426 s->lut_r[pixel] = s->lut_g[pixel] = s->lut_b[pixel] =
2427 s->lut_neutral[pixel] = pixel;
2428
2429 s->resx_optical = 256 * s->recv_buf[18] + s->recv_buf[19];
2430 s->resx_max = 256 * s->recv_buf[20] + s->recv_buf[21];
2431 s->resx_min = 256 * s->recv_buf[22] + s->recv_buf[23];
2432 s->boundaryx =
2433 65536 * (256 * s->recv_buf[36] + s->recv_buf[37]) +
2434 256 * s->recv_buf[38] + s->recv_buf[39];
2435
2436 s->resy_optical = 256 * s->recv_buf[40] + s->recv_buf[41];
2437 s->resy_max = 256 * s->recv_buf[42] + s->recv_buf[43];
2438 s->resy_min = 256 * s->recv_buf[44] + s->recv_buf[45];
2439 s->boundaryy =
2440 65536 * (256 * s->recv_buf[58] + s->recv_buf[59]) +
2441 256 * s->recv_buf[60] + s->recv_buf[61];
2442
2443 s->focus_min = 256 * s->recv_buf[76] + s->recv_buf[77];
2444 s->focus_max = 256 * s->recv_buf[78] + s->recv_buf[79];
2445
2446 s->n_frames = s->recv_buf[75];
2447
2448 s->frame_offset = s->resy_max * 1.5 + 1; /* works for LS-30, maybe not for others */
2449
2450 /* generate resolution list for x */
2451 s->resx_n_list = pitch_max = floor (s->resx_max / (double) s->resx_min);
2452 s->resx_list =
2453 (unsigned int *) cs2_xrealloc (s->resx_list,
2454 pitch_max * sizeof (unsigned int));
2455 for (pitch = 1; pitch <= pitch_max; pitch++)
2456 s->resx_list[pitch - 1] = s->resx_max / pitch;
2457
2458 /* generate resolution list for y */
2459 s->resy_n_list = pitch_max = floor (s->resy_max / (double) s->resy_min);
2460 s->resy_list =
2461 (unsigned int *) cs2_xrealloc (s->resy_list,
2462 pitch_max * sizeof (unsigned int));
2463 for (pitch = 1; pitch <= pitch_max; pitch++)
2464 s->resy_list[pitch - 1] = s->resy_max / pitch;
2465
2466 s->unit_dpi = s->resx_max;
2467 s->unit_mm = 25.4 / s->unit_dpi;
2468
2469 return SANE_STATUS_GOOD;
2470 }
2471
2472 static SANE_Status
cs2_execute(cs2_t * s)2473 cs2_execute (cs2_t * s)
2474 {
2475 cs2_scanner_ready (s, CS2_STATUS_NO_DOCS);
2476 cs2_init_buffer (s);
2477 cs2_parse_cmd (s, "c1 00 00 00 00 00");
2478 return cs2_issue_cmd (s);
2479 }
2480
2481 static SANE_Status
cs2_load(cs2_t * s)2482 cs2_load (cs2_t * s)
2483 {
2484 SANE_Status status;
2485
2486 cs2_scanner_ready (s, CS2_STATUS_NO_DOCS);
2487 cs2_init_buffer (s);
2488 cs2_parse_cmd (s, "e0 00 d1 00 00 00 00 00 0d 00");
2489 s->n_send += 13;
2490 status = cs2_grow_send_buffer (s);
2491 if (status)
2492 return status;
2493 status = cs2_issue_cmd (s);
2494 if (status)
2495 return status;
2496
2497 return cs2_execute (s);
2498 }
2499
2500 static SANE_Status
cs2_eject(cs2_t * s)2501 cs2_eject (cs2_t * s)
2502 {
2503 SANE_Status status;
2504
2505 cs2_scanner_ready (s, CS2_STATUS_NO_DOCS);
2506 cs2_init_buffer (s);
2507 cs2_parse_cmd (s, "e0 00 d0 00 00 00 00 00 0d 00");
2508 s->n_send += 13;
2509 status = cs2_grow_send_buffer (s);
2510 if (status)
2511 return status;
2512 status = cs2_issue_cmd (s);
2513 if (status)
2514 return status;
2515
2516 return cs2_execute (s);
2517 }
2518
2519 static SANE_Status
cs2_reset(cs2_t * s)2520 cs2_reset (cs2_t * s)
2521 {
2522 SANE_Status status;
2523
2524 cs2_scanner_ready (s, CS2_STATUS_NO_DOCS);
2525 cs2_init_buffer (s);
2526 cs2_parse_cmd (s, "e0 00 80 00 00 00 00 00 0d 00");
2527 s->n_send += 13;
2528 status = cs2_grow_send_buffer (s);
2529 if (status)
2530 return status;
2531 status = cs2_issue_cmd (s);
2532 if (status)
2533 return status;
2534
2535 return cs2_execute (s);
2536 }
2537
2538 static SANE_Status
cs2_focus(cs2_t * s)2539 cs2_focus (cs2_t * s)
2540 {
2541 SANE_Status status;
2542
2543 cs2_scanner_ready (s, CS2_STATUS_READY);
2544 cs2_init_buffer (s);
2545 cs2_parse_cmd (s, "e0 00 c1 00 00 00 00 00 0d 00 00");
2546 cs2_pack_byte (s, (s->focus >> 24) & 0xff);
2547 cs2_pack_byte (s, (s->focus >> 16) & 0xff);
2548 cs2_pack_byte (s, (s->focus >> 8) & 0xff);
2549 cs2_pack_byte (s, s->focus & 0xff);
2550 cs2_parse_cmd (s, "00 00 00 00 00 00 00 00");
2551 status = cs2_issue_cmd (s);
2552 if (status)
2553 return status;
2554
2555 return cs2_execute (s);
2556 }
2557
2558 static SANE_Status
cs2_autofocus(cs2_t * s)2559 cs2_autofocus (cs2_t * s)
2560 {
2561 SANE_Status status;
2562
2563 cs2_convert_options (s);
2564
2565 cs2_scanner_ready (s, CS2_STATUS_READY);
2566 cs2_init_buffer (s);
2567 cs2_parse_cmd (s, "e0 00 a0 00 00 00 00 00 0d 00 00");
2568 cs2_pack_byte (s, (s->real_focusx >> 24) & 0xff);
2569 cs2_pack_byte (s, (s->real_focusx >> 16) & 0xff);
2570 cs2_pack_byte (s, (s->real_focusx >> 8) & 0xff);
2571 cs2_pack_byte (s, s->real_focusx & 0xff);
2572 cs2_pack_byte (s, (s->real_focusy >> 24) & 0xff);
2573 cs2_pack_byte (s, (s->real_focusy >> 16) & 0xff);
2574 cs2_pack_byte (s, (s->real_focusy >> 8) & 0xff);
2575 cs2_pack_byte (s, s->real_focusy & 0xff);
2576 cs2_parse_cmd (s, "00 00 00 00");
2577 status = cs2_issue_cmd (s);
2578 if (status)
2579 return status;
2580
2581 status = cs2_execute (s);
2582 if (status)
2583 return status;
2584
2585 cs2_scanner_ready (s, CS2_STATUS_READY);
2586 cs2_init_buffer (s);
2587 cs2_parse_cmd (s, "e1 00 c1 00 00 00 00 00 0d 00");
2588 s->n_recv = 13;
2589 status = cs2_issue_cmd (s);
2590 if (status)
2591 return status;
2592
2593 s->focus =
2594 65536 * (256 * s->recv_buf[1] + s->recv_buf[2]) + 256 * s->recv_buf[3] +
2595 s->recv_buf[4];
2596
2597 return status;
2598 }
2599
2600 static SANE_Status
cs2_get_exposure(cs2_t * s)2601 cs2_get_exposure (cs2_t * s)
2602 {
2603 SANE_Status status;
2604 int i_colour;
2605
2606 for (i_colour = 0; i_colour < 3; i_colour++)
2607 { /* XXXXXXXXXXXXX CCCCCCCCCCCCC */
2608 cs2_scanner_ready (s, CS2_STATUS_NO_DOCS);
2609
2610 cs2_init_buffer (s);
2611 cs2_parse_cmd (s, "25 01 00 00 00");
2612 cs2_pack_byte (s, cs2_colour_list[i_colour]);
2613 cs2_parse_cmd (s, "00 00 3a 00");
2614 s->n_recv = 58;
2615 status = cs2_issue_cmd (s);
2616 if (status)
2617 return status;
2618
2619 s->real_exposure[cs2_colour_list[i_colour]] =
2620 65536 * (256 * s->recv_buf[54] + s->recv_buf[55]) +
2621 256 * s->recv_buf[56] + s->recv_buf[57];
2622
2623 DBG (6, "cs2_get_exposure(): exposure for colour %i: %li * 10ns\n", cs2_colour_list[i_colour], s->real_exposure[cs2_colour_list[i_colour]]);
2624 }
2625
2626 return SANE_STATUS_GOOD;
2627 }
2628
2629 static SANE_Status
cs2_convert_options(cs2_t * s)2630 cs2_convert_options (cs2_t * s)
2631 {
2632 int i_colour;
2633 unsigned long xmin, xmax, ymin, ymax;
2634 SANE_Byte *infrared_buf_new;
2635
2636 s->real_depth = (s->preview ? 8 : s->depth);
2637 s->bytes_per_pixel = (s->real_depth > 8 ? 2 : 1);
2638 s->shift_bits = 8 * s->bytes_per_pixel - s->real_depth;
2639
2640 if (s->preview)
2641 {
2642 s->real_resx = s->res_preview;
2643 s->real_resy = s->res_preview;
2644 }
2645 else if (s->res_independent)
2646 {
2647 s->real_resx = s->resx;
2648 s->real_resy = s->resy;
2649 }
2650 else
2651 {
2652 s->real_resx = s->res;
2653 s->real_resy = s->res;
2654 }
2655 s->real_pitchx = s->resx_max / s->real_resx;
2656 s->real_pitchy = s->resy_max / s->real_resy;
2657
2658 s->real_resx = s->resx_max / s->real_pitchx;
2659 s->real_resy = s->resy_max / s->real_pitchy;
2660
2661 /* The prefix "real_" refers to data in device units (1/maxdpi), "logical_" refers to resolution-dependent data. */
2662
2663 if (s->xmin < s->xmax)
2664 {
2665 xmin = s->xmin;
2666 xmax = s->xmax;
2667 }
2668 else
2669 {
2670 xmin = s->xmax;
2671 xmax = s->xmin;
2672 }
2673
2674 if (s->ymin < s->ymax)
2675 {
2676 ymin = s->ymin;
2677 ymax = s->ymax;
2678 }
2679 else
2680 {
2681 ymin = s->ymax;
2682 ymax = s->ymin;
2683 }
2684
2685 s->real_xoffset = xmin;
2686 s->real_yoffset =
2687 ymin + (s->i_frame - 1) * s->frame_offset + s->subframe / s->unit_mm;
2688 s->logical_width = (xmax - xmin + 1) / s->real_pitchx; /* XXXXXXXXX use mm units */
2689 s->logical_height = (ymax - ymin + 1) / s->real_pitchy;
2690 s->real_width = s->logical_width * s->real_pitchx;
2691 s->real_height = s->logical_height * s->real_pitchy;
2692
2693 s->odd_padding = 0;
2694 if ((s->bytes_per_pixel == 1) && (s->logical_width & 0x01)
2695 && (s->type != CS2_TYPE_LS30) && (s->type != CS2_TYPE_LS2000))
2696 s->odd_padding = 1;
2697
2698 if (s->focus_on_centre)
2699 {
2700 s->real_focusx = s->real_xoffset + s->real_width / 2;
2701 s->real_focusy = s->real_yoffset + s->real_height / 2;
2702 }
2703 else
2704 {
2705 s->real_focusx = s->focusx;
2706 s->real_focusy =
2707 s->focusy + (s->i_frame - 1) * s->frame_offset +
2708 s->subframe / s->unit_mm;
2709 }
2710
2711 s->real_exposure[1] = s->exposure * s->exposure_r * 100.;
2712 s->real_exposure[2] = s->exposure * s->exposure_g * 100.;
2713 s->real_exposure[3] = s->exposure * s->exposure_b * 100.;
2714
2715 for (i_colour = 0; i_colour < 3; i_colour++)
2716 if (s->real_exposure[cs2_colour_list[i_colour]] < 1)
2717 s->real_exposure[cs2_colour_list[i_colour]] = 1;
2718
2719 s->n_colour_out = s->n_colour_in = 3; /* XXXXXXXXXXXXXX CCCCCCCCCCCCCC */
2720
2721 s->xfer_bytes_total =
2722 s->bytes_per_pixel * s->n_colour_out * s->logical_width *
2723 s->logical_height;
2724
2725 if (s->preview)
2726 s->infrared_stage = s->infrared_next = CS2_INFRARED_OFF;
2727 else
2728 {
2729 if ((s->infrared) && (s->infrared_stage == CS2_INFRARED_OFF))
2730 s->infrared_next = CS2_INFRARED_IN;
2731
2732 s->infrared_stage = s->infrared_next;
2733
2734 if (s->infrared)
2735 {
2736 s->n_colour_in ++;
2737 s->n_infrared_buf =
2738 s->bytes_per_pixel * s->logical_width * s->logical_height;
2739 infrared_buf_new =
2740 (SANE_Byte *) cs2_xrealloc (s->infrared_buf, s->n_infrared_buf);
2741 if (infrared_buf_new)
2742 s->infrared_buf = infrared_buf_new;
2743 else
2744 return SANE_STATUS_NO_MEM;
2745 }
2746 }
2747
2748 return SANE_STATUS_GOOD;
2749 }
2750
2751 static SANE_Status
cs2_set_boundary(cs2_t *s)2752 cs2_set_boundary (cs2_t *s)
2753 {
2754 SANE_Status status;
2755 int i_boundary;
2756 unsigned long lvalue;
2757
2758 /* Ariel - Check this function */
2759
2760 cs2_scanner_ready (s, CS2_STATUS_READY);
2761 cs2_init_buffer (s);
2762 cs2_parse_cmd (s, "2a 00 88 00 00 03");
2763 cs2_pack_byte (s, ((4 + s->n_frames * 16) >> 16) & 0xff);
2764 cs2_pack_byte (s, ((4 + s->n_frames * 16) >> 8) & 0xff);
2765 cs2_pack_byte (s, (4 + s->n_frames * 16) & 0xff);
2766 cs2_parse_cmd (s, "00");
2767
2768 cs2_pack_byte (s, ((4 + s->n_frames * 16) >> 8) & 0xff);
2769 cs2_pack_byte (s, (4 + s->n_frames * 16) & 0xff);
2770 cs2_pack_byte (s, s->n_frames);
2771 cs2_pack_byte (s, s->n_frames);
2772 for (i_boundary = 0; i_boundary < s->n_frames; i_boundary++)
2773 {
2774 lvalue = s->frame_offset * i_boundary + s->subframe / s->unit_mm;
2775 cs2_pack_byte (s, (lvalue >> 24) & 0xff);
2776 cs2_pack_byte (s, (lvalue >> 16) & 0xff);
2777 cs2_pack_byte (s, (lvalue >> 8) & 0xff);
2778 cs2_pack_byte (s, lvalue & 0xff);
2779
2780 lvalue = 0;
2781 cs2_pack_byte (s, (lvalue >> 24) & 0xff);
2782 cs2_pack_byte (s, (lvalue >> 16) & 0xff);
2783 cs2_pack_byte (s, (lvalue >> 8) & 0xff);
2784 cs2_pack_byte (s, lvalue & 0xff);
2785
2786 lvalue = s->frame_offset * i_boundary + s->subframe / s->unit_mm + s->frame_offset - 1;
2787 cs2_pack_byte (s, (lvalue >> 24) & 0xff);
2788 cs2_pack_byte (s, (lvalue >> 16) & 0xff);
2789 cs2_pack_byte (s, (lvalue >> 8) & 0xff);
2790 cs2_pack_byte (s, lvalue & 0xff);
2791
2792 lvalue = s->boundaryx - 1;
2793 cs2_pack_byte (s, (lvalue >> 24) & 0xff);
2794 cs2_pack_byte (s, (lvalue >> 16) & 0xff);
2795 cs2_pack_byte (s, (lvalue >> 8) & 0xff);
2796 cs2_pack_byte (s, lvalue & 0xff);
2797 }
2798 status = cs2_issue_cmd (s);
2799 if (status)
2800 return status;
2801
2802 return SANE_STATUS_GOOD;
2803 }
2804
2805 static SANE_Status
cs2_scan(cs2_t * s, cs2_scan_t type)2806 cs2_scan (cs2_t * s, cs2_scan_t type)
2807 {
2808 SANE_Status status;
2809 int i_colour;
2810 cs2_pixel_t pixel;
2811 cs2_pixel_t *lut;
2812
2813 /* wait for device to be ready with document, and set device unit */
2814
2815 status = cs2_scanner_ready (s, CS2_STATUS_NO_DOCS);
2816 if (status)
2817 return status;
2818 if (s->status & CS2_STATUS_NO_DOCS)
2819 return SANE_STATUS_NO_DOCS;
2820
2821 cs2_scanner_ready (s, CS2_STATUS_READY);
2822 cs2_init_buffer (s);
2823 /* Ariel - the '0b' byte in the 'else' part seems to be wrong, should be 0 */
2824 if ((s->type == CS2_TYPE_LS50) || (s->type == CS2_TYPE_LS5000))
2825 cs2_parse_cmd (s, "15 10 00 00 14 00 00 00 00 08 00 00 00 00 00 00 00 01 03 06 00 00");
2826 else
2827 cs2_parse_cmd (s, "15 10 00 00 0c 00 0b 00 00 00 03 06 00 00");
2828 cs2_pack_byte (s, (s->unit_dpi >> 8) & 0xff);
2829 cs2_pack_byte (s, s->unit_dpi & 0xff);
2830 cs2_parse_cmd (s, "00 00");
2831 status = cs2_issue_cmd (s);
2832 if (status)
2833 return status;
2834
2835 status = cs2_convert_options (s);
2836 if (status)
2837 return status;
2838
2839 /* Ariel - Is this the best place to initialize it? */
2840 s->block_padding = 0;
2841
2842 status = cs2_set_boundary (s);
2843 if (status)
2844 return status;
2845
2846 switch (type)
2847 {
2848 case CS2_SCAN_NORMAL:
2849
2850 for (i_colour = 0; i_colour < s->n_colour_in; i_colour++)
2851 {
2852 cs2_scanner_ready (s, CS2_STATUS_READY);
2853
2854 switch (i_colour)
2855 {
2856 case 0:
2857 lut = s->lut_r;
2858 break;
2859 case 1:
2860 lut = s->lut_g;
2861 break;
2862 case 2:
2863 lut = s->lut_b;
2864 break;
2865 case 3:
2866 lut = s->lut_neutral;
2867 break;
2868 default:
2869 DBG (1,
2870 "BUG: cs2_scan(): Unknown colour number for LUT download.\n");
2871 return SANE_STATUS_INVAL;
2872 break;
2873 }
2874
2875 cs2_init_buffer (s);
2876 cs2_parse_cmd (s, "2a 00 03 00");
2877 cs2_pack_byte (s, cs2_colour_list[i_colour]);
2878 cs2_pack_byte (s, 2 - 1); /* XXXXXXXXXX number of bytes per data point - 1 */
2879 cs2_pack_byte (s, ((2 * s->n_lut) >> 16) & 0xff); /* XXXXXXXXXX 2 bytes per point */
2880 cs2_pack_byte (s, ((2 * s->n_lut) >> 8) & 0xff); /* XXXXXXXXXX 2 bytes per point */
2881 cs2_pack_byte (s, (2 * s->n_lut) & 0xff); /* XXXXXXXXXX 2 bytes per point */
2882 cs2_pack_byte (s, 0x00);
2883
2884 for (pixel = 0; pixel < s->n_lut; pixel++)
2885 { /* XXXXXXXXXXXXXXX 2 bytes per point */
2886 cs2_pack_byte (s, (lut[pixel] >> 8) & 0xff);
2887 cs2_pack_byte (s, lut[pixel] & 0xff);
2888 }
2889
2890 status = cs2_issue_cmd (s);
2891 if (status)
2892 return status;
2893 }
2894
2895 break;
2896
2897 default:
2898 break;
2899 }
2900
2901 for (i_colour = 0; i_colour < s->n_colour_in; i_colour++)
2902 {
2903 cs2_scanner_ready (s, CS2_STATUS_READY);
2904
2905 cs2_init_buffer (s);
2906 if ((s->type == CS2_TYPE_LS40) || (s->type == CS2_TYPE_LS4000))
2907 cs2_parse_cmd (s, "24 00 00 00 00 00 00 00 3a 80");
2908 else
2909 cs2_parse_cmd (s, "24 00 00 00 00 00 00 00 3a 00");
2910 cs2_parse_cmd (s, "00 00 00 00 00 00 00 32");
2911
2912 cs2_pack_byte (s, cs2_colour_list[i_colour]);
2913
2914 cs2_pack_byte (s, 0x00);
2915
2916 cs2_pack_byte (s, s->real_resx >> 8);
2917 cs2_pack_byte (s, s->real_resx & 0xff);
2918 cs2_pack_byte (s, s->real_resy >> 8);
2919 cs2_pack_byte (s, s->real_resy & 0xff);
2920
2921 cs2_pack_byte (s, (s->real_xoffset >> 24) & 0xff);
2922 cs2_pack_byte (s, (s->real_xoffset >> 16) & 0xff);
2923 cs2_pack_byte (s, (s->real_xoffset >> 8) & 0xff);
2924 cs2_pack_byte (s, s->real_xoffset & 0xff);
2925
2926 cs2_pack_byte (s, (s->real_yoffset >> 24) & 0xff);
2927 cs2_pack_byte (s, (s->real_yoffset >> 16) & 0xff);
2928 cs2_pack_byte (s, (s->real_yoffset >> 8) & 0xff);
2929 cs2_pack_byte (s, s->real_yoffset & 0xff);
2930
2931 cs2_pack_byte (s, (s->real_width >> 24) & 0xff);
2932 cs2_pack_byte (s, (s->real_width >> 16) & 0xff);
2933 cs2_pack_byte (s, (s->real_width >> 8) & 0xff);
2934 cs2_pack_byte (s, s->real_width & 0xff);
2935
2936 cs2_pack_byte (s, (s->real_height >> 24) & 0xff);
2937 cs2_pack_byte (s, (s->real_height >> 16) & 0xff);
2938 cs2_pack_byte (s, (s->real_height >> 8) & 0xff);
2939 cs2_pack_byte (s, s->real_height & 0xff);
2940
2941 cs2_pack_byte (s, 0x00); /* brightness, etc. */
2942 cs2_pack_byte (s, 0x00);
2943 cs2_pack_byte (s, 0x00);
2944 cs2_pack_byte (s, 0x05); /* image composition CCCCCCC */
2945 cs2_pack_byte (s, s->real_depth); /* pixel composition */
2946 cs2_parse_cmd (s, "00 00 00 00 00 00 00 00 00 00 00 00 00");
2947 cs2_pack_byte (s, ((s->samples_per_scan - 1) << 4) + 0x00); /* multiread, ordering */
2948 /* No need to use an undocumented bit in LS50 */
2949 if ((s->type == CS2_TYPE_LS50) || (s->type == CS2_TYPE_LS5000))
2950 cs2_pack_byte (s, 0x00 + (s->negative ? 0 : 1)); /* averaging, pos/neg */
2951 else
2952 cs2_pack_byte (s, 0x80 + (s->negative ? 0 : 1)); /* averaging, pos/neg */
2953
2954 switch (type)
2955 { /* scanning kind */
2956 case CS2_SCAN_NORMAL:
2957 cs2_pack_byte (s, 0x01);
2958 break;
2959 case CS2_SCAN_AE:
2960 cs2_pack_byte (s, 0x20);
2961 break;
2962 case CS2_SCAN_AE_WB:
2963 cs2_pack_byte (s, 0x40);
2964 break;
2965 default:
2966 DBG (1, "BUG: cs2_scan(): Unknown scanning type.\n");
2967 return SANE_STATUS_INVAL;
2968 }
2969 if (s->samples_per_scan == 1)
2970 cs2_pack_byte (s, 0x02); /* scanning mode single */
2971 else
2972 cs2_pack_byte (s, 0x10); /* scanning mode multi */
2973 cs2_pack_byte (s, 0x02); /* colour interleaving */
2974 cs2_pack_byte (s, 0xff); /* (ae) */
2975 if (i_colour == 3) /* infrared */
2976 cs2_parse_cmd (s, "00 00 00 00"); /* automatic */
2977 else
2978 {
2979 cs2_pack_byte (s,
2980 (s->
2981 real_exposure[cs2_colour_list[i_colour]] >> 24) &
2982 0xff);
2983 cs2_pack_byte (s,
2984 (s->
2985 real_exposure[cs2_colour_list[i_colour]] >> 16) &
2986 0xff);
2987 cs2_pack_byte (s,
2988 (s->
2989 real_exposure[cs2_colour_list[i_colour]] >> 8) &
2990 0xff);
2991 cs2_pack_byte (s,
2992 s->real_exposure[cs2_colour_list[i_colour]] & 0xff);
2993 }
2994 status = cs2_issue_cmd (s);
2995 if (status)
2996 return status;
2997 }
2998
2999 cs2_scanner_ready (s, CS2_STATUS_READY);
3000 cs2_focus (s);
3001
3002 cs2_scanner_ready (s, CS2_STATUS_READY);
3003 cs2_init_buffer (s);
3004 switch (s->n_colour_in)
3005 {
3006 case 3:
3007 cs2_parse_cmd (s, "1b 00 00 00 03 00 01 02 03");
3008 break;
3009 case 4:
3010 cs2_parse_cmd (s, "1b 00 00 00 04 00 01 02 03 09");
3011 break;
3012 default:
3013 DBG (1, "BUG: cs2_scan(): Unknown number of input colours.\n");
3014 break;
3015 }
3016 status = cs2_issue_cmd (s);
3017 if (status)
3018 return status;
3019 if (s->status == CS2_STATUS_REISSUE)
3020 {
3021 /* Make sure we don't affect the behaviour for other scanners */
3022 if ((s->type == CS2_TYPE_LS50) || (s->type == CS2_TYPE_LS5000))
3023 {
3024 cs2_init_buffer (s);
3025 cs2_parse_cmd (s, "28 00 87 00 00 00 00 00 06 00");
3026 s->n_recv = 6;
3027 status = cs2_issue_cmd (s);
3028 if (status)
3029 return status;
3030 cs2_init_buffer (s);
3031 cs2_parse_cmd (s, "28 00 87 00 00 00 00 00");
3032 cs2_pack_byte (s, s->recv_buf[5] + 6);
3033 cs2_parse_cmd (s, "00");
3034 s->n_recv = s->recv_buf[5] + 6;
3035 status = cs2_issue_cmd (s);
3036 if (status)
3037 return status;
3038 if ((s->recv_buf[11] != 0x08) || (s->recv_buf[12] != 0x00))
3039 DBG (1, "BUG: cs2_scan(): Unexpected block_padding position.\n");
3040 s->block_padding = 256 * s->recv_buf[19] + s->recv_buf[20];
3041 cs2_init_buffer (s);
3042 switch (s->n_colour_in)
3043 {
3044 case 3:
3045 cs2_parse_cmd (s, "1b 00 00 00 03 00 01 02 03");
3046 break;
3047 case 4:
3048 cs2_parse_cmd (s, "1b 00 00 00 04 00 01 02 03 09");
3049 break;
3050 }
3051 }
3052 status = cs2_issue_cmd (s);
3053 if (status)
3054 return status;
3055 }
3056
3057 return SANE_STATUS_GOOD;
3058 }
3059
3060 static void *
cs2_xmalloc(size_t size)3061 cs2_xmalloc (size_t size)
3062 {
3063 register void *value = malloc (size);
3064
3065 if (!value)
3066 DBG (0, "Error: cs2_xmalloc(): Failed to malloc() %lu bytes.\n",
3067 (unsigned long) size);
3068
3069 return value;
3070 }
3071
3072 static void *
cs2_xrealloc(void *p, size_t size)3073 cs2_xrealloc (void *p, size_t size)
3074 {
3075 register void *value;
3076
3077 if (!size)
3078 return p;
3079
3080 value = realloc (p, size);
3081
3082 if (!value)
3083 DBG (0, "Error: cs2_xrealloc(): Failed to realloc() %lu bytes.\n",
3084 (unsigned long) size);
3085
3086 return value;
3087 }
3088
3089 static void
cs2_xfree(const void *p)3090 cs2_xfree (const void *p)
3091 {
3092 if (p)
3093 free ((void *) p);
3094 }
3095