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