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