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