1 /* sane - Scanner Access Now Easy.
2
3 pie.c
4
5 Copyright (C) 2000 Simon Munton, based on the umax backend by Oliver Rauch
6
7 This file is part of the SANE package.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22 As a special exception, the authors of SANE give permission for
23 additional uses of the libraries contained in this release of SANE.
24
25 The exception is that, if you link a SANE library with other files
26 to produce an executable, this does not by itself cause the
27 resulting executable to be covered by the GNU General Public
28 License. Your use of that executable is in no way restricted on
29 account of linking the SANE library code into it.
30
31 This exception does not, however, invalidate any other reasons why
32 the executable file might be covered by the GNU General Public
33 License.
34
35 If you submit changes to SANE to the maintainers to be included in
36 a subsequent release, you agree by submitting the changes that
37 those changes may be distributed with this exception intact.
38
39 If you write modifications of your own for SANE, it is your choice
40 whether to permit this exception to apply to your modifications.
41 If you do not wish that, delete this exception notice. */
42
43 /*
44 * 22-2-2003 set devlist to NULL in sane_exit()
45 * set first_dev to NULL in sane_exit()
46 * eliminated num_devices
47 *
48 * 23-7-2002 added TL_X > BR_X, TL_Y > BR_Y check in sane_start
49 *
50 * 17-9-2001 changed ADLIB to AdLib as the comparison is case sensitive and
51 * the scanner returns AdLib
52 *
53 * 7-5-2001 removed removal of '\n' after sanei_config_read()
54 * free devlist allocated in sane_get_devices() on sane_exit()
55 *
56 * 2-3-2001 improved the reordering of RGB data in pie_reader_process()
57 *
58 * 11-11-2000 eliminated some warnings about signed/unsigned comparisons
59 * removed #undef NDEBUG and C++ style comments
60 *
61 * 1-10-2000 force gamma table to one to one mapping if lineart or halftone selected
62 *
63 * 30-9-2000 added ADLIB devices to scanner_str[]
64 *
65 * 29-9-2000 wasn't setting 'background is halftone bit' (BGHT) in halftone mode
66 *
67 * 27-9-2000 went public with build 4
68 */
69
70 #include "../include/sane/config.h"
71
72 #include <errno.h>
73 #include <fcntl.h>
74 #include <limits.h>
75 #include <signal.h>
76 #include <stdio.h>
77 #include <stdlib.h>
78 #include <string.h>
79 #include <sys/types.h>
80 #include <sys/wait.h>
81 #include <unistd.h>
82
83 #include "../include/sane/sane.h"
84 #include "../include/sane/sanei.h"
85 #include "../include/sane/saneopts.h"
86 #include "../include/sane/sanei_scsi.h"
87 #include "../include/sane/sanei_debug.h"
88
89 #define BACKEND_NAME pie
90 #include "../include/sane/sanei_backend.h"
91 #include "../include/sane/sanei_config.h"
92
93 # include "../include/sane/sanei_thread.h"
94
95 #include "pie-scsidef.h"
96
97 #define DBG_error0 0
98 #define DBG_error 1
99 #define DBG_sense 2
100 #define DBG_warning 3
101 #define DBG_inquiry 4
102
103 #define DBG_info 5
104 #define DBG_info2 6
105 #define DBG_proc 7
106 #define DBG_read 8
107 #define DBG_sane_init 10
108 #define DBG_sane_proc 11
109 #define DBG_sane_info 12
110 #define DBG_sane_option 13
111 #define DBG_dump 14
112
113 #define BUILD 9
114
115 #define PIE_CONFIG_FILE "pie.conf"
116
117 #define LINEART_STR SANE_VALUE_SCAN_MODE_LINEART
118 #define HALFTONE_STR SANE_VALUE_SCAN_MODE_HALFTONE
119 #define GRAY_STR SANE_VALUE_SCAN_MODE_GRAY
120 #define COLOR_STR SANE_VALUE_SCAN_MODE_COLOR
121
122 #define LINEART 1
123 #define HALFTONE 2
124 #define GRAYSCALE 3
125 #define RGB 4
126
127 #define CAL_MODE_PREVIEW (INQ_CAP_FAST_PREVIEW)
128 #define CAL_MODE_FLATBED 0x00
129 #define CAL_MODE_ADF (INQ_OPT_DEV_ADF)
130 #define CAL_MODE_TRANPSARENCY (INQ_OPT_DEV_TP)
131 #define CAL_MODE_TRANPSARENCY1 (INQ_OPT_DEV_TP1)
132
133 #define min(a,b) (((a)<(b))?(a):(b))
134 #define max(a,b) (((a)>(b))?(a):(b))
135
136
137 /* names of scanners that are supported because */
138 /* the inquiry_return_block is ok and driver is tested */
139
140 static char *scanner_str[] = {
141 "DEVCOM", "9636PRO",
142 "DEVCOM", "9636S",
143 "DEVCOM", "9630S",
144 "PIE", "ScanAce 1236S",
145 "PIE", "ScanAce 1230S",
146 "PIE", "ScanAce II",
147 "PIE", "ScanAce III",
148 "PIE", "ScanAce Plus",
149 "PIE", "ScanAce II Plus",
150 "PIE", "ScanAce III Plus",
151 "PIE", "ScanAce V",
152 "PIE", "ScanMedia",
153 "PIE", "ScanMedia II",
154 "PIE", "ScanAce 630S",
155 "PIE", "ScanAce 636S",
156 "AdLib", "JetScan 630",
157 "AdLib", "JetScan 636PRO",
158 "END_OF_LIST"
159 };
160
161 /* times (in us) to delay after certain commands. Scanner seems to lock up if it returns busy
162 * status and commands are repeatedly reissued (by kernel error handler) */
163
164 #define DOWNLOAD_GAMMA_WAIT_TIME (1000000)
165 #define SCAN_WAIT_TIME (1000000)
166 #define SCAN_WARMUP_WAIT_TIME (500000)
167 #define TUR_WAIT_TIME (500000)
168
169
170 /* options supported by the scanner */
171
172 enum Pie_Option
173 {
174 OPT_NUM_OPTS = 0,
175
176 /* ------------------------------------------- */
177 OPT_MODE_GROUP,
178 OPT_MODE,
179 OPT_RESOLUTION,
180
181
182 /* ------------------------------------------- */
183
184 OPT_GEOMETRY_GROUP,
185 OPT_TL_X, /* top-left x */
186 OPT_TL_Y, /* top-left y */
187 OPT_BR_X, /* bottom-right x */
188 OPT_BR_Y, /* bottom-right y */
189
190 /* ------------------------------------------- */
191
192 OPT_ENHANCEMENT_GROUP,
193
194 OPT_HALFTONE_PATTERN,
195 OPT_SPEED,
196 OPT_THRESHOLD,
197
198 OPT_GAMMA_VECTOR,
199 OPT_GAMMA_VECTOR_R,
200 OPT_GAMMA_VECTOR_G,
201 OPT_GAMMA_VECTOR_B,
202
203 /* ------------------------------------------- */
204
205 OPT_ADVANCED_GROUP,
206 OPT_PREVIEW,
207
208 /* must come last: */
209 NUM_OPTIONS
210 };
211
212
213
214
215 /* This defines the information needed during calibration */
216
217 struct Pie_cal_info
218 {
219 int cal_type;
220 int receive_bits;
221 int send_bits;
222 int num_lines;
223 int pixels_per_line;
224 };
225
226
227 /* This structure holds the information about a physical scanner */
228
229 typedef struct Pie_Device
230 {
231 struct Pie_Device *next;
232
233 char *devicename; /* name of the scanner device */
234
235 char vendor[9]; /* will be xxxxx */
236 char product[17]; /* e.g. "SuperVista_S12" or so */
237 char version[5]; /* e.g. V1.3 */
238
239 SANE_Device sane;
240 SANE_Range dpi_range;
241 SANE_Range x_range;
242 SANE_Range y_range;
243
244 SANE_Range exposure_range;
245 SANE_Range shadow_range;
246 SANE_Range highlight_range;
247
248 int inquiry_len; /* length of inquiry return block */
249
250 int inquiry_x_res; /* maximum x-resolution */
251 int inquiry_y_res; /* maximum y-resolution */
252 int inquiry_pixel_resolution;
253 double inquiry_fb_width; /* flatbed width in inches */
254 double inquiry_fb_length; /* flatbed length in inches */
255
256 int inquiry_trans_top_left_x;
257 int inquiry_trans_top_left_y;
258 double inquiry_trans_width; /* transparency width in inches */
259 double inquiry_trans_length; /* transparency length in inches */
260
261 int inquiry_halftones; /* number of halftones supported */
262 int inquiry_filters; /* available colour filters */
263 int inquiry_color_depths; /* available colour depths */
264 int inquiry_color_format; /* colour format from scanner */
265 int inquiry_image_format; /* image data format */
266 int inquiry_scan_capability; /* additional scanner features, number of speeds */
267 int inquiry_optional_devices; /* optional devices */
268 int inquiry_enhancements; /* enhancements */
269 int inquiry_gamma_bits; /* no of bits used for gamma table */
270 int inquiry_fast_preview_res; /* fast preview resolution */
271 int inquiry_min_highlight; /* min highlight % that can be used */
272 int inquiry_max_shadow; /* max shadow % that can be used */
273 int inquiry_cal_eqn; /* which calibration equation to use */
274 int inquiry_min_exp; /* min exposure % */
275 int inquiry_max_exp; /* max exposure % */
276
277 SANE_String scan_mode_list[7]; /* holds names of types of scan (color, ...) */
278
279 SANE_String halftone_list[17]; /* holds the names of the halftone patterns from the scanner */
280
281 SANE_String speed_list[9]; /* holds the names of available speeds */
282
283 int cal_info_count; /* number of calibration info sets */
284 struct Pie_cal_info *cal_info; /* points to the actual calibration information */
285 }
286 Pie_Device;
287
288 /* This structure holds information about an instance of an 'opened' scanner */
289
290 typedef struct Pie_Scanner
291 {
292 struct Pie_Scanner *next;
293 Pie_Device *device; /* pointer to physical scanner */
294
295 int sfd; /* scanner file desc. */
296 int bufsize; /* max scsi buffer size */
297
298 SANE_Option_Descriptor opt[NUM_OPTIONS]; /* option descriptions for this instance */
299 Option_Value val[NUM_OPTIONS]; /* option settings for this instance */
300 SANE_Int *gamma_table[4]; /* gamma tables for this instance */
301 SANE_Range gamma_range;
302 int gamma_length; /* size of gamma table */
303
304 int scanning; /* true if actually doing a scan */
305 SANE_Parameters params;
306
307 SANE_Pid reader_pid;
308 int pipe;
309 int reader_fds;
310
311 int colormode; /* whether RGB, GRAY, LINEART, HALFTONE */
312 int resolution;
313 int cal_mode; /* set to value to compare cal_info mode to */
314
315 int cal_filter; /* set to indicate which filters will provide data for cal */
316
317 int filter_offset1; /* offsets between colors in indexed scan mode */
318 int filter_offset2;
319
320 int bytes_per_line; /* number of bytes per line */
321
322 }
323 Pie_Scanner;
324
325 static const SANE_Range percentage_range_100 = {
326 0 << SANE_FIXED_SCALE_SHIFT, /* minimum */
327 100 << SANE_FIXED_SCALE_SHIFT, /* maximum */
328 0 << SANE_FIXED_SCALE_SHIFT /* quantization */
329 };
330
331 static Pie_Device *first_dev = NULL;
332 static Pie_Scanner *first_handle = NULL;
333 static const SANE_Device **devlist = NULL;
334
335
336
337 static SANE_Status pie_wait_scanner (Pie_Scanner * scanner);
338
339
340 /* ---------------------------------- PIE DUMP_BUFFER ---------------------------------- */
341
342 #define DBG_DUMP(level, buf, n) { if (DBG_LEVEL >= (level)) pie_dump_buffer(level,buf,n); }
343
344
345 static void
pie_dump_buffer(int level,unsigned char * buf,int n)346 pie_dump_buffer (int level, unsigned char *buf, int n)
347 {
348 char s[80], *p = s;
349 int a = 0;
350
351 while (n--)
352 {
353 if ((a % 16) == 0)
354 p += sprintf (p, " %04X ", a);
355
356 p += sprintf (p, "%02X ", *buf++);
357
358 if ((n == 0) || (a % 16) == 15)
359 {
360 DBG (level, "%s\n", s);
361 p = s;
362 }
363 a++;
364 }
365 }
366
367 /* ---------------------------------- PIE INIT ---------------------------------- */
368
369 static void
pie_init(Pie_Device * dev)370 pie_init (Pie_Device * dev) /* pie_init is called once while driver-initialization */
371 {
372 DBG (DBG_proc, "init\n");
373
374 dev->cal_info_count = 0;
375 dev->cal_info = NULL;
376
377 dev->devicename = NULL;
378 dev->inquiry_len = 0;
379
380 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
381 DBG (DBG_info,
382 "variable scsi buffer size (usage of sanei_scsi_open_extended)\n");
383 #else
384 DBG (DBG_info, "fixed scsi buffer size = %d bytes\n",
385 sanei_scsi_max_request_size);
386 #endif
387 }
388
389
390 /* ---------------------------- SENSE_HANDLER ------------------------------ */
391
392
393 static SANE_Status
sense_handler(__sane_unused__ int scsi_fd,unsigned char * result,__sane_unused__ void * arg)394 sense_handler (__sane_unused__ int scsi_fd, unsigned char *result, __sane_unused__ void *arg) /* is called by sanei_scsi */
395 {
396 unsigned char asc, ascq, sensekey;
397 int asc_ascq, len;
398 /* Pie_Device *dev = arg; */
399
400 DBG (DBG_proc, "check condition sense handler\n");
401
402 sensekey = get_RS_sense_key (result);
403 asc = get_RS_ASC (result);
404 ascq = get_RS_ASCQ (result);
405 asc_ascq = (int) (256 * asc + ascq);
406 len = 7 + get_RS_additional_length (result);
407
408 if (get_RS_error_code (result) != 0x70)
409 {
410 DBG (DBG_proc, "invalid sense key => handled as DEVICE BUSY!\n");
411 return SANE_STATUS_DEVICE_BUSY; /* sense key invalid */
412 }
413
414 DBG (DBG_sense, "check condition sense: %s\n", sense_str[sensekey]);
415
416 if (get_RS_ILI (result) != 0)
417 {
418 DBG (DBG_sense,
419 "-> ILI-ERROR: requested data length is larger than actual length\n");
420 }
421
422 switch (sensekey)
423 {
424 case 0x00: /* no sense, could have been busy */
425 return SANE_STATUS_IO_ERROR;
426 break;
427
428 case 0x02:
429 if (asc_ascq == 0x0401)
430 DBG (DBG_sense, "-> Not Ready - Warming Up\n");
431 else if (asc_ascq == 0x0483)
432 DBG (DBG_sense, "-> Not Ready - Need manual service\n");
433 else if (asc_ascq == 0x0881)
434 DBG (DBG_sense, "-> Not Ready - Communication time out\n");
435 else
436 DBG (DBG_sense, "-> unknown medium error: asc=%d, ascq=%d\n", asc,
437 ascq);
438 break;
439
440 case 0x03: /* medium error */
441 if (asc_ascq == 0x5300)
442 DBG (DBG_sense, "-> Media load or eject failure\n");
443 else if (asc_ascq == 0x3a00)
444 DBG (DBG_sense, "-> Media not present\n");
445 else if (asc_ascq == 0x3b05)
446 DBG (DBG_sense, "-> Paper jam\n");
447 else if (asc_ascq == 0x3a80)
448 DBG (DBG_sense, "-> ADF paper out\n");
449 else
450 DBG (DBG_sense, "-> unknown medium error: asc=%d, ascq=%d\n", asc,
451 ascq);
452 break;
453
454
455 case 0x04: /* hardware error */
456 if (asc_ascq == 0x4081)
457 DBG (DBG_sense, "-> CPU RAM failure\n");
458 else if (asc_ascq == 0x4082)
459 DBG (DBG_sense, "-> Scanning system RAM failure\n");
460 else if (asc_ascq == 0x4083)
461 DBG (DBG_sense, "-> Image buffer failure\n");
462 else if (asc_ascq == 0x0403)
463 DBG (DBG_sense, "-> Manual intervention required\n");
464 else if (asc_ascq == 0x6200)
465 DBG (DBG_sense, "-> Scan head position error\n");
466 else if (asc_ascq == 0x6000)
467 DBG (DBG_sense, "-> Lamp or CCD failure\n");
468 else if (asc_ascq == 0x6081)
469 DBG (DBG_sense, "-> Transparency lamp failure\n");
470 else if (asc_ascq == 0x8180)
471 DBG (DBG_sense, "-> DC offset or black level calibration failure\n");
472 else if (asc_ascq == 0x8181)
473 DBG (DBG_sense,
474 "-> Integration time adjustment failure (too light)\n");
475 else if (asc_ascq == 0x8182)
476 DBG (DBG_sense,
477 "-> Integration time adjustment failure (too dark)\n");
478 else if (asc_ascq == 0x8183)
479 DBG (DBG_sense, "-> Shading curve adjustment failure\n");
480 else if (asc_ascq == 0x8184)
481 DBG (DBG_sense, "-> Gain adjustment failure\n");
482 else if (asc_ascq == 0x8185)
483 DBG (DBG_sense, "-> Optical alignment failure\n");
484 else if (asc_ascq == 0x8186)
485 DBG (DBG_sense, "-> Optical locating failure\n");
486 else if (asc_ascq == 0x8187)
487 DBG (DBG_sense, "-> Scan pixel map less than 5100 pixels!\n");
488 else if (asc_ascq == 0x4700)
489 DBG (DBG_sense, "-> Parity error on SCSI bus\n");
490 else if (asc_ascq == 0x4b00)
491 DBG (DBG_sense, "-> Data phase error\n");
492 else
493 DBG (DBG_sense, "-> unknown hardware error: asc=%d, ascq=%d\n", asc,
494 ascq);
495 return SANE_STATUS_IO_ERROR;
496 break;
497
498
499 case 0x05: /* illegal request */
500 if (asc_ascq == 0x1a00)
501 DBG (DBG_sense, "-> Parameter list length error\n");
502 else if (asc_ascq == 0x2c01)
503 DBG (DBG_sense, "-> Too many windows specified\n");
504 else if (asc_ascq == 0x2c02)
505 DBG (DBG_sense, "-> Invalid combination of windows\n");
506 else if (asc_ascq == 0x2c81)
507 DBG (DBG_sense, "-> Illegal scanning frame\n");
508 else if (asc_ascq == 0x2400)
509 DBG (DBG_sense, "-> Invalid field in CDB\n");
510 else if (asc_ascq == 0x2481)
511 DBG (DBG_sense, "-> Request too many lines of data\n");
512 else if (asc_ascq == 0x2000)
513 DBG (DBG_sense, "-> Invalid command OP code\n");
514 else if (asc_ascq == 0x2501)
515 DBG (DBG_sense, "-> LUN not supported\n");
516 else if (asc_ascq == 0x2601)
517 DBG (DBG_sense, "-> Parameter not supported\n");
518 else if (asc_ascq == 0x2602)
519 DBG (DBG_sense,
520 "-> Parameter value invalid - Parameter not specified\n");
521 else if (asc_ascq == 0x2603)
522 DBG (DBG_sense, "-> Parameter value invalid - Invalid threshold\n");
523 else if (asc_ascq == 0x2680)
524 DBG (DBG_sense,
525 "-> Parameter value invalid - Control command sequence error\n");
526 else if (asc_ascq == 0x2681)
527 DBG (DBG_sense,
528 "-> Parameter value invalid - Grain setting (halftone pattern\n");
529 else if (asc_ascq == 0x2682)
530 DBG (DBG_sense,
531 "-> Parameter value invalid - Illegal resolution setting\n");
532 else if (asc_ascq == 0x2683)
533 DBG (DBG_sense,
534 "-> Parameter value invalid - Invalid filter assignment\n");
535 else if (asc_ascq == 0x2684)
536 DBG (DBG_sense,
537 "-> Parameter value invalid - Illegal gamma adjustment setting (look-up table)\n");
538 else if (asc_ascq == 0x2685)
539 DBG (DBG_sense,
540 "-> Parameter value invalid - Illegal offset setting (digital brightness)\n");
541 else if (asc_ascq == 0x2686)
542 DBG (DBG_sense,
543 "-> Parameter value invalid - Illegal bits per pixel setting\n");
544 else if (asc_ascq == 0x2687)
545 DBG (DBG_sense,
546 "-> Parameter value invalid - Illegal contrast setting\n");
547 else if (asc_ascq == 0x2688)
548 DBG (DBG_sense,
549 "-> Parameter value invalid - Illegal paper length setting\n");
550 else if (asc_ascq == 0x2689)
551 DBG (DBG_sense,
552 "-> Parameter value invalid - Illegal highlight/shadow setting\n");
553 else if (asc_ascq == 0x268a)
554 DBG (DBG_sense,
555 "-> Parameter value invalid - Illegal exposure time setting (analog brightness)\n");
556 else if (asc_ascq == 0x268b)
557 DBG (DBG_sense,
558 "-> Parameter value invalid - Invalid device select or device not exist\n");
559 else if (asc_ascq == 0x268c)
560 DBG (DBG_sense,
561 "-> Parameter value invalid - Illegal color packing\n");
562 else if (asc_ascq == 0x3d00)
563 DBG (DBG_sense, "-> Invalid bits in identify field\n");
564
565
566
567 else if (asc_ascq == 0x4900)
568 DBG (DBG_sense, "-> Invalid message\n");
569 else if (asc_ascq == 0x8101)
570 DBG (DBG_sense, "-> Not enough memory for color packing\n");
571
572 if (len >= 0x11)
573 {
574 if (get_RS_SKSV (result) != 0)
575 {
576 if (get_RS_CD (result) == 0)
577 {
578
579 DBG (DBG_sense, "-> illegal parameter in CDB\n");
580 }
581 else
582 {
583 DBG (DBG_sense,
584 "-> illegal parameter is in the data parameters sent during data out phase\n");
585 }
586
587 DBG (DBG_sense, "-> error detected in byte %d\n",
588 get_RS_field_pointer (result));
589 }
590 }
591 return SANE_STATUS_IO_ERROR;
592 break;
593
594
595 case 0x06: /* unit attention */
596 if (asc_ascq == 0x2900)
597 DBG (DBG_sense, "-> power on, reset or bus device reset\n");
598 if (asc_ascq == 0x8200)
599 DBG (DBG_sense,
600 "-> unit attention - calibration disable not granted\n");
601 if (asc_ascq == 0x8300)
602 DBG (DBG_sense, "-> unit attention - calibration will be ignored\n");
603 else
604 DBG (DBG_sense, "-> unit attention: asc=%d, ascq=%d\n", asc, ascq);
605 break;
606
607
608 case 0x09: /* vendor specific */
609 DBG (DBG_sense, "-> vendor specific sense-code: asc=%d, ascq=%d\n", asc,
610 ascq);
611 break;
612
613 case 0x0b:
614 if (asc_ascq == 0x0006)
615 DBG (DBG_sense, "-> Received ABORT message from initiator\n");
616 if (asc_ascq == 0x4800)
617 DBG (DBG_sense, "-> Initiator detected error message received\n");
618 if (asc_ascq == 0x4300)
619 DBG (DBG_sense, "-> Message error\n");
620 if (asc_ascq == 0x4500)
621 DBG (DBG_sense, "-> Select or re-select error\n");
622 else
623 DBG (DBG_sense, "-> aborted command: asc=%d, ascq=%d\n", asc, ascq);
624 break;
625
626 }
627
628 return SANE_STATUS_IO_ERROR;
629 }
630
631
632 /* -------------------------------- PIE PRINT INQUIRY ------------------------- */
633
634
635 static void
pie_print_inquiry(Pie_Device * dev)636 pie_print_inquiry (Pie_Device * dev)
637 {
638 DBG (DBG_inquiry, "INQUIRY:\n");
639 DBG (DBG_inquiry, "========\n");
640 DBG (DBG_inquiry, "\n");
641 DBG (DBG_inquiry, "vendor........................: '%s'\n", dev->vendor);
642 DBG (DBG_inquiry, "product.......................: '%s'\n", dev->product);
643 DBG (DBG_inquiry, "version.......................: '%s'\n", dev->version);
644
645 DBG (DBG_inquiry, "X resolution..................: %d dpi\n",
646 dev->inquiry_x_res);
647 DBG (DBG_inquiry, "Y resolution..................: %d dpi\n",
648 dev->inquiry_y_res);
649 DBG (DBG_inquiry, "pixel resolution..............: %d dpi\n",
650 dev->inquiry_pixel_resolution);
651 DBG (DBG_inquiry, "fb width......................: %f in\n",
652 dev->inquiry_fb_width);
653 DBG (DBG_inquiry, "fb length.....................: %f in\n",
654 dev->inquiry_fb_length);
655
656 DBG (DBG_inquiry, "transparency width............: %f in\n",
657 dev->inquiry_trans_width);
658 DBG (DBG_inquiry, "transparency length...........: %f in\n",
659 dev->inquiry_trans_length);
660 DBG (DBG_inquiry, "transparency offset...........: %d,%d\n",
661 dev->inquiry_trans_top_left_x, dev->inquiry_trans_top_left_y);
662
663 DBG (DBG_inquiry, "# of halftones................: %d\n",
664 dev->inquiry_halftones);
665
666 DBG (DBG_inquiry, "One pass color................: %s\n",
667 dev->inquiry_filters & INQ_ONE_PASS_COLOR ? "yes" : "no");
668
669 DBG (DBG_inquiry, "Filters.......................: %s%s%s%s (%02x)\n",
670 dev->inquiry_filters & INQ_FILTER_RED ? "Red " : "",
671 dev->inquiry_filters & INQ_FILTER_GREEN ? "Green " : "",
672 dev->inquiry_filters & INQ_FILTER_BLUE ? "Blue " : "",
673 dev->inquiry_filters & INQ_FILTER_NEUTRAL ? "Neutral " : "",
674 dev->inquiry_filters);
675
676 DBG (DBG_inquiry, "Color depths..................: %s%s%s%s%s%s (%02x)\n",
677 dev->inquiry_color_depths & INQ_COLOR_DEPTH_16 ? "16 bit " : "",
678 dev->inquiry_color_depths & INQ_COLOR_DEPTH_12 ? "12 bit " : "",
679 dev->inquiry_color_depths & INQ_COLOR_DEPTH_10 ? "10 bit " : "",
680 dev->inquiry_color_depths & INQ_COLOR_DEPTH_8 ? "8 bit " : "",
681 dev->inquiry_color_depths & INQ_COLOR_DEPTH_4 ? "4 bit " : "",
682 dev->inquiry_color_depths & INQ_COLOR_DEPTH_1 ? "1 bit " : "",
683 dev->inquiry_color_depths);
684
685 DBG (DBG_inquiry, "Color Format..................: %s%s%s (%02x)\n",
686 dev->inquiry_color_format & INQ_COLOR_FORMAT_INDEX ? "Indexed " : "",
687 dev->inquiry_color_format & INQ_COLOR_FORMAT_LINE ? "Line " : "",
688 dev->inquiry_color_format & INQ_COLOR_FORMAT_PIXEL ? "Pixel " : "",
689 dev->inquiry_color_format);
690
691 DBG (DBG_inquiry, "Image Format..................: %s%s%s%s (%02x)\n",
692 dev->inquiry_image_format & INQ_IMG_FMT_OKLINE ? "OKLine " : "",
693 dev->inquiry_image_format & INQ_IMG_FMT_BLK_ONE ? "BlackOne " : "",
694 dev->inquiry_image_format & INQ_IMG_FMT_MOTOROLA ? "Motorola " : "",
695 dev->inquiry_image_format & INQ_IMG_FMT_INTEL ? "Intel" : "",
696 dev->inquiry_image_format);
697
698 DBG (DBG_inquiry,
699 "Scan Capability...............: %s%s%s%s%d speeds (%02x)\n",
700 dev->inquiry_scan_capability & INQ_CAP_PWRSAV ? "PowerSave " : "",
701 dev->inquiry_scan_capability & INQ_CAP_EXT_CAL ? "ExtCal " : "",
702 dev->inquiry_scan_capability & INQ_CAP_FAST_PREVIEW ? "FastPreview" :
703 "",
704 dev->inquiry_scan_capability & INQ_CAP_DISABLE_CAL ? "DisCal " : "",
705 dev->inquiry_scan_capability & INQ_CAP_SPEEDS,
706 dev->inquiry_scan_capability);
707
708 DBG (DBG_inquiry, "Optional Devices..............: %s%s%s%s (%02x)\n",
709 dev->inquiry_optional_devices & INQ_OPT_DEV_MPCL ? "MultiPageLoad " :
710 "",
711 dev->inquiry_optional_devices & INQ_OPT_DEV_TP1 ? "TransModule1 " : "",
712 dev->inquiry_optional_devices & INQ_OPT_DEV_TP ? "TransModule " : "",
713 dev->inquiry_optional_devices & INQ_OPT_DEV_ADF ? "ADF " : "",
714 dev->inquiry_optional_devices);
715
716 DBG (DBG_inquiry, "Enhancement...................: %02x\n",
717 dev->inquiry_enhancements);
718 DBG (DBG_inquiry, "Gamma bits....................: %d\n",
719 dev->inquiry_gamma_bits);
720
721 DBG (DBG_inquiry, "Fast Preview Resolution.......: %d\n",
722 dev->inquiry_fast_preview_res);
723 DBG (DBG_inquiry, "Min Highlight.................: %d\n",
724 dev->inquiry_min_highlight);
725 DBG (DBG_inquiry, "Max Shadow....................: %d\n",
726 dev->inquiry_max_shadow);
727 DBG (DBG_inquiry, "Cal Eqn.......................: %d\n",
728 dev->inquiry_cal_eqn);
729 DBG (DBG_inquiry, "Min Exposure..................: %d\n",
730 dev->inquiry_min_exp);
731 DBG (DBG_inquiry, "Max Exposure..................: %d\n",
732 dev->inquiry_max_exp);
733 }
734
735
736 /* ------------------------------ PIE GET INQUIRY VALUES -------------------- */
737
738
739 static void
pie_get_inquiry_values(Pie_Device * dev,unsigned char * buffer)740 pie_get_inquiry_values (Pie_Device * dev, unsigned char *buffer)
741 {
742 DBG (DBG_proc, "get_inquiry_values\n");
743
744 dev->inquiry_len = get_inquiry_additional_length (buffer) + 5;
745
746 get_inquiry_vendor ((char *) buffer, dev->vendor);
747 get_inquiry_product ((char *) buffer, dev->product);
748 get_inquiry_version ((char *) buffer, dev->version);
749
750 dev->inquiry_x_res = get_inquiry_max_x_res (buffer);
751 dev->inquiry_y_res = get_inquiry_max_y_res (buffer);
752
753 if (dev->inquiry_y_res < 256)
754 {
755 /* y res is a multiplier */
756 dev->inquiry_pixel_resolution = dev->inquiry_x_res;
757 dev->inquiry_x_res *= dev->inquiry_y_res;
758 dev->inquiry_y_res = dev->inquiry_x_res;
759 }
760 else
761 {
762 /* y res really is resolution */
763 dev->inquiry_pixel_resolution =
764 min (dev->inquiry_x_res, dev->inquiry_y_res);
765 }
766
767 dev->inquiry_fb_width =
768 (double) get_inquiry_fb_max_scan_width (buffer) /
769 dev->inquiry_pixel_resolution;
770 dev->inquiry_fb_length =
771 (double) get_inquiry_fb_max_scan_length (buffer) /
772 dev->inquiry_pixel_resolution;
773
774 dev->inquiry_trans_top_left_x = get_inquiry_trans_x1 (buffer);
775 dev->inquiry_trans_top_left_y = get_inquiry_trans_y1 (buffer);
776
777 dev->inquiry_trans_width =
778 (double) (get_inquiry_trans_x2 (buffer) -
779 get_inquiry_trans_x1 (buffer)) / dev->inquiry_pixel_resolution;
780 dev->inquiry_trans_length =
781 (double) (get_inquiry_trans_y2 (buffer) -
782 get_inquiry_trans_y1 (buffer)) / dev->inquiry_pixel_resolution;
783
784 dev->inquiry_halftones = get_inquiry_halftones (buffer) & 0x0f;
785
786 dev->inquiry_filters = get_inquiry_filters (buffer);
787 dev->inquiry_color_depths = get_inquiry_color_depths (buffer);
788 dev->inquiry_color_format = get_inquiry_color_format (buffer);
789 dev->inquiry_image_format = get_inquiry_image_format (buffer);
790
791 dev->inquiry_scan_capability = get_inquiry_scan_capability (buffer);
792 dev->inquiry_optional_devices = get_inquiry_optional_devices (buffer);
793 dev->inquiry_enhancements = get_inquiry_enhancements (buffer);
794 dev->inquiry_gamma_bits = get_inquiry_gamma_bits (buffer);
795 dev->inquiry_fast_preview_res = get_inquiry_fast_preview_res (buffer);
796 dev->inquiry_min_highlight = get_inquiry_min_highlight (buffer);
797 dev->inquiry_max_shadow = get_inquiry_max_shadow (buffer);
798 dev->inquiry_cal_eqn = get_inquiry_cal_eqn (buffer);
799 dev->inquiry_min_exp = get_inquiry_min_exp (buffer);
800 dev->inquiry_max_exp = get_inquiry_max_exp (buffer);
801
802 pie_print_inquiry (dev);
803
804 return;
805 }
806
807 /* ----------------------------- PIE DO INQUIRY ---------------------------- */
808
809
810 static void
pie_do_inquiry(int sfd,unsigned char * buffer)811 pie_do_inquiry (int sfd, unsigned char *buffer)
812 {
813 size_t size;
814 SANE_Status status;
815
816 DBG (DBG_proc, "do_inquiry\n");
817 memset (buffer, '\0', 256); /* clear buffer */
818
819 size = 5;
820
821 set_inquiry_return_size (inquiry.cmd, size); /* first get only 5 bytes to get size of inquiry_return_block */
822 status = sanei_scsi_cmd (sfd, inquiry.cmd, inquiry.size, buffer, &size);
823 if (status)
824 {
825 DBG (DBG_error, "pie_do_inquiry: command returned status %s\n",
826 sane_strstatus (status));
827 }
828
829 size = get_inquiry_additional_length (buffer) + 5;
830
831 set_inquiry_return_size (inquiry.cmd, size); /* then get inquiry with actual size */
832 status = sanei_scsi_cmd (sfd, inquiry.cmd, inquiry.size, buffer, &size);
833 if (status)
834 {
835 DBG (DBG_error, "pie_do_inquiry: command returned status %s\n",
836 sane_strstatus (status));
837 }
838 }
839
840 /* ---------------------- PIE IDENTIFY SCANNER ---------------------- */
841
842
843 static int
pie_identify_scanner(Pie_Device * dev,int sfd)844 pie_identify_scanner (Pie_Device * dev, int sfd)
845 {
846 char vendor[9];
847 char product[0x11];
848 char version[5];
849 char *pp;
850 int i = 0;
851 unsigned char inquiry_block[256];
852
853 DBG (DBG_proc, "identify_scanner\n");
854
855 pie_do_inquiry (sfd, inquiry_block); /* get inquiry */
856
857 if (get_inquiry_periph_devtype (inquiry_block) != IN_periph_devtype_scanner)
858 {
859 return 1;
860 } /* no scanner */
861
862 get_inquiry_vendor ((char *) inquiry_block, vendor);
863 get_inquiry_product ((char *) inquiry_block, product);
864 get_inquiry_version ((char *) inquiry_block, version);
865
866 pp = &vendor[8];
867 vendor[8] = ' ';
868 while (*pp == ' ')
869 {
870 *pp-- = '\0';
871 }
872
873 pp = &product[0x10];
874 product[0x10] = ' ';
875 while (*pp == ' ')
876 {
877 *pp-- = '\0';
878 }
879
880 pp = &version[4];
881
882 version[4] = ' ';
883 while (*pp == ' ')
884 {
885 *pp-- = '\0';
886 }
887
888 DBG (DBG_info, "Found %s scanner %s version %s on device %s\n", vendor,
889 product, version, dev->devicename);
890
891 while (strncmp ("END_OF_LIST", scanner_str[2 * i], 11) != 0) /* Now identify full supported scanners */
892 {
893 if (!strncmp (vendor, scanner_str[2 * i], strlen (scanner_str[2 * i])))
894 {
895 if (!strncmp
896 (product, scanner_str[2 * i + 1],
897 strlen (scanner_str[2 * i + 1])))
898 {
899 DBG (DBG_info, "found supported scanner\n");
900
901 pie_get_inquiry_values (dev, inquiry_block);
902 return 0;
903 }
904 }
905 i++;
906 }
907
908 return 1; /* NO SUPPORTED SCANNER: short inquiry-block and unknown scanner */
909 }
910
911
912 /* ------------------------------- GET SPEEDS ----------------------------- */
913
914 static void
pie_get_speeds(Pie_Device * dev)915 pie_get_speeds (Pie_Device * dev)
916 {
917 int speeds = dev->inquiry_scan_capability & INQ_CAP_SPEEDS;
918
919 DBG (DBG_proc, "get_speeds\n");
920
921 if (speeds == 3)
922 {
923 dev->speed_list[0] = strdup ("Normal");
924 dev->speed_list[1] = strdup ("Fine");
925 dev->speed_list[2] = strdup ("Pro");
926 dev->speed_list[3] = NULL;
927 }
928 else
929 {
930 int i;
931 char buf[2];
932
933 buf[1] = '\0';
934
935 for (i = 0; i < speeds; i++)
936 {
937 buf[0] = '1' + i;
938 dev->speed_list[i] = strdup (buf);
939 }
940
941 dev->speed_list[i] = NULL;
942 }
943 }
944
945 /* ------------------------------- GET HALFTONES ----------------------------- */
946
947 static void
pie_get_halftones(Pie_Device * dev,int sfd)948 pie_get_halftones (Pie_Device * dev, int sfd)
949 {
950 int i;
951 size_t size;
952 SANE_Status status;
953 unsigned char *data;
954 unsigned char buffer[128];
955
956 DBG (DBG_proc, "get_halftones\n");
957
958 for (i = 0; i < dev->inquiry_halftones; i++)
959 {
960 size = 6;
961
962 set_write_length (swrite.cmd, size);
963
964 memcpy (buffer, swrite.cmd, swrite.size);
965
966 data = buffer + swrite.size;
967 memset (data, 0, size);
968
969 set_command (data, READ_HALFTONE);
970 set_data_length (data, 2);
971 data[4] = i;
972
973 status = sanei_scsi_cmd (sfd, buffer, swrite.size + size, NULL, NULL);
974 if (status)
975 {
976 DBG (DBG_error,
977 "pie_get_halftones: write command returned status %s\n",
978 sane_strstatus (status));
979 }
980 else
981 {
982 /* now read the halftone data */
983 memset (buffer, '\0', sizeof buffer); /* clear buffer */
984
985 size = 128;
986 set_read_length (sread.cmd, size);
987
988 DBG (DBG_info, "doing read\n");
989 status = sanei_scsi_cmd (sfd, sread.cmd, sread.size, buffer, &size);
990 if (status)
991 {
992 DBG (DBG_error,
993 "pie_get_halftones: read command returned status %s\n",
994 sane_strstatus (status));
995 }
996 else
997 {
998 unsigned char *s;
999
1000 s = buffer + 8 + buffer[6] * buffer[7];
1001
1002 DBG (DBG_info, "halftone %d: %s\n", i, s);
1003
1004 dev->halftone_list[i] = strdup ((char *)s);
1005 }
1006 }
1007 }
1008 dev->halftone_list[i] = NULL;
1009 }
1010
1011 /* ------------------------------- GET CAL DATA ----------------------------- */
1012
1013 static void
pie_get_cal_info(Pie_Device * dev,int sfd)1014 pie_get_cal_info (Pie_Device * dev, int sfd)
1015 {
1016 size_t size;
1017 SANE_Status status;
1018 unsigned char *data;
1019 unsigned char buffer[280];
1020
1021 DBG (DBG_proc, "get_cal_info\n");
1022
1023 if (!(dev->inquiry_scan_capability & INQ_CAP_EXT_CAL))
1024 return;
1025
1026 size = 6;
1027
1028 set_write_length (swrite.cmd, size);
1029
1030 memcpy (buffer, swrite.cmd, swrite.size);
1031
1032 data = buffer + swrite.size;
1033 memset (data, 0, size);
1034
1035 set_command (data, READ_CAL_INFO);
1036
1037 status = sanei_scsi_cmd (sfd, buffer, swrite.size + size, NULL, NULL);
1038 if (status)
1039 {
1040 DBG (DBG_error, "pie_get_cal_info: write command returned status %s\n",
1041 sane_strstatus (status));
1042 }
1043 else
1044 {
1045 /* now read the cal data */
1046 memset (buffer, '\0', sizeof buffer); /* clear buffer */
1047
1048 size = 128;
1049 set_read_length (sread.cmd, size);
1050
1051 DBG (DBG_info, "doing read\n");
1052 status = sanei_scsi_cmd (sfd, sread.cmd, sread.size, buffer, &size);
1053 if (status)
1054 {
1055 DBG (DBG_error,
1056 "pie_get_cal_info: read command returned status %s\n",
1057 sane_strstatus (status));
1058 }
1059 else
1060 {
1061 int i;
1062
1063 dev->cal_info_count = buffer[4];
1064 dev->cal_info =
1065 malloc (sizeof (struct Pie_cal_info) * dev->cal_info_count);
1066
1067 for (i = 0; i < dev->cal_info_count; i++)
1068 {
1069 dev->cal_info[i].cal_type = buffer[8 + i * buffer[5]];
1070 dev->cal_info[i].send_bits = buffer[9 + i * buffer[5]];
1071 dev->cal_info[i].receive_bits = buffer[10 + i * buffer[5]];
1072 dev->cal_info[i].num_lines = buffer[11 + i * buffer[5]];
1073 dev->cal_info[i].pixels_per_line =
1074 (buffer[13 + i * buffer[5]] << 8) + buffer[12 +
1075 i * buffer[5]];
1076
1077 DBG (DBG_info2, "%02x %2d %2d %2d %d\n",
1078 dev->cal_info[i].cal_type, dev->cal_info[i].send_bits,
1079 dev->cal_info[i].receive_bits, dev->cal_info[i].num_lines,
1080 dev->cal_info[i].pixels_per_line);
1081 }
1082 }
1083 }
1084 }
1085
1086 /* ------------------------------- ATTACH SCANNER ----------------------------- */
1087
1088 static SANE_Status
attach_scanner(const char * devicename,Pie_Device ** devp)1089 attach_scanner (const char *devicename, Pie_Device ** devp)
1090 {
1091 Pie_Device *dev;
1092 int sfd;
1093 int bufsize;
1094
1095 DBG (DBG_sane_proc, "attach_scanner: %s\n", devicename);
1096
1097 for (dev = first_dev; dev; dev = dev->next)
1098 {
1099 if (strcmp (dev->sane.name, devicename) == 0)
1100 {
1101 if (devp)
1102 {
1103 *devp = dev;
1104 }
1105 return SANE_STATUS_GOOD;
1106 }
1107 }
1108
1109 dev = malloc (sizeof (*dev));
1110 if (!dev)
1111 {
1112 return SANE_STATUS_NO_MEM;
1113 }
1114
1115 DBG (DBG_info, "attach_scanner: opening %s\n", devicename);
1116
1117 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
1118 bufsize = 16384; /* 16KB */
1119
1120 if (sanei_scsi_open_extended
1121 (devicename, &sfd, sense_handler, dev, &bufsize) != 0)
1122 {
1123 DBG (DBG_error, "attach_scanner: open failed\n");
1124 free (dev);
1125 return SANE_STATUS_INVAL;
1126 }
1127
1128 if (bufsize < 4096) /* < 4KB */
1129 {
1130 DBG (DBG_error,
1131 "attach_scanner: sanei_scsi_open_extended returned too small scsi buffer (%d)\n",
1132 bufsize);
1133 sanei_scsi_close (sfd);
1134 free (dev);
1135 return SANE_STATUS_NO_MEM;
1136 }
1137
1138 DBG (DBG_info,
1139 "attach_scanner: sanei_scsi_open_extended returned scsi buffer size = %d\n",
1140 bufsize);
1141 #else
1142 bufsize = sanei_scsi_max_request_size;
1143
1144 if (sanei_scsi_open (devicename, &sfd, sense_handler, dev) != 0)
1145 {
1146 DBG (DBG_error, "attach_scanner: open failed\n");
1147 free (dev);
1148
1149 return SANE_STATUS_INVAL;
1150
1151 }
1152 #endif
1153
1154 pie_init (dev); /* preset values in structure dev */
1155
1156 dev->devicename = strdup (devicename);
1157
1158 if (pie_identify_scanner (dev, sfd) != 0)
1159 {
1160 DBG (DBG_error, "attach_scanner: scanner-identification failed\n");
1161 sanei_scsi_close (sfd);
1162 free (dev);
1163 return SANE_STATUS_INVAL;
1164 }
1165
1166 pie_get_halftones (dev, sfd);
1167 pie_get_cal_info (dev, sfd);
1168 pie_get_speeds (dev);
1169
1170 dev->scan_mode_list[0] = COLOR_STR;
1171 dev->scan_mode_list[1] = GRAY_STR;
1172 dev->scan_mode_list[2] = LINEART_STR;
1173 dev->scan_mode_list[3] = HALFTONE_STR;
1174 dev->scan_mode_list[4] = 0;
1175
1176 sanei_scsi_close (sfd);
1177
1178 dev->sane.name = dev->devicename;
1179 dev->sane.vendor = dev->vendor;
1180 dev->sane.model = dev->product;
1181 dev->sane.type = "flatbed scanner";
1182
1183 dev->x_range.min = SANE_FIX (0);
1184 dev->x_range.quant = SANE_FIX (0);
1185 dev->x_range.max = SANE_FIX (dev->inquiry_fb_width * MM_PER_INCH);
1186
1187 dev->y_range.min = SANE_FIX (0);
1188 dev->y_range.quant = SANE_FIX (0);
1189 dev->y_range.max = SANE_FIX (dev->inquiry_fb_length * MM_PER_INCH);
1190
1191 dev->dpi_range.min = SANE_FIX (25);
1192 dev->dpi_range.quant = SANE_FIX (1);
1193 dev->dpi_range.max =
1194 SANE_FIX (max (dev->inquiry_x_res, dev->inquiry_y_res));
1195
1196 dev->shadow_range.min = SANE_FIX (0);
1197 dev->shadow_range.quant = SANE_FIX (1);
1198 dev->shadow_range.max = SANE_FIX (dev->inquiry_max_shadow);
1199
1200 dev->highlight_range.min = SANE_FIX (dev->inquiry_min_highlight);
1201 dev->highlight_range.quant = SANE_FIX (1);
1202 dev->highlight_range.max = SANE_FIX (100);
1203
1204 dev->exposure_range.min = SANE_FIX (dev->inquiry_min_exp);
1205 dev->exposure_range.quant = SANE_FIX (1);
1206 dev->exposure_range.max = SANE_FIX (dev->inquiry_max_exp);
1207
1208 #if 0
1209 dev->analog_gamma_range.min = SANE_FIX (1.0);
1210 dev->analog_gamma_range.quant = SANE_FIX (0.01);
1211 dev->analog_gamma_range.max = SANE_FIX (2.0);
1212
1213 #endif
1214
1215 dev->next = first_dev;
1216 first_dev = dev;
1217
1218 if (devp)
1219 {
1220 *devp = dev;
1221 }
1222
1223 return SANE_STATUS_GOOD;
1224 }
1225
1226 /* --------------------------- MAX STRING SIZE ---------------------------- */
1227
1228
1229 static size_t
max_string_size(SANE_String_Const strings[])1230 max_string_size (SANE_String_Const strings[])
1231 {
1232 size_t size, max_size = 0;
1233 int i;
1234
1235 for (i = 0; strings[i]; ++i)
1236 {
1237 size = strlen (strings[i]) + 1;
1238 if (size > max_size)
1239 {
1240 max_size = size;
1241 }
1242 }
1243
1244 return max_size;
1245 }
1246
1247
1248 /* --------------------------- INIT OPTIONS ------------------------------- */
1249
1250
1251 static SANE_Status
init_options(Pie_Scanner * scanner)1252 init_options (Pie_Scanner * scanner)
1253 {
1254 int i;
1255
1256 DBG (DBG_sane_proc, "init_options\n");
1257
1258 memset (scanner->opt, 0, sizeof (scanner->opt));
1259 memset (scanner->val, 0, sizeof (scanner->val));
1260
1261 for (i = 0; i < NUM_OPTIONS; ++i)
1262 {
1263 scanner->opt[i].size = sizeof (SANE_Word);
1264 scanner->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1265 }
1266
1267 scanner->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
1268 scanner->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
1269 scanner->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
1270 scanner->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
1271 scanner->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
1272
1273 /* "Mode" group: */
1274 scanner->opt[OPT_MODE_GROUP].title = "Scan Mode";
1275 scanner->opt[OPT_MODE_GROUP].desc = "";
1276 scanner->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
1277 scanner->opt[OPT_MODE_GROUP].cap = 0;
1278 scanner->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1279
1280 /* scan mode */
1281 scanner->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
1282 scanner->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
1283 scanner->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
1284 scanner->opt[OPT_MODE].type = SANE_TYPE_STRING;
1285 scanner->opt[OPT_MODE].size =
1286 max_string_size ((SANE_String_Const *) scanner->device->scan_mode_list);
1287 scanner->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1288 scanner->opt[OPT_MODE].constraint.string_list =
1289 (SANE_String_Const *) scanner->device->scan_mode_list;
1290 scanner->val[OPT_MODE].s =
1291 (SANE_Char *) strdup (scanner->device->scan_mode_list[0]);
1292
1293 /* x-resolution */
1294 scanner->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
1295 scanner->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
1296 scanner->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
1297 scanner->opt[OPT_RESOLUTION].type = SANE_TYPE_FIXED;
1298 scanner->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
1299 scanner->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
1300 scanner->opt[OPT_RESOLUTION].constraint.range = &scanner->device->dpi_range;
1301 scanner->val[OPT_RESOLUTION].w = 100 << SANE_FIXED_SCALE_SHIFT;
1302
1303 /* "Geometry" group: */
1304
1305 scanner->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
1306 scanner->opt[OPT_GEOMETRY_GROUP].desc = "";
1307 scanner->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
1308 scanner->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
1309 scanner->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1310
1311 /* top-left x */
1312 scanner->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
1313 scanner->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
1314 scanner->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
1315 scanner->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
1316 scanner->opt[OPT_TL_X].unit = SANE_UNIT_MM;
1317 scanner->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1318 scanner->opt[OPT_TL_X].constraint.range = &(scanner->device->x_range);
1319 scanner->val[OPT_TL_X].w = 0;
1320
1321 /* top-left y */
1322 scanner->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1323 scanner->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1324 scanner->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1325 scanner->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
1326 scanner->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
1327 scanner->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1328 scanner->opt[OPT_TL_Y].constraint.range = &(scanner->device->y_range);
1329 scanner->val[OPT_TL_Y].w = 0;
1330
1331 /* bottom-right x */
1332 scanner->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
1333 scanner->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
1334 scanner->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
1335 scanner->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
1336 scanner->opt[OPT_BR_X].unit = SANE_UNIT_MM;
1337 scanner->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
1338 scanner->opt[OPT_BR_X].constraint.range = &(scanner->device->x_range);
1339 scanner->val[OPT_BR_X].w = scanner->device->x_range.max;
1340
1341 /* bottom-right y */
1342 scanner->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
1343 scanner->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
1344 scanner->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
1345 scanner->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
1346 scanner->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
1347 scanner->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1348 scanner->opt[OPT_BR_Y].constraint.range = &(scanner->device->y_range);
1349 scanner->val[OPT_BR_Y].w = scanner->device->y_range.max;
1350
1351 /* "enhancement" group: */
1352
1353 scanner->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
1354 scanner->opt[OPT_ENHANCEMENT_GROUP].desc = "";
1355 scanner->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
1356 scanner->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
1357 scanner->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1358
1359 /* grayscale gamma vector */
1360 scanner->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
1361 scanner->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
1362 scanner->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
1363 scanner->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
1364 scanner->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
1365 scanner->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
1366 scanner->val[OPT_GAMMA_VECTOR].wa = scanner->gamma_table[0];
1367 scanner->opt[OPT_GAMMA_VECTOR].constraint.range = &scanner->gamma_range;
1368 scanner->opt[OPT_GAMMA_VECTOR].size =
1369 scanner->gamma_length * sizeof (SANE_Word);
1370 scanner->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1371
1372 /* red gamma vector */
1373 scanner->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
1374 scanner->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
1375 scanner->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
1376 scanner->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
1377 scanner->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
1378 scanner->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
1379 scanner->val[OPT_GAMMA_VECTOR_R].wa = scanner->gamma_table[1];
1380 scanner->opt[OPT_GAMMA_VECTOR_R].constraint.range = &(scanner->gamma_range);
1381 scanner->opt[OPT_GAMMA_VECTOR_R].size =
1382 scanner->gamma_length * sizeof (SANE_Word);
1383
1384 /* green gamma vector */
1385 scanner->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
1386 scanner->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
1387 scanner->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
1388 scanner->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
1389 scanner->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
1390 scanner->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
1391 scanner->val[OPT_GAMMA_VECTOR_G].wa = scanner->gamma_table[2];
1392 scanner->opt[OPT_GAMMA_VECTOR_G].constraint.range = &(scanner->gamma_range);
1393 scanner->opt[OPT_GAMMA_VECTOR_G].size =
1394 scanner->gamma_length * sizeof (SANE_Word);
1395
1396
1397 /* blue gamma vector */
1398 scanner->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
1399 scanner->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
1400 scanner->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
1401 scanner->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
1402 scanner->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
1403 scanner->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
1404 scanner->val[OPT_GAMMA_VECTOR_B].wa = scanner->gamma_table[3];
1405 scanner->opt[OPT_GAMMA_VECTOR_B].constraint.range = &(scanner->gamma_range);
1406 scanner->opt[OPT_GAMMA_VECTOR_B].size =
1407 scanner->gamma_length * sizeof (SANE_Word);
1408
1409 /* halftone pattern */
1410 scanner->opt[OPT_HALFTONE_PATTERN].name = SANE_NAME_HALFTONE_PATTERN;
1411 scanner->opt[OPT_HALFTONE_PATTERN].title = SANE_TITLE_HALFTONE_PATTERN;
1412 scanner->opt[OPT_HALFTONE_PATTERN].desc = SANE_DESC_HALFTONE_PATTERN;
1413 scanner->opt[OPT_HALFTONE_PATTERN].type = SANE_TYPE_STRING;
1414 scanner->opt[OPT_HALFTONE_PATTERN].size =
1415 max_string_size ((SANE_String_Const *) scanner->device->halftone_list);
1416 scanner->opt[OPT_HALFTONE_PATTERN].constraint_type =
1417 SANE_CONSTRAINT_STRING_LIST;
1418 scanner->opt[OPT_HALFTONE_PATTERN].constraint.string_list =
1419 (SANE_String_Const *) scanner->device->halftone_list;
1420 scanner->val[OPT_HALFTONE_PATTERN].s =
1421 (SANE_Char *) strdup (scanner->device->halftone_list[0]);
1422 scanner->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
1423
1424 /* speed */
1425 scanner->opt[OPT_SPEED].name = SANE_NAME_SCAN_SPEED;
1426 scanner->opt[OPT_SPEED].title = SANE_TITLE_SCAN_SPEED;
1427 scanner->opt[OPT_SPEED].desc = SANE_DESC_SCAN_SPEED;
1428 scanner->opt[OPT_SPEED].type = SANE_TYPE_STRING;
1429 scanner->opt[OPT_SPEED].size =
1430 max_string_size ((SANE_String_Const *) scanner->device->speed_list);
1431 scanner->opt[OPT_SPEED].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1432 scanner->opt[OPT_SPEED].constraint.string_list =
1433 (SANE_String_Const *) scanner->device->speed_list;
1434 scanner->val[OPT_SPEED].s =
1435 (SANE_Char *) strdup (scanner->device->speed_list[0]);
1436
1437 /* lineart threshold */
1438 scanner->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
1439 scanner->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
1440 scanner->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
1441 scanner->opt[OPT_THRESHOLD].type = SANE_TYPE_FIXED;
1442 scanner->opt[OPT_THRESHOLD].unit = SANE_UNIT_PERCENT;
1443 scanner->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
1444 scanner->opt[OPT_THRESHOLD].constraint.range = &percentage_range_100;
1445 scanner->val[OPT_THRESHOLD].w = SANE_FIX (50);
1446 scanner->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
1447
1448 /* "advanced" group: */
1449
1450 scanner->opt[OPT_ADVANCED_GROUP].title = "Advanced";
1451 scanner->opt[OPT_ADVANCED_GROUP].desc = "";
1452 scanner->opt[OPT_ADVANCED_GROUP].type = SANE_TYPE_GROUP;
1453 scanner->opt[OPT_ADVANCED_GROUP].cap = SANE_CAP_ADVANCED;
1454 scanner->opt[OPT_ADVANCED_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1455
1456 /* preview */
1457 scanner->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
1458 scanner->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
1459 scanner->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
1460 scanner->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
1461 scanner->val[OPT_PREVIEW].w = SANE_FALSE;
1462
1463
1464
1465 return SANE_STATUS_GOOD;
1466 }
1467
1468
1469 /*------------------------- PIE POWER SAVE -----------------------------*/
1470
1471 static SANE_Status
pie_power_save(Pie_Scanner * scanner,int time)1472 pie_power_save (Pie_Scanner * scanner, int time)
1473 {
1474 unsigned char buffer[128];
1475 size_t size;
1476 SANE_Status status;
1477 unsigned char *data;
1478
1479 DBG (DBG_proc, "pie_power_save: %d min\n", time);
1480
1481 size = 6;
1482
1483 set_write_length (swrite.cmd, size);
1484
1485 memcpy (buffer, swrite.cmd, swrite.size);
1486
1487 data = buffer + swrite.size;
1488 memset (data, 0, size);
1489
1490 set_command (data, SET_POWER_SAVE_CONTROL);
1491 set_data_length (data, size - 4);
1492 data[4] = time & 0x7f;
1493
1494 status =
1495 sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL);
1496 if (status)
1497 {
1498 DBG (DBG_error, "pie_power_save: write command returned status %s\n",
1499 sane_strstatus (status));
1500 }
1501
1502 return status;
1503 }
1504
1505 /*------------------------- PIE SEND EXPOSURE ONE -----------------------------*/
1506
1507
1508 static SANE_Status
pie_send_exposure_one(Pie_Scanner * scanner,int filter,int value)1509 pie_send_exposure_one (Pie_Scanner * scanner, int filter, int value)
1510 {
1511 unsigned char buffer[128];
1512 size_t size;
1513 SANE_Status status;
1514 unsigned char *data;
1515
1516 DBG (DBG_proc, "pie_send_exposure_one\n");
1517
1518 size = 8;
1519
1520 set_write_length (swrite.cmd, size);
1521
1522 memcpy (buffer, swrite.cmd, swrite.size);
1523
1524 data = buffer + swrite.size;
1525 memset (data, 0, size);
1526
1527 set_command (data, SET_EXP_TIME);
1528 set_data_length (data, size - 4);
1529
1530 data[4] = filter;
1531
1532 set_data (data, 6, (int) value, 2);
1533
1534 status =
1535 sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL);
1536 if (status)
1537 {
1538 DBG (DBG_error,
1539 "pie_send_exposure_one: write command returned status %s\n",
1540 sane_strstatus (status));
1541 }
1542
1543 return status;
1544 }
1545
1546 /*------------------------- PIE SEND EXPOSURE -----------------------------*/
1547
1548 static SANE_Status
pie_send_exposure(Pie_Scanner * scanner)1549 pie_send_exposure (Pie_Scanner * scanner)
1550 {
1551 SANE_Status status;
1552
1553 DBG (DBG_proc, "pie_send_exposure\n");
1554
1555 status = pie_send_exposure_one (scanner, FILTER_RED, 100);
1556 if (status)
1557 return status;
1558
1559 status = pie_send_exposure_one (scanner, FILTER_GREEN, 100);
1560 if (status)
1561 return status;
1562
1563 status = pie_send_exposure_one (scanner, FILTER_BLUE, 100);
1564 if (status)
1565 return status;
1566
1567 return SANE_STATUS_GOOD;
1568 }
1569
1570
1571 /*------------------------- PIE SEND HIGHLIGHT/SHADOW ONE -----------------------------*/
1572
1573 static SANE_Status
pie_send_highlight_shadow_one(Pie_Scanner * scanner,int filter,int highlight,int shadow)1574 pie_send_highlight_shadow_one (Pie_Scanner * scanner, int filter,
1575 int highlight, int shadow)
1576 {
1577 unsigned char buffer[128];
1578 size_t size;
1579 SANE_Status status;
1580 unsigned char *data;
1581
1582 DBG (DBG_proc, "pie_send_highlight_shadow_one\n");
1583
1584 size = 8;
1585
1586 set_write_length (swrite.cmd, size);
1587
1588 memcpy (buffer, swrite.cmd, swrite.size);
1589
1590 data = buffer + swrite.size;
1591 memset (data, 0, size);
1592
1593 set_command (data, SET_EXP_TIME);
1594 set_data_length (data, size - 4);
1595
1596 data[4] = filter;
1597
1598 data[6] = highlight;
1599 data[7] = shadow;
1600
1601 status =
1602 sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL);
1603 if (status)
1604 {
1605 DBG (DBG_error,
1606 "pie_send_highlight_shadow_one: write command returned status %s\n",
1607 sane_strstatus (status));
1608 }
1609
1610 return status;
1611 }
1612
1613 /*------------------------- PIE SEND HIGHLIGHT/SHADOW -----------------------------*/
1614
1615 static SANE_Status
pie_send_highlight_shadow(Pie_Scanner * scanner)1616 pie_send_highlight_shadow (Pie_Scanner * scanner)
1617 {
1618 SANE_Status status;
1619
1620 DBG (DBG_proc, "pie_send_highlight_shadow\n");
1621
1622 status = pie_send_highlight_shadow_one (scanner, FILTER_RED, 100, 0);
1623 if (status)
1624 return status;
1625
1626 status = pie_send_highlight_shadow_one (scanner, FILTER_GREEN, 100, 0);
1627 if (status)
1628 return status;
1629
1630 status = pie_send_highlight_shadow_one (scanner, FILTER_BLUE, 100, 0);
1631 if (status)
1632 return status;
1633
1634 return SANE_STATUS_GOOD;
1635 }
1636
1637 /*------------------------- PIE PERFORM CAL ----------------------------*/
1638
1639 static SANE_Status
pie_perform_cal(Pie_Scanner * scanner,int cal_index)1640 pie_perform_cal (Pie_Scanner * scanner, int cal_index)
1641 {
1642 long *red_result;
1643 long *green_result;
1644 long *blue_result;
1645 long *neutral_result;
1646 long *result = NULL;
1647 int rcv_length, send_length;
1648 int rcv_lines, rcv_bits, send_bits;
1649 int pixels_per_line;
1650 int i;
1651 unsigned char *rcv_buffer, *rcv_ptr;
1652 unsigned char *send_buffer, *send_ptr;
1653 size_t size;
1654 int fullscale;
1655 int cal_limit;
1656 int k;
1657 int filter;
1658 SANE_Status status;
1659
1660 DBG (DBG_proc, "pie_perform_cal\n");
1661
1662 pixels_per_line = scanner->device->cal_info[cal_index].pixels_per_line;
1663 rcv_length = pixels_per_line;
1664 send_length = pixels_per_line;
1665
1666 rcv_bits = scanner->device->cal_info[cal_index].receive_bits;
1667 if (rcv_bits > 8)
1668 rcv_length *= 2; /* 2 bytes / sample */
1669
1670 send_bits = scanner->device->cal_info[cal_index].send_bits;
1671 if (send_bits > 8)
1672 send_length *= 2; /* 2 bytes / sample */
1673
1674 rcv_lines = scanner->device->cal_info[cal_index].num_lines;
1675
1676 send_length += 2; /* space for filter at start */
1677
1678 if (scanner->colormode == RGB)
1679 {
1680 rcv_lines *= 3;
1681 send_length *= 3;
1682 rcv_length += 2; /* 2 bytes for index at front of data (only in RGB??) */
1683 }
1684
1685 send_length += 4; /* space for header at start of data */
1686
1687 /* allocate buffers for the receive data, the result buffers, and for the send data */
1688 rcv_buffer = (unsigned char *) malloc (rcv_length);
1689
1690 red_result = (long *) calloc (pixels_per_line, sizeof (long));
1691 green_result = (long *) calloc (pixels_per_line, sizeof (long));
1692 blue_result = (long *) calloc (pixels_per_line, sizeof (long));
1693 neutral_result = (long *) calloc (pixels_per_line, sizeof (long));
1694
1695 if (!rcv_buffer || !red_result || !green_result || !blue_result
1696 || !neutral_result)
1697 {
1698 /* at least one malloc failed, so free all buffers (free accepts NULL) */
1699 free (rcv_buffer);
1700 free (red_result);
1701 free (green_result);
1702 free (blue_result);
1703 free (neutral_result);
1704 return SANE_STATUS_NO_MEM;
1705 }
1706
1707 /* read the cal data a line at a time, and accumulate into the result arrays */
1708 while (rcv_lines--)
1709 {
1710 /* TUR */
1711 status = pie_wait_scanner (scanner);
1712 if (status)
1713 {
1714 free (rcv_buffer);
1715 free (red_result);
1716 free (green_result);
1717 free (blue_result);
1718 free (neutral_result);
1719 return status;
1720 }
1721
1722 set_read_length (sread.cmd, 1);
1723 size = rcv_length;
1724
1725 DBG (DBG_info, "pie_perform_cal: reading 1 line (%lu bytes)\n", (u_long) size);
1726
1727 status =
1728 sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, rcv_buffer,
1729 &size);
1730
1731 if (status)
1732 {
1733 DBG (DBG_error,
1734 "pie_perform_cal: read command returned status %s\n",
1735 sane_strstatus (status));
1736 free (rcv_buffer);
1737 free (red_result);
1738 free (green_result);
1739 free (blue_result);
1740 free (neutral_result);
1741 return status;
1742 }
1743
1744 DBG_DUMP (DBG_dump, rcv_buffer, 32);
1745
1746 /* which result buffer does this line belong to? */
1747 if (scanner->colormode == RGB)
1748 {
1749 if (*rcv_buffer == 'R')
1750 result = red_result;
1751 else if (*rcv_buffer == 'G')
1752 result = green_result;
1753 else if (*rcv_buffer == 'B')
1754 result = blue_result;
1755 else if (*rcv_buffer == 'N')
1756 result = neutral_result;
1757 else
1758 {
1759 DBG (DBG_error, "pie_perform_cal: invalid index byte (%02x)\n",
1760 *rcv_buffer);
1761 DBG_DUMP (DBG_error, rcv_buffer, 32);
1762 free (rcv_buffer);
1763 free (red_result);
1764 free (green_result);
1765 free (blue_result);
1766 free (neutral_result);
1767 return SANE_STATUS_INVAL;
1768 }
1769 rcv_ptr = rcv_buffer + 2;
1770 }
1771 else
1772 {
1773 /* monochrome - no bytes indicating filter here */
1774 result = neutral_result;
1775 rcv_ptr = rcv_buffer;
1776 }
1777
1778 /* now add the values in this line to the result array */
1779 for (i = 0; i < pixels_per_line; i++)
1780 {
1781 result[i] += *rcv_ptr++;
1782 if (rcv_bits > 8)
1783 {
1784 result[i] += (*rcv_ptr++) << 8;
1785 }
1786 }
1787 }
1788
1789 /* got all the cal data, now process it ready to send back */
1790 free (rcv_buffer);
1791 send_buffer = (unsigned char *) malloc (send_length + swrite.size);
1792
1793 if (!send_buffer)
1794 {
1795 free (red_result);
1796 free (green_result);
1797 free (blue_result);
1798 free (neutral_result);
1799 return SANE_STATUS_NO_MEM;
1800 }
1801
1802 rcv_lines = scanner->device->cal_info[cal_index].num_lines;
1803 fullscale = (1 << rcv_bits) - 1;
1804 cal_limit = fullscale / (1 << scanner->device->inquiry_cal_eqn);
1805 k = (1 << scanner->device->inquiry_cal_eqn) - 1;
1806
1807 /* set up scsi command and data */
1808 size = send_length;
1809
1810 memcpy (send_buffer, swrite.cmd, swrite.size);
1811 set_write_length (send_buffer, size);
1812
1813 set_command (send_buffer + swrite.size, SEND_CAL_DATA);
1814 set_data_length (send_buffer + swrite.size, size - 4);
1815
1816 send_ptr = send_buffer + swrite.size + 4;
1817
1818 for (filter = FILTER_NEUTRAL; filter <= FILTER_BLUE; filter <<= 1)
1819 {
1820
1821 /* only send data for filter we expect to send */
1822 if (!(filter & scanner->cal_filter))
1823 continue;
1824
1825 set_data (send_ptr, 0, filter, 2);
1826 send_ptr += 2;
1827
1828 if (scanner->colormode == RGB)
1829 {
1830 switch (filter)
1831 {
1832 case FILTER_RED:
1833 result = red_result;
1834 break;
1835
1836 case FILTER_GREEN:
1837 result = green_result;
1838 break;
1839
1840 case FILTER_BLUE:
1841 result = blue_result;
1842 break;
1843
1844 case FILTER_NEUTRAL:
1845 result = neutral_result;
1846 break;
1847 }
1848 }
1849 else
1850 result = neutral_result;
1851
1852 /* for each pixel */
1853 for (i = 0; i < pixels_per_line; i++)
1854 {
1855 long x;
1856
1857 /* make average */
1858 x = result[i] / rcv_lines;
1859
1860 /* ensure not overflowed */
1861 if (x > fullscale)
1862 x = fullscale;
1863
1864 /* process according to required calibration equation */
1865 if (scanner->device->inquiry_cal_eqn)
1866 {
1867 if (x <= cal_limit)
1868 x = fullscale;
1869 else
1870 x = ((fullscale - x) * fullscale) / (x * k);
1871 }
1872
1873 if (rcv_bits > send_bits)
1874 x >>= (rcv_bits - send_bits);
1875 else if (send_bits > rcv_bits)
1876 x <<= (send_bits - rcv_bits);
1877
1878 /* put result into send buffer */
1879 *send_ptr++ = x;
1880 if (send_bits > 8)
1881 *send_ptr++ = x >> 8;
1882 }
1883 }
1884
1885 /* now send the data back to scanner */
1886
1887 /* TUR */
1888 status = pie_wait_scanner (scanner);
1889 if (status)
1890 {
1891 free (red_result);
1892 free (green_result);
1893 free (blue_result);
1894 free (neutral_result);
1895 free (send_buffer);
1896 return status;
1897 }
1898
1899 DBG (DBG_info, "pie_perform_cal: sending cal data (%lu bytes)\n", (u_long) size);
1900 DBG_DUMP (DBG_dump, send_buffer, 64);
1901
1902 status =
1903 sanei_scsi_cmd (scanner->sfd, send_buffer, swrite.size + size, NULL,
1904 NULL);
1905 if (status)
1906 {
1907 DBG (DBG_error, "pie_perform_cal: write command returned status %s\n",
1908 sane_strstatus (status));
1909 free (red_result);
1910 free (green_result);
1911 free (blue_result);
1912 free (neutral_result);
1913 free (send_buffer);
1914 return status;
1915 }
1916
1917 free (red_result);
1918 free (green_result);
1919 free (blue_result);
1920 free (neutral_result);
1921 free (send_buffer);
1922
1923 return SANE_STATUS_GOOD;
1924 }
1925
1926 /*------------------------- PIE DO CAL -----------------------------*/
1927
1928 static SANE_Status
pie_do_cal(Pie_Scanner * scanner)1929 pie_do_cal (Pie_Scanner * scanner)
1930 {
1931 SANE_Status status;
1932 int cal_index;
1933
1934 DBG (DBG_proc, "pie_do_cal\n");
1935
1936 if (scanner->device->inquiry_scan_capability & INQ_CAP_EXT_CAL)
1937 {
1938 for (cal_index = 0; cal_index < scanner->device->cal_info_count;
1939 cal_index++)
1940 if (scanner->device->cal_info[cal_index].cal_type ==
1941 scanner->cal_mode)
1942 {
1943 status = pie_perform_cal (scanner, cal_index);
1944 if (status != SANE_STATUS_GOOD)
1945 return status;
1946 }
1947 }
1948
1949 return SANE_STATUS_GOOD;
1950 }
1951
1952 /*------------------------- PIE DWNLD GAMMA ONE -----------------------------*/
1953
1954 static SANE_Status
pie_dwnld_gamma_one(Pie_Scanner * scanner,int filter,SANE_Int * table)1955 pie_dwnld_gamma_one (Pie_Scanner * scanner, int filter, SANE_Int * table)
1956 {
1957 unsigned char *buffer;
1958 size_t size;
1959 SANE_Status status;
1960 unsigned char *data;
1961 int i;
1962
1963 DBG (DBG_proc, "pie_dwnld_gamma_one\n");
1964
1965 /* TUR */
1966 status = pie_wait_scanner (scanner);
1967 if (status)
1968 {
1969 return status;
1970 }
1971
1972 if (scanner->device->inquiry_gamma_bits > 8)
1973 size = scanner->gamma_length * 2 + 6;
1974 else
1975 size = scanner->gamma_length + 6;
1976
1977 buffer = malloc (size + swrite.size);
1978 if (!buffer)
1979 return SANE_STATUS_NO_MEM;
1980
1981 set_write_length (swrite.cmd, size);
1982
1983 memcpy (buffer, swrite.cmd, swrite.size);
1984
1985 data = buffer + swrite.size;
1986 memset (data, 0, size);
1987
1988 set_command (data, DWNLD_GAMMA_TABLE);
1989 set_data_length (data, size - 4);
1990
1991 data[4] = filter;
1992
1993 for (i = 0; i < scanner->gamma_length; i++)
1994 {
1995 if (scanner->device->inquiry_gamma_bits > 8)
1996 {
1997 set_data (data, 6 + 2 * i, table ? table[i] : i, 2);
1998 }
1999 else
2000 {
2001 set_data (data, 6 + i, table ? table[i] : i, 1);
2002 }
2003 }
2004
2005 DBG_DUMP (DBG_dump, data, 128);
2006
2007 status =
2008 sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL);
2009 if (status)
2010 {
2011 DBG (DBG_error,
2012 "pie_dwnld_gamma_one: write command returned status %s\n",
2013 sane_strstatus (status));
2014 }
2015
2016 free (buffer);
2017
2018 return status;
2019 }
2020
2021 /*------------------------- PIE DWNLD GAMMA -----------------------------*/
2022
2023 static SANE_Status
pie_dwnld_gamma(Pie_Scanner * scanner)2024 pie_dwnld_gamma (Pie_Scanner * scanner)
2025 {
2026 SANE_Status status;
2027
2028 DBG (DBG_proc, "pie_dwnld_gamma\n");
2029
2030 if (scanner->colormode == RGB)
2031 {
2032 status =
2033 pie_dwnld_gamma_one (scanner, FILTER_RED, scanner->gamma_table[1]);
2034 if (status)
2035 return status;
2036
2037
2038 status =
2039 pie_dwnld_gamma_one (scanner, FILTER_GREEN, scanner->gamma_table[2]);
2040 if (status)
2041 return status;
2042
2043 status =
2044 pie_dwnld_gamma_one (scanner, FILTER_BLUE, scanner->gamma_table[3]);
2045 if (status)
2046 return status;
2047 }
2048 else
2049 {
2050 SANE_Int *table;
2051
2052 /* if lineart or half tone, force gamma to be one to one by passing NULL */
2053 if (scanner->colormode == GRAYSCALE)
2054 table = scanner->gamma_table[0];
2055 else
2056 table = NULL;
2057
2058 status = pie_dwnld_gamma_one (scanner, FILTER_GREEN, table);
2059 if (status)
2060 return status;
2061 }
2062
2063 usleep (DOWNLOAD_GAMMA_WAIT_TIME);
2064
2065 return SANE_STATUS_GOOD;
2066 }
2067
2068 /*------------------------- PIE SET WINDOW -----------------------------*/
2069
2070 static SANE_Status
pie_set_window(Pie_Scanner * scanner)2071 pie_set_window (Pie_Scanner * scanner)
2072 {
2073 unsigned char buffer[128];
2074 size_t size;
2075 SANE_Status status;
2076 unsigned char *data;
2077 double x, dpmm;
2078
2079 DBG (DBG_proc, "pie_set_window\n");
2080
2081 size = 14;
2082
2083 set_write_length (swrite.cmd, size);
2084
2085 memcpy (buffer, swrite.cmd, swrite.size);
2086
2087 data = buffer + swrite.size;
2088 memset (data, 0, size);
2089
2090 set_command (data, SET_SCAN_FRAME);
2091 set_data_length (data, size - 4);
2092
2093 data[4] = 0x80;
2094 if (scanner->colormode == HALFTONE)
2095 data[4] |= 0x40;
2096
2097 dpmm = (double) scanner->device->inquiry_pixel_resolution / MM_PER_INCH;
2098
2099 x = SANE_UNFIX (scanner->val[OPT_TL_X].w) * dpmm;
2100 set_data (data, 6, (int) x, 2);
2101 DBG (DBG_info, "TL_X: %d\n", (int) x);
2102
2103 x = SANE_UNFIX (scanner->val[OPT_TL_Y].w) * dpmm;
2104 set_data (data, 8, (int) x, 2);
2105 DBG (DBG_info, "TL_Y: %d\n", (int) x);
2106
2107 x = SANE_UNFIX (scanner->val[OPT_BR_X].w) * dpmm;
2108 set_data (data, 10, (int) x, 2);
2109 DBG (DBG_info, "BR_X: %d\n", (int) x);
2110
2111 x = SANE_UNFIX (scanner->val[OPT_BR_Y].w) * dpmm;
2112 set_data (data, 12, (int) x, 2);
2113 DBG (DBG_info, "BR_Y: %d\n", (int) x);
2114
2115 status =
2116 sanei_scsi_cmd (scanner->sfd, buffer, swrite.size + size, NULL, NULL);
2117 if (status)
2118 {
2119 DBG (DBG_error, "pie_set_window: write command returned status %s\n",
2120 sane_strstatus (status));
2121 }
2122
2123 return status;
2124 }
2125
2126
2127 /*------------------------- PIE MODE SELECT -----------------------------*/
2128
2129 static SANE_Status
pie_mode_select(Pie_Scanner * scanner)2130 pie_mode_select (Pie_Scanner * scanner)
2131 {
2132
2133 SANE_Status status;
2134 unsigned char buffer[128];
2135 size_t size;
2136 unsigned char *data;
2137 int i;
2138
2139 DBG (DBG_proc, "pie_mode_select\n");
2140
2141 size = 14;
2142
2143 set_mode_length (smode.cmd, size);
2144
2145 memcpy (buffer, smode.cmd, smode.size);
2146
2147 data = buffer + smode.size;
2148 memset (data, 0, size);
2149
2150 /* size of data */
2151 data[1] = size - 2;
2152
2153 /* set resolution required */
2154 set_data (data, 2, scanner->resolution, 2);
2155
2156 /* set color filter and color depth */
2157 switch (scanner->colormode)
2158 {
2159 case RGB:
2160 if (scanner->device->inquiry_filters & INQ_ONE_PASS_COLOR)
2161 {
2162 data[4] = INQ_ONE_PASS_COLOR;
2163 scanner->cal_filter = FILTER_RED | FILTER_GREEN | FILTER_BLUE;
2164 }
2165 else
2166 {
2167 DBG (DBG_error,
2168 "pie_mode_select: support for multipass color not yet implemented\n");
2169 return SANE_STATUS_UNSUPPORTED;
2170 }
2171 data[5] = INQ_COLOR_DEPTH_8;
2172 break;
2173
2174 case GRAYSCALE:
2175 case LINEART:
2176 case HALFTONE:
2177 /* choose which filter to use for monochrome mode */
2178 if (scanner->device->inquiry_filters & INQ_FILTER_NEUTRAL)
2179 {
2180 data[4] = FILTER_NEUTRAL;
2181 scanner->cal_filter = FILTER_NEUTRAL;
2182 }
2183 else if (scanner->device->inquiry_filters & INQ_FILTER_GREEN)
2184 {
2185 data[4] = FILTER_GREEN;
2186 scanner->cal_filter = FILTER_GREEN;
2187 }
2188 else if (scanner->device->inquiry_filters & INQ_FILTER_RED)
2189 {
2190 data[4] = FILTER_RED;
2191 scanner->cal_filter = FILTER_RED;
2192 }
2193 else if (scanner->device->inquiry_filters & INQ_FILTER_BLUE)
2194 {
2195 data[4] = FILTER_BLUE;
2196 scanner->cal_filter = FILTER_BLUE;
2197 }
2198 else
2199 {
2200 DBG (DBG_error,
2201 "pie_mode_select: scanner doesn't appear to support monochrome\n");
2202 return SANE_STATUS_UNSUPPORTED;
2203 }
2204
2205 if (scanner->colormode == GRAYSCALE)
2206 data[5] = INQ_COLOR_DEPTH_8;
2207 else
2208 data[5] = INQ_COLOR_DEPTH_1;
2209 break;
2210 }
2211
2212 /* choose color packing method */
2213 if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_LINE)
2214 data[6] = INQ_COLOR_FORMAT_LINE;
2215 else if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_INDEX)
2216 data[6] = INQ_COLOR_FORMAT_INDEX;
2217 else
2218 {
2219 DBG (DBG_error,
2220 "pie_mode_select: support for pixel packing not yet implemented\n");
2221 return SANE_STATUS_UNSUPPORTED;
2222 }
2223
2224 /* choose data format */
2225 if (scanner->device->inquiry_image_format & INQ_IMG_FMT_INTEL)
2226 data[8] = INQ_IMG_FMT_INTEL;
2227 else
2228 {
2229 DBG (DBG_error,
2230 "pie_mode_select: support for Motorola format not yet implemented\n");
2231 return SANE_STATUS_UNSUPPORTED;
2232 }
2233
2234 /* set required speed */
2235 i = 0;
2236 while (scanner->device->speed_list[i] != NULL)
2237 {
2238 if (strcmp (scanner->device->speed_list[i], scanner->val[OPT_SPEED].s)
2239 == 0)
2240 break;
2241 i++;
2242 }
2243
2244 if (scanner->device->speed_list[i] == NULL)
2245 data[9] = 0;
2246 else
2247 data[9] = i;
2248
2249 scanner->cal_mode = CAL_MODE_FLATBED;
2250
2251 /* if preview supported, ask for preview, limit resolution to max for fast preview */
2252 if (scanner->val[OPT_PREVIEW].w
2253 && (scanner->device->inquiry_scan_capability & INQ_CAP_FAST_PREVIEW))
2254 {
2255 DBG (DBG_info, "pie_mode_select: setting preview\n");
2256 scanner->cal_mode |= CAL_MODE_PREVIEW;
2257 data[9] |= INQ_CAP_FAST_PREVIEW;
2258 data[9] &= ~INQ_CAP_SPEEDS;
2259 if (scanner->resolution > scanner->device->inquiry_fast_preview_res)
2260 set_data (data, 2, scanner->device->inquiry_fast_preview_res, 2);
2261 }
2262
2263
2264 /* set required halftone pattern */
2265 i = 0;
2266 while (scanner->device->halftone_list[i] != NULL)
2267 {
2268 if (strcmp
2269 (scanner->device->halftone_list[i],
2270 scanner->val[OPT_HALFTONE_PATTERN].s) == 0)
2271 break;
2272 i++;
2273 }
2274
2275 if (scanner->device->halftone_list[i] == NULL)
2276 data[12] = 0; /* halftone pattern */
2277 else
2278 data[12] = i;
2279
2280 data[13] = SANE_UNFIX (scanner->val[OPT_THRESHOLD].w) * 255 / 100; /* lineart threshold */
2281
2282 DBG (DBG_info, "pie_mode_select: speed %02x\n", data[9]);
2283 DBG (DBG_info, "pie_mode_select: halftone %d\n", data[12]);
2284 DBG (DBG_info, "pie_mode_select: threshold %02x\n", data[13]);
2285
2286 status =
2287 sanei_scsi_cmd (scanner->sfd, buffer, smode.size + size, NULL, NULL);
2288 if (status)
2289 {
2290 DBG (DBG_error, "pie_mode_select: write command returned status %s\n",
2291 sane_strstatus (status));
2292 }
2293
2294 return status;
2295 }
2296
2297
2298 /*------------------------- PIE SCAN -----------------------------*/
2299
2300 static SANE_Status
pie_scan(Pie_Scanner * scanner,int start)2301 pie_scan (Pie_Scanner * scanner, int start)
2302 {
2303 SANE_Status status;
2304
2305 DBG (DBG_proc, "pie_scan\n");
2306
2307 /* TUR */
2308 status = pie_wait_scanner (scanner);
2309 if (status)
2310 {
2311 return status;
2312 }
2313
2314 set_scan_cmd (scan.cmd, start);
2315
2316 do
2317 {
2318 status = sanei_scsi_cmd (scanner->sfd, scan.cmd, scan.size, NULL, NULL);
2319 if (status)
2320 {
2321 DBG (DBG_error, "pie_scan: write command returned status %s\n",
2322 sane_strstatus (status));
2323 usleep (SCAN_WARMUP_WAIT_TIME);
2324 }
2325 }
2326 while (start && status);
2327
2328 usleep (SCAN_WAIT_TIME);
2329
2330 return status;
2331 }
2332
2333
2334 /* --------------------------------------- PIE WAIT SCANNER -------------------------- */
2335
2336
2337 static SANE_Status
pie_wait_scanner(Pie_Scanner * scanner)2338 pie_wait_scanner (Pie_Scanner * scanner)
2339 {
2340 SANE_Status status;
2341 int cnt = 0;
2342
2343 DBG (DBG_proc, "wait_scanner\n");
2344
2345 do
2346 {
2347 if (cnt > 100) /* maximal 100 * 0.5 sec = 50 sec */
2348 {
2349 DBG (DBG_warning, "scanner does not get ready\n");
2350 return -1;
2351 }
2352 /* test unit ready */
2353 status =
2354 sanei_scsi_cmd (scanner->sfd, test_unit_ready.cmd,
2355 test_unit_ready.size, NULL, NULL);
2356 cnt++;
2357
2358 if (status)
2359 {
2360 if (cnt == 1)
2361 {
2362 DBG (DBG_info2, "scanner reports %s, waiting ...\n",
2363 sane_strstatus (status));
2364 }
2365
2366 usleep (TUR_WAIT_TIME);
2367 }
2368 }
2369 while (status != SANE_STATUS_GOOD);
2370
2371 DBG (DBG_info, "scanner ready\n");
2372
2373
2374 return status;
2375 }
2376
2377
2378 /* -------------------------------------- PIE GET PARAMS -------------------------- */
2379
2380
2381 static SANE_Status
pie_get_params(Pie_Scanner * scanner)2382 pie_get_params (Pie_Scanner * scanner)
2383 {
2384 SANE_Status status;
2385 size_t size;
2386 unsigned char buffer[128];
2387
2388 DBG (DBG_proc, "pie_get_params\n");
2389
2390 status = pie_wait_scanner (scanner);
2391 if (status)
2392 return status;
2393
2394 if (scanner->device->inquiry_image_format & INQ_IMG_FMT_OKLINE)
2395 size = 16;
2396 else
2397
2398 size = 14;
2399
2400 set_param_length (param.cmd, size);
2401
2402 status =
2403 sanei_scsi_cmd (scanner->sfd, param.cmd, param.size, buffer, &size);
2404
2405 if (status)
2406 {
2407 DBG (DBG_error, "pie_get_params: command returned status %s\n",
2408 sane_strstatus (status));
2409 }
2410 else
2411 {
2412 DBG (DBG_info, "Scan Width: %d\n", get_param_scan_width (buffer));
2413 DBG (DBG_info, "Scan Lines: %d\n", get_param_scan_lines (buffer));
2414 DBG (DBG_info, "Scan bytes: %d\n", get_param_scan_bytes (buffer));
2415
2416 DBG (DBG_info, "Offset 1: %d\n",
2417 get_param_scan_filter_offset1 (buffer));
2418 DBG (DBG_info, "Offset 2: %d\n",
2419 get_param_scan_filter_offset2 (buffer));
2420 DBG (DBG_info, "Scan period: %d\n", get_param_scan_period (buffer));
2421 DBG (DBG_info, "Xfer rate: %d\n", get_param_scsi_xfer_rate (buffer));
2422 if (scanner->device->inquiry_image_format & INQ_IMG_FMT_OKLINE)
2423 DBG (DBG_info, "Avail lines: %d\n",
2424 get_param_scan_available_lines (buffer));
2425
2426 scanner->filter_offset1 = get_param_scan_filter_offset1 (buffer);
2427 scanner->filter_offset2 = get_param_scan_filter_offset2 (buffer);
2428 scanner->bytes_per_line = get_param_scan_bytes (buffer);
2429
2430 scanner->params.pixels_per_line = get_param_scan_width (buffer);
2431 scanner->params.lines = get_param_scan_lines (buffer);
2432
2433 switch (scanner->colormode)
2434 {
2435 case RGB:
2436 scanner->params.format = SANE_FRAME_RGB;
2437 scanner->params.depth = 8;
2438 scanner->params.bytes_per_line = 3 * get_param_scan_bytes (buffer);
2439 break;
2440
2441 case GRAYSCALE:
2442 scanner->params.format = SANE_FRAME_GRAY;
2443 scanner->params.depth = 8;
2444 scanner->params.bytes_per_line = get_param_scan_bytes (buffer);
2445 break;
2446
2447 case HALFTONE:
2448 case LINEART:
2449 scanner->params.format = SANE_FRAME_GRAY;
2450 scanner->params.depth = 1;
2451 scanner->params.bytes_per_line = get_param_scan_bytes (buffer);
2452 break;
2453 }
2454
2455 scanner->params.last_frame = 0;
2456 }
2457
2458 return status;
2459 }
2460
2461
2462 /* -------------------------------------- PIE GRAB SCANNER -------------------------- */
2463
2464
2465 static SANE_Status
pie_grab_scanner(Pie_Scanner * scanner)2466 pie_grab_scanner (Pie_Scanner * scanner)
2467 {
2468 SANE_Status status;
2469
2470 DBG (DBG_proc, "grab_scanner\n");
2471
2472
2473 status = pie_wait_scanner (scanner);
2474 if (status)
2475 return status;
2476
2477 status =
2478 sanei_scsi_cmd (scanner->sfd, reserve_unit.cmd, reserve_unit.size, NULL,
2479 NULL);
2480
2481
2482 if (status)
2483 {
2484 DBG (DBG_error, "pie_grab_scanner: command returned status %s\n",
2485 sane_strstatus (status));
2486 }
2487 else
2488 {
2489 DBG (DBG_info, "scanner reserved\n");
2490 }
2491
2492 return status;
2493 }
2494
2495
2496 /* ------------------------------------ PIE GIVE SCANNER -------------------------- */
2497
2498
2499 static SANE_Status
pie_give_scanner(Pie_Scanner * scanner)2500 pie_give_scanner (Pie_Scanner * scanner)
2501 {
2502 SANE_Status status;
2503
2504 DBG (DBG_info2, "trying to release scanner ...\n");
2505
2506 status =
2507 sanei_scsi_cmd (scanner->sfd, release_unit.cmd, release_unit.size, NULL,
2508 NULL);
2509 if (status)
2510 {
2511 DBG (DBG_error, "pie_give_scanner: command returned status %s\n",
2512 sane_strstatus (status));
2513 }
2514 else
2515 {
2516 DBG (DBG_info, "scanner released\n");
2517 }
2518 return status;
2519 }
2520
2521
2522 /* ------------------- PIE READER PROCESS INDEXED ------------------- */
2523
2524 static int
pie_reader_process_indexed(Pie_Scanner * scanner,FILE * fp)2525 pie_reader_process_indexed (Pie_Scanner * scanner, FILE * fp)
2526 {
2527 int status;
2528 int lines;
2529 unsigned char *buffer, *reorder = NULL;
2530 unsigned char *red_buffer = NULL, *green_buffer = NULL;
2531 unsigned char *red_in = NULL, *red_out = NULL;
2532 unsigned char *green_in = NULL, *green_out = NULL;
2533 int red_size = 0, green_size = 0;
2534 int bytes_per_line;
2535 int red_count = 0, green_count = 0;
2536
2537 size_t size;
2538
2539 DBG (DBG_read, "reading %d lines of %d bytes/line (indexed)\n",
2540 scanner->params.lines, scanner->params.bytes_per_line);
2541
2542 lines = scanner->params.lines;
2543 bytes_per_line = scanner->bytes_per_line;
2544
2545 /* allocate receive buffer */
2546 buffer = malloc (bytes_per_line + 2);
2547 if (!buffer)
2548 {
2549 return SANE_STATUS_NO_MEM;
2550 }
2551
2552 /* allocate deskew buffers for RGB mode */
2553 if (scanner->colormode == RGB)
2554 {
2555 lines *= 3;
2556
2557 red_size = bytes_per_line * (scanner->filter_offset1 +
2558 scanner->filter_offset2 + 2);
2559 green_size = bytes_per_line * (scanner->filter_offset2 + 2);
2560
2561 DBG (DBG_info2,
2562 "pie_reader_process_indexed: alloc %d lines (%d bytes) for red buffer\n",
2563 red_size / bytes_per_line, red_size);
2564 DBG (DBG_info2,
2565 "pie_reader_process_indexed: alloc %d lines (%d bytes) for green buffer\n",
2566 green_size / bytes_per_line, green_size);
2567
2568 reorder = malloc (scanner->params.bytes_per_line);
2569 red_buffer = malloc (red_size);
2570 green_buffer = malloc (green_size);
2571
2572 if (!reorder || !red_buffer || !green_buffer)
2573 {
2574 free (buffer);
2575 free (reorder);
2576 free (red_buffer);
2577 free (green_buffer);
2578 return SANE_STATUS_NO_MEM;
2579 }
2580
2581 red_in = red_out = red_buffer;
2582 green_in = green_out = green_buffer;
2583 }
2584
2585 while (lines--)
2586 {
2587 set_read_length (sread.cmd, 1);
2588 size = bytes_per_line + 2;
2589
2590 do
2591 {
2592 status =
2593 sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, buffer,
2594 &size);
2595 }
2596 while (status);
2597
2598 DBG_DUMP (DBG_dump, buffer, 64);
2599
2600 if (scanner->colormode == RGB)
2601 {
2602 /* we're assuming that we get red before green before blue here */
2603 switch (*buffer)
2604 {
2605 case 'R':
2606 /* copy to red buffer */
2607 memcpy (red_in, buffer + 2, bytes_per_line);
2608
2609 /* advance in pointer, and check for wrap */
2610 red_in += bytes_per_line;
2611 if (red_in >= (red_buffer + red_size))
2612 red_in = red_buffer;
2613
2614 /* increment red line count */
2615 red_count++;
2616 DBG (DBG_info2,
2617 "pie_reader_process_indexed: got a red line (%d)\n",
2618 red_count);
2619 break;
2620
2621 case 'G':
2622 /* copy to green buffer */
2623 memcpy (green_in, buffer + 2, bytes_per_line);
2624
2625 /* advance in pointer, and check for wrap */
2626 green_in += bytes_per_line;
2627 if (green_in >= (green_buffer + green_size))
2628 green_in = green_buffer;
2629
2630 /* increment green line count */
2631 green_count++;
2632 DBG (DBG_info2,
2633 "pie_reader_process_indexed: got a green line (%d)\n",
2634 green_count);
2635 break;
2636
2637 case 'B':
2638 /* check we actually have red and green data available */
2639 if (!red_count || !green_count)
2640 {
2641 DBG (DBG_error,
2642 "pie_reader_process_indexed: deskew buffer empty (%d %d)\n",
2643 red_count, green_count);
2644 return SANE_STATUS_INVAL;
2645 }
2646 red_count--;
2647 green_count--;
2648
2649 DBG (DBG_info2,
2650 "pie_reader_process_indexed: got a blue line\n");
2651
2652 {
2653 int i;
2654 unsigned char *red, *green, *blue, *dest;
2655
2656 /* now pack the pixels lines into RGB format */
2657 dest = reorder;
2658 red = red_out;
2659 green = green_out;
2660 blue = buffer + 2;
2661
2662 for (i = bytes_per_line; i > 0; i--)
2663 {
2664 *dest++ = *red++;
2665 *dest++ = *green++;
2666 *dest++ = *blue++;
2667 }
2668 fwrite (reorder, 1, scanner->params.bytes_per_line, fp);
2669
2670 /* advance out pointers, and check for wrap */
2671 red_out += bytes_per_line;
2672 if (red_out >= (red_buffer + red_size))
2673 red_out = red_buffer;
2674 green_out += bytes_per_line;
2675 if (green_out >= (green_buffer + green_size))
2676 green_out = green_buffer;
2677 }
2678 break;
2679
2680 default:
2681 DBG (DBG_error,
2682 "pie_reader_process_indexed: bad filter index\n");
2683 }
2684 }
2685 else
2686 {
2687 DBG (DBG_info2,
2688 "pie_reader_process_indexed: got a line (%lu bytes)\n", (u_long) size);
2689
2690 /* just send the data on, assume filter bytes not present as per calibration case */
2691 fwrite (buffer, 1, scanner->params.bytes_per_line, fp);
2692 }
2693 }
2694
2695 free (buffer);
2696 free (reorder);
2697 free (red_buffer);
2698 free (green_buffer);
2699 return 0;
2700 }
2701
2702 /* --------------------------------- PIE READER PROCESS ------------------------ */
2703
2704 static int
pie_reader_process(Pie_Scanner * scanner,FILE * fp)2705 pie_reader_process (Pie_Scanner * scanner, FILE * fp)
2706 {
2707 int status;
2708 int lines;
2709 unsigned char *buffer, *reorder;
2710 size_t size;
2711
2712 DBG (DBG_read, "reading %d lines of %d bytes/line\n", scanner->params.lines,
2713 scanner->params.bytes_per_line);
2714
2715 buffer = malloc (scanner->params.bytes_per_line);
2716 reorder = malloc (scanner->params.bytes_per_line);
2717 if (!buffer || !reorder)
2718 {
2719 free (buffer);
2720 free (reorder);
2721 return SANE_STATUS_NO_MEM;
2722 }
2723
2724 lines = scanner->params.lines;
2725
2726 while (lines--)
2727 {
2728 set_read_length (sread.cmd, 1);
2729 size = scanner->params.bytes_per_line;
2730
2731 do
2732 {
2733 status =
2734 sanei_scsi_cmd (scanner->sfd, sread.cmd, sread.size, buffer,
2735 &size);
2736 }
2737 while (status);
2738
2739 DBG_DUMP (DBG_dump, buffer, 64);
2740
2741 if (scanner->colormode == RGB)
2742 {
2743 int i;
2744 unsigned char *src, *dest;
2745 int offset;
2746
2747 dest = reorder;
2748 src = buffer;
2749 offset = scanner->params.pixels_per_line;
2750
2751 for (i = scanner->params.pixels_per_line; i > 0; i--)
2752 {
2753 *dest++ = *src;
2754 *dest++ = *(src + offset);
2755 *dest++ = *(src + 2 * offset);
2756 src++;
2757 }
2758 fwrite (reorder, 1, scanner->params.bytes_per_line, fp);
2759 }
2760 else
2761 {
2762 fwrite (buffer, 1, scanner->params.bytes_per_line, fp);
2763 }
2764
2765 fflush (fp);
2766 }
2767
2768 free (buffer);
2769 free (reorder);
2770
2771 return 0;
2772 }
2773
2774
2775
2776 /* --------------------------------- READER PROCESS SIGTERM HANDLER ------------ */
2777
2778
2779 static void
reader_process_sigterm_handler(int signal)2780 reader_process_sigterm_handler (int signal)
2781 {
2782 DBG (DBG_sane_info, "reader_process: terminated by signal %d\n", signal);
2783
2784 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
2785 sanei_scsi_req_flush_all (); /* flush SCSI queue */
2786 #else
2787 sanei_scsi_req_flush_all (); /* flush SCSI queue */
2788 #endif
2789
2790 _exit (SANE_STATUS_GOOD);
2791 }
2792
2793
2794
2795 /* ------------------------------ READER PROCESS ----------------------------- */
2796
2797
2798 static int
reader_process(void * data)2799 reader_process ( void *data ) /* executed as a child process */
2800 {
2801 int status;
2802 FILE *fp;
2803 Pie_Scanner * scanner;
2804 sigset_t ignore_set;
2805 struct SIGACTION act;
2806
2807 scanner = (Pie_Scanner *)data;
2808
2809 if (sanei_thread_is_forked ()) {
2810
2811 close ( scanner->pipe );
2812
2813 sigfillset (&ignore_set);
2814 sigdelset (&ignore_set, SIGTERM);
2815 #if defined (__APPLE__) && defined (__MACH__)
2816 sigdelset (&ignore_set, SIGUSR2);
2817 #endif
2818 sigprocmask (SIG_SETMASK, &ignore_set, 0);
2819
2820 memset (&act, 0, sizeof (act));
2821 sigaction (SIGTERM, &act, 0);
2822 }
2823
2824 DBG (DBG_sane_proc, "reader_process started\n");
2825
2826 memset (&act, 0, sizeof (act)); /* define SIGTERM-handler */
2827 act.sa_handler = reader_process_sigterm_handler;
2828 sigaction (SIGTERM, &act, 0);
2829
2830 fp = fdopen (scanner->reader_fds, "w");
2831 if (!fp)
2832 {
2833 return SANE_STATUS_IO_ERROR;
2834 }
2835
2836 DBG (DBG_sane_info, "reader_process: starting to READ data\n");
2837
2838 if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_LINE)
2839 status = pie_reader_process (scanner, fp);
2840 else if (scanner->device->inquiry_color_format & INQ_COLOR_FORMAT_INDEX)
2841 status = pie_reader_process_indexed (scanner, fp);
2842 else
2843 status = SANE_STATUS_UNSUPPORTED;
2844
2845 fclose (fp);
2846
2847 DBG (DBG_sane_info, "reader_process: finished reading data\n");
2848
2849 return status;
2850 }
2851
2852
2853 /* -------------------------------- ATTACH_ONE ---------------------------------- */
2854
2855
2856 /* callback function for sanei_config_attach_matching_devices(dev_name, attach_one) */
2857 static SANE_Status
attach_one(const char * name)2858 attach_one (const char *name)
2859 {
2860 attach_scanner (name, 0);
2861 return SANE_STATUS_GOOD;
2862 }
2863
2864
2865 /* ----------------------------- CLOSE PIPE ---------------------------------- */
2866
2867
2868 static SANE_Status
close_pipe(Pie_Scanner * scanner)2869 close_pipe (Pie_Scanner * scanner)
2870 {
2871 DBG (DBG_sane_proc, "close_pipe\n");
2872
2873 if (scanner->pipe >= 0)
2874 {
2875 close (scanner->pipe);
2876 scanner->pipe = -1;
2877 }
2878
2879 return SANE_STATUS_EOF;
2880 }
2881
2882
2883
2884 /* ---------------------------- DO CANCEL ---------------------------------- */
2885
2886
2887 static SANE_Status
do_cancel(Pie_Scanner * scanner)2888 do_cancel (Pie_Scanner * scanner)
2889 {
2890 DBG (DBG_sane_proc, "do_cancel\n");
2891
2892 scanner->scanning = SANE_FALSE;
2893
2894 if (sanei_thread_is_valid (scanner->reader_pid))
2895 {
2896 DBG (DBG_sane_info, "killing reader_process\n");
2897 sanei_thread_kill (scanner->reader_pid);
2898 sanei_thread_waitpid (scanner->reader_pid, 0);
2899 sanei_thread_invalidate (scanner->reader_pid);
2900 DBG (DBG_sane_info, "reader_process killed\n");
2901 }
2902
2903 if (scanner->sfd >= 0)
2904 {
2905 pie_scan (scanner, 0);
2906
2907 pie_power_save (scanner, 15);
2908
2909 pie_give_scanner (scanner); /* reposition and release scanner */
2910
2911 DBG (DBG_sane_info, "closing scannerdevice filedescriptor\n");
2912 sanei_scsi_close (scanner->sfd);
2913 scanner->sfd = -1;
2914 }
2915
2916 return SANE_STATUS_CANCELLED;
2917 }
2918
2919
2920
2921 /* --------------------------------------- SANE INIT ---------------------------------- */
2922
2923
2924 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback __sane_unused__ authorize)2925 sane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize)
2926 {
2927 char dev_name[PATH_MAX];
2928 size_t len;
2929 FILE *fp;
2930
2931 DBG_INIT ();
2932
2933 DBG (DBG_sane_init, "sane_init() build %d\n", BUILD);
2934
2935 if (version_code)
2936 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
2937
2938 fp = sanei_config_open (PIE_CONFIG_FILE);
2939 if (!fp)
2940 {
2941 attach_scanner ("/dev/scanner", 0); /* no config-file: /dev/scanner */
2942 return SANE_STATUS_GOOD;
2943 }
2944
2945 while (sanei_config_read (dev_name, sizeof (dev_name), fp))
2946 {
2947 if (dev_name[0] == '#')
2948 {
2949 continue;
2950 } /* ignore line comments */
2951
2952 len = strlen (dev_name);
2953
2954 if (!len) /* ignore empty lines */
2955 {
2956 continue;
2957 }
2958
2959 sanei_config_attach_matching_devices (dev_name, attach_one);
2960 }
2961
2962 fclose (fp);
2963
2964 return SANE_STATUS_GOOD;
2965 }
2966
2967
2968 /* ----------------------------------------- SANE EXIT ---------------------------------- */
2969
2970
2971 void
sane_exit(void)2972 sane_exit (void)
2973 {
2974 Pie_Device *dev, *next;
2975 int i;
2976
2977 DBG (DBG_sane_init, "sane_exit()\n");
2978
2979 for (dev = first_dev; dev; dev = next)
2980 {
2981 next = dev->next;
2982 free (dev->devicename);
2983 free (dev->cal_info);
2984 i = 0;
2985 while (dev->halftone_list[i] != NULL)
2986 free (dev->halftone_list[i++]);
2987 i = 0;
2988 while (dev->speed_list[i] != NULL)
2989 free (dev->speed_list[i++]);
2990
2991 free (dev);
2992 }
2993
2994 first_dev = NULL;
2995
2996 if (devlist)
2997 {
2998 free (devlist);
2999 devlist = NULL;
3000 }
3001 }
3002
3003
3004 /* ------------------------------------------ SANE GET DEVICES --------------------------- */
3005
3006
3007 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool __sane_unused__ local_only)3008 sane_get_devices (const SANE_Device *** device_list, SANE_Bool __sane_unused__ local_only)
3009 {
3010 Pie_Device *dev;
3011 int i;
3012
3013 DBG (DBG_sane_init, "sane_get_devices\n");
3014
3015 i = 0;
3016 for (dev = first_dev; dev; dev = dev->next)
3017 i++;
3018
3019 if (devlist)
3020 {
3021 free (devlist);
3022 }
3023
3024 devlist = malloc ((i + 1) * sizeof (devlist[0]));
3025 if (!devlist)
3026 {
3027 return SANE_STATUS_NO_MEM;
3028 }
3029
3030 i = 0;
3031
3032 for (dev = first_dev; dev; dev = dev->next)
3033 {
3034 devlist[i++] = &dev->sane;
3035 }
3036
3037 devlist[i] = NULL;
3038
3039 *device_list = devlist;
3040
3041 return SANE_STATUS_GOOD;
3042 }
3043
3044
3045 /* --------------------------------------- SANE OPEN ---------------------------------- */
3046
3047 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)3048 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
3049 {
3050 Pie_Device *dev;
3051 SANE_Status status;
3052 Pie_Scanner *scanner;
3053 int i, j;
3054
3055 DBG (DBG_sane_init, "sane_open(%s)\n", devicename);
3056
3057 if (devicename[0]) /* search for devicename */
3058 {
3059 for (dev = first_dev; dev; dev = dev->next)
3060 {
3061 if (strcmp (dev->sane.name, devicename) == 0)
3062 {
3063 break;
3064 }
3065 }
3066
3067 if (!dev)
3068 {
3069 status = attach_scanner (devicename, &dev);
3070 if (status != SANE_STATUS_GOOD)
3071 {
3072 return status;
3073 }
3074 }
3075 }
3076 else
3077 {
3078 dev = first_dev; /* empty devicename -> use first device */
3079 }
3080
3081
3082 if (!dev)
3083 {
3084 return SANE_STATUS_INVAL;
3085 }
3086
3087 scanner = malloc (sizeof (*scanner));
3088 if (!scanner)
3089
3090 {
3091 return SANE_STATUS_NO_MEM;
3092 }
3093
3094 memset (scanner, 0, sizeof (*scanner));
3095
3096 scanner->device = dev;
3097 scanner->sfd = -1;
3098 scanner->pipe = -1;
3099
3100 scanner->gamma_length = 1 << (scanner->device->inquiry_gamma_bits);
3101
3102 DBG (DBG_sane_info, "Using %d bits for gamma input\n",
3103 scanner->device->inquiry_gamma_bits);
3104
3105 scanner->gamma_range.min = 0;
3106 scanner->gamma_range.max = scanner->gamma_length - 1;
3107 scanner->gamma_range.quant = 0;
3108
3109 scanner->gamma_table[0] =
3110 (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int));
3111 scanner->gamma_table[1] =
3112 (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int));
3113 scanner->gamma_table[2] =
3114 (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int));
3115 scanner->gamma_table[3] =
3116 (SANE_Int *) malloc (scanner->gamma_length * sizeof (SANE_Int));
3117
3118 for (i = 0; i < 4; ++i) /* gamma_table[0,1,2,3] */
3119 {
3120 for (j = 0; j < scanner->gamma_length; ++j)
3121 {
3122 scanner->gamma_table[i][j] = j;
3123 }
3124 }
3125
3126 init_options (scanner);
3127
3128 scanner->next = first_handle; /* insert newly opened handle into list of open handles: */
3129 first_handle = scanner;
3130
3131 *handle = scanner;
3132
3133 return SANE_STATUS_GOOD;
3134 }
3135
3136
3137 /* ------------------------------------ SANE CLOSE --------------------------------- */
3138
3139
3140 void
sane_close(SANE_Handle handle)3141 sane_close (SANE_Handle handle)
3142 {
3143 Pie_Scanner *prev, *scanner;
3144
3145 DBG (DBG_sane_init, "sane_close\n");
3146
3147 /* remove handle from list of open handles: */
3148 prev = 0;
3149
3150 for (scanner = first_handle; scanner; scanner = scanner->next)
3151 {
3152 if (scanner == handle)
3153 {
3154 break;
3155 }
3156
3157 prev = scanner;
3158 }
3159
3160 if (!scanner)
3161 {
3162 DBG (DBG_error, "close: invalid handle %p\n", handle);
3163 return; /* oops, not a handle we know about */
3164 }
3165
3166 if (scanner->scanning) /* stop scan if still scanning */
3167 {
3168 do_cancel (handle);
3169 }
3170
3171 if (prev)
3172 {
3173 prev->next = scanner->next;
3174 }
3175 else
3176 {
3177 first_handle = scanner->next;
3178 }
3179
3180 free (scanner->gamma_table[0]); /* free custom gamma tables */
3181 free (scanner->gamma_table[1]);
3182 free (scanner->gamma_table[2]);
3183 free (scanner->gamma_table[3]);
3184 free (scanner->val[OPT_MODE].s);
3185 free (scanner->val[OPT_SPEED].s);
3186 free (scanner->val[OPT_HALFTONE_PATTERN].s);
3187
3188 scanner->bufsize = 0;
3189
3190 free (scanner); /* free scanner */
3191 }
3192
3193
3194 /* ---------------------------------- SANE GET OPTION DESCRIPTOR ----------------- */
3195
3196 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)3197 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
3198 {
3199 Pie_Scanner *scanner = handle;
3200
3201 DBG (DBG_sane_option, "sane_get_option_descriptor %d\n", option);
3202
3203 if ((unsigned) option >= NUM_OPTIONS)
3204 {
3205 return 0;
3206 }
3207
3208 return scanner->opt + option;
3209 }
3210
3211
3212 /* ---------------------------------- SANE CONTROL OPTION ------------------------ */
3213
3214
3215 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)3216 sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
3217 void *val, SANE_Int * info)
3218 {
3219 Pie_Scanner *scanner = handle;
3220 SANE_Status status;
3221 SANE_Word cap;
3222 SANE_String_Const name;
3223
3224 if (info)
3225 {
3226 *info = 0;
3227 }
3228
3229 if (scanner->scanning)
3230 {
3231 return SANE_STATUS_DEVICE_BUSY;
3232 }
3233
3234 if ((unsigned) option >= NUM_OPTIONS)
3235 {
3236 return SANE_STATUS_INVAL;
3237 }
3238
3239 cap = scanner->opt[option].cap;
3240 if (!SANE_OPTION_IS_ACTIVE (cap))
3241 {
3242 return SANE_STATUS_INVAL;
3243 }
3244
3245 name = scanner->opt[option].name;
3246 if (!name)
3247 {
3248 name = "(no name)";
3249 }
3250
3251 if (action == SANE_ACTION_GET_VALUE)
3252 {
3253
3254 DBG (DBG_sane_option, "get %s [#%d]\n", name, option);
3255
3256 switch (option)
3257 {
3258 /* word options: */
3259 case OPT_NUM_OPTS:
3260 case OPT_RESOLUTION:
3261 case OPT_TL_X:
3262 case OPT_TL_Y:
3263 case OPT_BR_X:
3264 case OPT_BR_Y:
3265 case OPT_PREVIEW:
3266 case OPT_THRESHOLD:
3267 *(SANE_Word *) val = scanner->val[option].w;
3268 return SANE_STATUS_GOOD;
3269
3270 /* word-array options: */
3271 case OPT_GAMMA_VECTOR:
3272 case OPT_GAMMA_VECTOR_R:
3273 case OPT_GAMMA_VECTOR_G:
3274 case OPT_GAMMA_VECTOR_B:
3275 memcpy (val, scanner->val[option].wa, scanner->opt[option].size);
3276 return SANE_STATUS_GOOD;
3277
3278 #if 0
3279 /* string options: */
3280 case OPT_SOURCE:
3281 #endif
3282 case OPT_MODE:
3283 case OPT_HALFTONE_PATTERN:
3284 case OPT_SPEED:
3285 strcpy (val, scanner->val[option].s);
3286 return SANE_STATUS_GOOD;
3287 }
3288 }
3289 else if (action == SANE_ACTION_SET_VALUE)
3290 {
3291 switch (scanner->opt[option].type)
3292 {
3293 case SANE_TYPE_INT:
3294 DBG (DBG_sane_option, "set %s [#%d] to %d\n", name, option,
3295 *(SANE_Word *) val);
3296 break;
3297
3298 case SANE_TYPE_FIXED:
3299 DBG (DBG_sane_option, "set %s [#%d] to %f\n", name, option,
3300 SANE_UNFIX (*(SANE_Word *) val));
3301 break;
3302
3303 case SANE_TYPE_STRING:
3304 DBG (DBG_sane_option, "set %s [#%d] to %s\n", name, option,
3305 (char *) val);
3306 break;
3307
3308 case SANE_TYPE_BOOL:
3309 DBG (DBG_sane_option, "set %s [#%d] to %d\n", name, option,
3310 *(SANE_Word *) val);
3311 break;
3312
3313 default:
3314 DBG (DBG_sane_option, "set %s [#%d]\n", name, option);
3315 }
3316
3317 if (!SANE_OPTION_IS_SETTABLE (cap))
3318 {
3319 return SANE_STATUS_INVAL;
3320 }
3321
3322 status = sanei_constrain_value (scanner->opt + option, val, info);
3323 if (status != SANE_STATUS_GOOD)
3324 {
3325 return status;
3326 }
3327
3328 switch (option)
3329 {
3330 /* (mostly) side-effect-free word options: */
3331 case OPT_RESOLUTION:
3332 case OPT_TL_X:
3333 case OPT_TL_Y:
3334 case OPT_BR_X:
3335 case OPT_BR_Y:
3336 if (info)
3337 {
3338 *info |= SANE_INFO_RELOAD_PARAMS;
3339 }
3340 /* fall through */
3341 case OPT_NUM_OPTS:
3342 case OPT_PREVIEW:
3343 case OPT_THRESHOLD:
3344 scanner->val[option].w = *(SANE_Word *) val;
3345 return SANE_STATUS_GOOD;
3346
3347 /* side-effect-free word-array options: */
3348 case OPT_GAMMA_VECTOR:
3349 case OPT_GAMMA_VECTOR_R:
3350 case OPT_GAMMA_VECTOR_G:
3351 case OPT_GAMMA_VECTOR_B:
3352 memcpy (scanner->val[option].wa, val, scanner->opt[option].size);
3353 return SANE_STATUS_GOOD;
3354
3355 /* options with side-effects: */
3356
3357 case OPT_MODE:
3358 {
3359 int halftoning;
3360
3361 if (scanner->val[option].s)
3362 {
3363 free (scanner->val[option].s);
3364 }
3365
3366 scanner->val[option].s = (SANE_Char *) strdup (val);
3367
3368 if (info)
3369 {
3370 *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
3371 }
3372
3373 scanner->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
3374
3375
3376 scanner->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
3377 scanner->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
3378 scanner->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
3379 scanner->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
3380 scanner->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
3381
3382 halftoning = (strcmp (val, HALFTONE_STR) == 0);
3383
3384 if (halftoning || strcmp (val, LINEART_STR) == 0)
3385 { /* one bit modes */
3386 if (halftoning)
3387 { /* halftoning modes */
3388 scanner->opt[OPT_HALFTONE_PATTERN].cap &=
3389 ~SANE_CAP_INACTIVE;
3390 }
3391 else
3392 { /* lineart modes */
3393 }
3394 scanner->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
3395 }
3396 else
3397 { /* multi-bit modes(gray or color) */
3398 }
3399
3400 if ((strcmp (val, LINEART_STR) == 0)
3401 || (strcmp (val, HALFTONE_STR) == 0)
3402 || (strcmp (val, GRAY_STR) == 0))
3403 {
3404 scanner->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
3405 }
3406 else if (strcmp (val, COLOR_STR) == 0)
3407 {
3408 /* scanner->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; */
3409 scanner->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
3410 scanner->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
3411 scanner->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
3412 }
3413 return SANE_STATUS_GOOD;
3414 }
3415
3416 case OPT_SPEED:
3417 case OPT_HALFTONE_PATTERN:
3418 {
3419 if (scanner->val[option].s)
3420 {
3421 free (scanner->val[option].s);
3422 }
3423
3424 scanner->val[option].s = (SANE_Char *) strdup (val);
3425
3426 return SANE_STATUS_GOOD;
3427 }
3428 }
3429 } /* else */
3430 return SANE_STATUS_INVAL;
3431 }
3432
3433
3434 /* ------------------------------------ SANE GET PARAMETERS ------------------------ */
3435
3436
3437 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)3438 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
3439 {
3440 Pie_Scanner *scanner = handle;
3441 const char *mode;
3442
3443 DBG (DBG_sane_info, "sane_get_parameters\n");
3444
3445 if (!scanner->scanning)
3446 { /* not scanning, so lets use recent values */
3447 double width, length, x_dpi, y_dpi;
3448
3449 memset (&scanner->params, 0, sizeof (scanner->params));
3450
3451 width =
3452 SANE_UNFIX (scanner->val[OPT_BR_X].w - scanner->val[OPT_TL_X].w);
3453 length =
3454 SANE_UNFIX (scanner->val[OPT_BR_Y].w - scanner->val[OPT_TL_Y].w);
3455 x_dpi = SANE_UNFIX (scanner->val[OPT_RESOLUTION].w);
3456 y_dpi = x_dpi;
3457
3458 #if 0
3459 if ((scanner->val[OPT_RESOLUTION_BIND].w == SANE_TRUE)
3460 || (scanner->val[OPT_PREVIEW].w == SANE_TRUE))
3461 {
3462 y_dpi = x_dpi;
3463 }
3464 #endif
3465 if (x_dpi > 0.0 && y_dpi > 0.0 && width > 0.0 && length > 0.0)
3466 {
3467 double x_dots_per_mm = x_dpi / MM_PER_INCH;
3468 double y_dots_per_mm = y_dpi / MM_PER_INCH;
3469
3470 scanner->params.pixels_per_line = width * x_dots_per_mm;
3471 scanner->params.lines = length * y_dots_per_mm;
3472 }
3473 }
3474
3475 mode = scanner->val[OPT_MODE].s;
3476
3477 if (strcmp (mode, LINEART_STR) == 0 || strcmp (mode, HALFTONE_STR) == 0)
3478 {
3479 scanner->params.format = SANE_FRAME_GRAY;
3480 scanner->params.bytes_per_line =
3481 (scanner->params.pixels_per_line + 7) / 8;
3482 scanner->params.depth = 1;
3483 }
3484 else if (strcmp (mode, GRAY_STR) == 0)
3485 {
3486 scanner->params.format = SANE_FRAME_GRAY;
3487 scanner->params.bytes_per_line = scanner->params.pixels_per_line;
3488 scanner->params.depth = 8;
3489 }
3490 else /* RGB */
3491 {
3492 scanner->params.format = SANE_FRAME_RGB;
3493 scanner->params.bytes_per_line = 3 * scanner->params.pixels_per_line;
3494 scanner->params.depth = 8;
3495 }
3496
3497 scanner->params.last_frame = (scanner->params.format != SANE_FRAME_RED
3498 && scanner->params.format !=
3499 SANE_FRAME_GREEN);
3500
3501 if (params)
3502 {
3503 *params = scanner->params;
3504 }
3505
3506 return SANE_STATUS_GOOD;
3507 }
3508
3509
3510 /* ----------------------------------------- SANE START --------------------------------- */
3511
3512
3513 SANE_Status
sane_start(SANE_Handle handle)3514 sane_start (SANE_Handle handle)
3515 {
3516 Pie_Scanner *scanner = handle;
3517 int fds[2];
3518 const char *mode;
3519 int status;
3520
3521 DBG (DBG_sane_init, "sane_start\n");
3522
3523 /* Check for inconsistencies */
3524
3525 if (scanner->val[OPT_TL_X].w > scanner->val[OPT_BR_X].w)
3526 {
3527 DBG (0, "sane_start: %s (%.1f mm) is bigger than %s (%.1f mm) "
3528 "-- aborting\n",
3529 scanner->opt[OPT_TL_X].title, SANE_UNFIX (scanner->val[OPT_TL_X].w),
3530 scanner->opt[OPT_BR_X].title, SANE_UNFIX (scanner->val[OPT_BR_X].w));
3531 return SANE_STATUS_INVAL;
3532 }
3533 if (scanner->val[OPT_TL_Y].w > scanner->val[OPT_BR_Y].w)
3534 {
3535 DBG (0, "sane_start: %s (%.1f mm) is bigger than %s (%.1f mm) "
3536 "-- aborting\n",
3537 scanner->opt[OPT_TL_Y].title, SANE_UNFIX (scanner->val[OPT_TL_Y].w),
3538 scanner->opt[OPT_BR_Y].title, SANE_UNFIX (scanner->val[OPT_BR_Y].w));
3539 return SANE_STATUS_INVAL;
3540 }
3541
3542 mode = scanner->val[OPT_MODE].s;
3543
3544 if (scanner->sfd < 0) /* first call, don`t run this routine again on multi frame or multi image scan */
3545 {
3546 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
3547 int scsi_bufsize = 131072; /* 128KB */
3548
3549 if (sanei_scsi_open_extended
3550 (scanner->device->sane.name, &(scanner->sfd), sense_handler,
3551 scanner->device, &scsi_bufsize) != 0)
3552
3553 {
3554 DBG (DBG_error, "sane_start: open failed\n");
3555 return SANE_STATUS_INVAL;
3556 }
3557
3558 if (scsi_bufsize < 32768) /* < 32KB */
3559 {
3560 DBG (DBG_error,
3561 "sane_start: sanei_scsi_open_extended returned too small scsi buffer (%d)\n",
3562 scsi_bufsize);
3563 sanei_scsi_close ((scanner->sfd));
3564 return SANE_STATUS_NO_MEM;
3565 }
3566 DBG (DBG_info,
3567 "sane_start: sanei_scsi_open_extended returned scsi buffer size = %d\n",
3568 scsi_bufsize);
3569
3570
3571 scanner->bufsize = scsi_bufsize;
3572 #else
3573 if (sanei_scsi_open
3574 (scanner->device->sane.name, &(scanner->sfd), sense_handler,
3575 scanner->device) != SANE_STATUS_GOOD)
3576 {
3577 DBG (DBG_error, "sane_start: open of %s failed:\n",
3578 scanner->device->sane.name);
3579 return SANE_STATUS_INVAL;
3580 }
3581
3582 /* there is no need to reallocate the buffer because the size is fixed */
3583 #endif
3584
3585 #if 0
3586 if (pie_check_values (scanner->device) != 0)
3587 {
3588 DBG (DBG_error, "ERROR: invalid scan-values\n");
3589 scanner->scanning = SANE_FALSE;
3590 pie_give_scanner (scanner); /* reposition and release scanner */
3591 sanei_scsi_close (scanner->sfd);
3592 scanner->sfd = -1;
3593 return SANE_STATUS_INVAL;
3594 }
3595 #endif
3596 #if 0
3597 scanner->params.bytes_per_line = scanner->device->row_len;
3598 scanner->params.pixels_per_line = scanner->device->width_in_pixels;
3599 scanner->params.lines = scanner->device->length_in_pixels;
3600
3601 sane_get_parameters (scanner, 0);
3602
3603 DBG (DBG_sane_info, "x_resolution (dpi) = %u\n",
3604 scanner->device->x_resolution);
3605 DBG (DBG_sane_info, "y_resolution (dpi) = %u\n",
3606 scanner->device->y_resolution);
3607 DBG (DBG_sane_info, "x_coordinate_base (dpi) = %u\n",
3608 scanner->device->x_coordinate_base);
3609 DBG (DBG_sane_info, "y_coordinate_base (dpi) = %u\n",
3610 scanner->device->y_coordinate_base);
3611 DBG (DBG_sane_info, "upper_left_x (xbase) = %d\n",
3612 scanner->device->upper_left_x);
3613 DBG (DBG_sane_info, "upper_left_y (ybase) = %d\n",
3614 scanner->device->upper_left_y);
3615 DBG (DBG_sane_info, "scanwidth (xbase) = %u\n",
3616 scanner->device->scanwidth);
3617 DBG (DBG_sane_info, "scanlength (ybase) = %u\n",
3618 scanner->device->scanlength);
3619 DBG (DBG_sane_info, "width in pixels = %u\n",
3620 scanner->device->width_in_pixels);
3621 DBG (DBG_sane_info, "length in pixels = %u\n",
3622 scanner->device->length_in_pixels);
3623 DBG (DBG_sane_info, "bits per pixel/color = %u\n",
3624 scanner->device->bits_per_pixel);
3625 DBG (DBG_sane_info, "bytes per line = %d\n",
3626 scanner->params.bytes_per_line);
3627 DBG (DBG_sane_info, "pixels_per_line = %d\n",
3628 scanner->params.pixels_per_line);
3629 DBG (DBG_sane_info, "lines = %d\n",
3630 scanner->params.lines);
3631 #endif
3632
3633 /* grab scanner */
3634 if (pie_grab_scanner (scanner))
3635 {
3636 sanei_scsi_close (scanner->sfd);
3637 scanner->sfd = -1;
3638 DBG (DBG_warning,
3639 "WARNING: unable to reserve scanner: device busy\n");
3640 return SANE_STATUS_DEVICE_BUSY;
3641 }
3642
3643 scanner->scanning = SANE_TRUE;
3644
3645 pie_power_save (scanner, 0);
3646 } /* ------------ end of first call -------------- */
3647
3648
3649 if (strcmp (mode, LINEART_STR) == 0)
3650 {
3651 scanner->colormode = LINEART;
3652 }
3653 else if (strcmp (mode, HALFTONE_STR) == 0)
3654 {
3655 scanner->colormode = HALFTONE;
3656 }
3657 else if (strcmp (mode, GRAY_STR) == 0)
3658 {
3659 scanner->colormode = GRAYSCALE;
3660 }
3661 else if (strcmp (mode, COLOR_STR) == 0)
3662 {
3663 scanner->colormode = RGB;
3664 }
3665
3666 /* get and set geometric values for scanning */
3667 scanner->resolution = SANE_UNFIX (scanner->val[OPT_RESOLUTION].w);
3668
3669 pie_set_window (scanner);
3670 pie_send_exposure (scanner);
3671 pie_mode_select (scanner);
3672 pie_send_highlight_shadow (scanner);
3673
3674 pie_scan (scanner, 1);
3675
3676 status = pie_do_cal (scanner);
3677 if (status)
3678 return status;
3679
3680 /* send gammacurves */
3681
3682 pie_dwnld_gamma (scanner);
3683
3684 pie_get_params (scanner);
3685
3686 if (pipe (fds) < 0) /* create a pipe, fds[0]=read-fd, fds[1]=write-fd */
3687 {
3688 DBG (DBG_error, "ERROR: could not create pipe\n");
3689 scanner->scanning = SANE_FALSE;
3690 pie_scan (scanner, 0);
3691 pie_give_scanner (scanner); /* reposition and release scanner */
3692 sanei_scsi_close (scanner->sfd);
3693 scanner->sfd = -1;
3694 return SANE_STATUS_IO_ERROR;
3695 }
3696
3697 scanner->pipe = fds[0];
3698 scanner->reader_fds = fds[1];
3699 scanner->reader_pid = sanei_thread_begin( reader_process, (void*)scanner );
3700
3701 if (!sanei_thread_is_valid (scanner->reader_pid))
3702 {
3703 DBG (1, "sane_start: sanei_thread_begin failed (%s)\n",
3704 strerror (errno));
3705 return SANE_STATUS_NO_MEM;
3706 }
3707
3708 if (sanei_thread_is_forked ())
3709 {
3710 close (scanner->reader_fds);
3711 scanner->reader_fds = -1;
3712 }
3713
3714 return SANE_STATUS_GOOD;
3715 }
3716
3717
3718 /* -------------------------------------- SANE READ ---------------------------------- */
3719
3720
3721 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)3722 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
3723 SANE_Int * len)
3724 {
3725 Pie_Scanner *scanner = handle;
3726 ssize_t nread;
3727
3728 *len = 0;
3729
3730 nread = read (scanner->pipe, buf, max_len);
3731 DBG (DBG_sane_info, "sane_read: read %ld bytes\n", (long) nread);
3732
3733 if (!(scanner->scanning)) /* OOPS, not scanning */
3734 {
3735 return do_cancel (scanner);
3736 }
3737
3738 if (nread < 0)
3739 {
3740 if (errno == EAGAIN)
3741 {
3742 DBG (DBG_sane_info, "sane_read: EAGAIN\n");
3743 return SANE_STATUS_GOOD;
3744 }
3745 else
3746 {
3747 do_cancel (scanner); /* we had an error, stop scanner */
3748 return SANE_STATUS_IO_ERROR;
3749 }
3750 }
3751
3752 *len = nread;
3753
3754 if (nread == 0) /* EOF */
3755 {
3756 do_cancel (scanner);
3757
3758 return close_pipe (scanner); /* close pipe */
3759 }
3760
3761 return SANE_STATUS_GOOD;
3762 }
3763
3764
3765 /* ------------------------------------- SANE CANCEL -------------------------------- */
3766
3767
3768 void
sane_cancel(SANE_Handle handle)3769 sane_cancel (SANE_Handle handle)
3770 {
3771 Pie_Scanner *scanner = handle;
3772
3773 DBG (DBG_sane_init, "sane_cancel\n");
3774
3775 if (scanner->scanning)
3776 {
3777 do_cancel (scanner);
3778 }
3779 }
3780
3781
3782 /* -------------------------------------- SANE SET IO MODE --------------------------- */
3783
3784
3785 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)3786 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
3787 {
3788 Pie_Scanner *scanner = handle;
3789
3790 DBG (DBG_sane_init, "sane_set_io_mode: non_blocking=%d\n", non_blocking);
3791
3792 if (!scanner->scanning)
3793 {
3794 return SANE_STATUS_INVAL;
3795 }
3796
3797 if (fcntl (scanner->pipe, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0)
3798 {
3799 return SANE_STATUS_IO_ERROR;
3800 }
3801
3802 return SANE_STATUS_GOOD;
3803 }
3804
3805
3806 /* --------------------------------------- SANE GET SELECT FD ------------------------- */
3807
3808
3809 SANE_Status
sane_get_select_fd(SANE_Handle handle,SANE_Int * fd)3810 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
3811 {
3812 Pie_Scanner *scanner = handle;
3813
3814 DBG (DBG_sane_init, "sane_get_select_fd\n");
3815
3816 if (!scanner->scanning)
3817 {
3818 return SANE_STATUS_INVAL;
3819 }
3820 *fd = scanner->pipe;
3821
3822 return SANE_STATUS_GOOD;
3823 }
3824