1 /* sane - Scanner Access Now Easy.
2
3 Copyright (C) 2000-2001 Kazuya Fukuda, based on sharp.c, which is
4 based on canon.c.
5
6 This file is part of the SANE package.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <https://www.gnu.org/licenses/>.
20
21 As a special exception, the authors of SANE give permission for
22 additional uses of the libraries contained in this release of SANE.
23
24 The exception is that, if you link a SANE library with other files
25 to produce an executable, this does not by itself cause the
26 resulting executable to be covered by the GNU General Public
27 License. Your use of that executable is in no way restricted on
28 account of linking the SANE library code into it.
29
30 This exception does not, however, invalidate any other reasons why
31 the executable file might be covered by the GNU General Public
32 License.
33
34 If you submit changes to SANE to the maintainers to be included in
35 a subsequent release, you agree by submitting the changes that
36 those changes may be distributed with this exception intact.
37
38 If you write modifications of your own for SANE, it is your choice
39 whether to permit this exception to apply to your modifications.
40 If you do not wish that, delete this exception notice.
41
42 This file implements a SANE backend for NEC flatbed scanners. */
43
44 /*
45 Version 0.12
46 - Remove references to sharp backend (grep for "JX").
47 - Check for HAVE_SYS_SHM_H before including sys/shm.h and
48 disable shared memory support if necessary.
49 - free devlist allocated in sane_get_devices() in sane_exit()
50 - resolution setting bug fixed(PC-IN500/4C 10dpi step)
51 - remove resolution list
52 Version 0.11
53 - get_data_buffer_status is not called in sane_get_parameter and
54 sane_read_direct, sane_read_shuffled.
55 - change some #include <> to ""
56 Version 0.10
57 - First release!
58 - supported scanner
59 PC-IN500/4C available
60 MultiReder 300U/300S series not available
61 MultiReder 600U/600S series not available
62 MultiReader PetiScan series not available
63 */
64 #include "../include/sane/config.h"
65
66 #include <limits.h>
67 #include <stdlib.h>
68 #include <stdarg.h>
69 #include <string.h>
70 #include <unistd.h>
71 #include <errno.h>
72 #include <math.h>
73
74 #include "../include/sane/sane.h"
75 #include "../include/sane/saneopts.h"
76 #include "../include/sane/sanei_scsi.h"
77
78 /* QUEUEDEBUG should be undefined unless you want to play
79 with the sanei_scsi.c under Linux and/or with the Linux's SG driver,
80 or your suspect problems with command queueing
81 */
82 #define QUEUEDEBUG
83 /*#define DEBUG*/
84 #ifdef DEBUG
85 #include <unistd.h>
86 #include <sys/time.h>
87 #endif
88
89 /* USE_FORK: fork a special reader process
90 disable shared memory support.
91 */
92 #if 0
93 #ifdef HAVE_SYS_SHM_H
94 #define USE_FORK
95 #endif
96 #endif
97
98 #ifdef USE_FORK
99 #include <signal.h>
100 #include <fcntl.h>
101 #include <sys/types.h>
102 #include <sys/wait.h>
103
104 #include <sys/ipc.h>
105 #include <sys/shm.h>
106
107 #endif /* USE_FORK */
108
109 #ifndef USE_CUSTOM_GAMMA
110 #define USE_CUSTOM_GAMMA
111 #endif
112 #ifndef USE_COLOR_THRESHOLD
113 #define USE_COLOR_THRESHOLD
114 #endif
115 /* enable a short list of some standard resolutions. XSane provides
116 its own resolution list; therefore its is generally not reasonable
117 to enable this list, if you mainly using XSane. But it might be handy
118 if you are working with xscanimage
119 */
120 /* #define USE_RESOLUTION_LIST */
121
122 #define BACKEND_NAME nec
123 #include "../include/sane/sanei_backend.h"
124
125 #ifndef PATH_MAX
126 #define PATH_MAX 1024
127 #endif
128
129 #define DEFAULT_MUD_1200 1200
130
131 #define PIX_TO_MM(x, mud) ((x) * 25.4 / mud)
132 #define MM_TO_PIX(x, mud) ((x) * mud / 25.4)
133
134 #include "../include/sane/sanei_config.h"
135 #define NEC_CONFIG_FILE "nec.conf"
136
137 #include "nec.h"
138
139 static int num_devices = 0;
140 static NEC_Device *first_dev = NULL;
141 static NEC_Scanner *first_handle = NULL;
142 static const SANE_Device **devlist = 0;
143
144 typedef enum
145 {
146 MODES_LINEART = 0,
147 MODES_GRAY,
148 MODES_COLOR,
149 MODES_LINEART_COLOR
150 }
151 Modes;
152
153 #define M_LINEART SANE_VALUE_SCAN_MODE_LINEART
154 #define M_GRAY SANE_VALUE_SCAN_MODE_GRAY
155 #define M_LINEART_COLOR "Lineart Color"
156 #define M_COLOR SANE_VALUE_SCAN_MODE_COLOR
157 static const SANE_String_Const mode_list[] =
158 {
159 #if 0
160 M_LINEART, M_GRAY, M_LINEART_COLOR, M_COLOR,
161 #endif
162 M_LINEART, M_GRAY, M_COLOR,
163 0
164 };
165
166 #define M_BILEVEL "none"
167 #define M_BAYER "Dither Bayer"
168 #define M_SPIRAL "Dither Spiral"
169 #define M_DISPERSED "Dither Dispersed"
170 #define M_ERRDIFFUSION "Error Diffusion"
171
172 #define M_DITHER1 "Dither 1"
173 #define M_DITHER2 "Dither 2"
174 #define M_DITHER3 "Dither 3"
175 #define M_DITHERUSER "User defined"
176
177 static const SANE_String_Const halftone_list[] =
178 {
179 M_BILEVEL, M_DITHER1, M_DITHER2, M_DITHER3,
180 0
181 };
182
183 #define LIGHT_GREEN "green"
184 #define LIGHT_RED "red"
185 #define LIGHT_BLUE "blue"
186 #define LIGHT_NONE "none"
187 #define LIGHT_WHITE "white"
188
189 static const SANE_String_Const light_color_list[] =
190 {
191 LIGHT_GREEN, LIGHT_RED, LIGHT_BLUE, LIGHT_NONE,
192 0
193 };
194
195 /* possible values for ADF/FSU selection */
196 static SANE_String use_adf = "Automatic Document Feeder";
197 static SANE_String use_fsu = "Transparency Adapter";
198 static SANE_String use_simple = "Flatbed";
199
200 #define HAVE_FSU 1
201 #define HAVE_ADF 2
202
203 /* The follow #defines are used in NEC_Scanner.adf_fsu_mode
204 and as indexes for the arrays x_ranges, y_ranges in NEC_Device
205 */
206 #define SCAN_SIMPLE 0
207 #define SCAN_WITH_FSU 1
208 #define SCAN_WITH_ADF 2
209
210 #define LOAD_PAPER 1
211 #define UNLOAD_PAPER 0
212
213 #define PAPER_MAX 10
214 #define W_LETTER "11\"x17\""
215 #define INVOICE "8.5\"x5.5\""
216 static const SANE_String_Const paper_list_pcinxxx[] =
217 {
218 "A3", "A4", "A5", "A6", "B4", "B5",
219 W_LETTER, "Legal", "Letter", INVOICE,
220 0
221 };
222
223 static const SANE_String_Const paper_list_pcin500[] =
224 {
225 "A4", "A5", "A6", "B5",
226 0
227 };
228
229
230 #define CRT1 "CRT1"
231 #define CRT2 "CRT2"
232 #define PRINTER1 "PRINTER1"
233 #define PRINTER2 "PRINTER2"
234 #define NONE "NONE"
235 /* #define CUSTOM "CUSTOM" */
236 static const SANE_String_Const gamma_list[] =
237 {
238 CRT1, CRT2, PRINTER1, PRINTER2, NONE,
239 0
240 };
241
242 #if 0
243 #define SPEED_NORMAL "Normal"
244 #define SPEED_FAST "Fast"
245 static const SANE_String_Const speed_list[] =
246 {
247 SPEED_NORMAL, SPEED_FAST,
248 0
249 };
250 #endif
251
252 #ifdef USE_RESOLUTION_LIST
253 #define RESOLUTION_MAX_PCINXXX 8
254 static const SANE_String_Const resolution_list_pcinxxx[] =
255 {
256 "50", "75", "100", "150", "200", "300", "400", "600", "Select",
257 0
258 };
259
260 #define RESOLUTION_MAX_PCIN500 8
261 static const SANE_String_Const resolution_list_pcin500[] =
262 {
263 "50", "75", "100", "150", "200", "300", "400", "480", "Select",
264 0
265 };
266 #endif
267
268 #define EDGE_NONE "None"
269 #define EDGE_MIDDLE "Middle"
270 #define EDGE_STRONG "Strong"
271 #define EDGE_BLUR "Blur"
272 static const SANE_String_Const edge_emphasis_list[] =
273 {
274 EDGE_NONE, EDGE_MIDDLE, EDGE_STRONG, EDGE_BLUR,
275 0
276 };
277
278 #ifdef USE_CUSTOM_GAMMA
279 static const SANE_Range u8_range =
280 {
281 0, /* minimum */
282 255, /* maximum */
283 0 /* quantization */
284 };
285 #endif
286
287 static SANE_Status
sense_handler(int fd, u_char *sense_buffer, void *ss)288 sense_handler(int fd, u_char *sense_buffer, void *ss)
289 {
290 int sense_key;
291 NEC_Sense_Data *sdat = (NEC_Sense_Data *) ss;
292
293 (void) fd; /* silence compilation warnings */
294
295 #define add_sense_code sense_buffer[12]
296 #define add_sense_qual sense_buffer[13]
297
298 memcpy(sdat->sb, sense_buffer, 16);
299
300 DBG(10, "sense code: %02x %02x %02x %02x %02x %02x %02x %02x "
301 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
302 sense_buffer[0], sense_buffer[1], sense_buffer[2], sense_buffer[3],
303 sense_buffer[4], sense_buffer[5], sense_buffer[6], sense_buffer[7],
304 sense_buffer[8], sense_buffer[9], sense_buffer[10], sense_buffer[11],
305 sense_buffer[12], sense_buffer[13], sense_buffer[14], sense_buffer[15]);
306
307 sense_key = sense_buffer[1] & 0x0F;
308 /* do we have additional information ? */
309 if (sense_buffer[7] >= 5)
310 {
311 if (sdat->model == PCIN500)
312 {
313 switch (sense_key)
314 {
315 case 0x02: /* not ready */
316 switch (add_sense_code)
317 {
318 case 0x80:
319 switch (add_sense_qual & 0xf0)
320 {
321 case 0x10:
322 DBG(1, "Scanner not ready: memory error\n");
323 return SANE_STATUS_IO_ERROR;
324 case 0x20:
325 DBG(1, "Scanner not ready: hardware error\n");
326 return SANE_STATUS_IO_ERROR;
327 case 0x30:
328 DBG(1, "Scanner not ready: optical error\n");
329 return SANE_STATUS_IO_ERROR;
330 case 0x40:
331 DBG(1, "Scanner not ready: optical error\n");
332 return SANE_STATUS_IO_ERROR;
333 case 0x50:
334 DBG(1, "Scanner not ready: marker error\n");
335 return SANE_STATUS_IO_ERROR;
336 case 0x60:
337 DBG(1, "Scanner not ready: mechanical error\n");
338 return SANE_STATUS_IO_ERROR;
339 case 0x70:
340 DBG(1, "Scanner not ready: hardware error\n");
341 return SANE_STATUS_IO_ERROR;
342 case 0x80:
343 DBG(1, "Scanner not ready: hardware error\n");
344 return SANE_STATUS_IO_ERROR;
345 case 0x90:
346 default:
347 DBG(5, "Scanner not ready: undocumented reason\n");
348 return SANE_STATUS_IO_ERROR;
349 }
350 default:
351 DBG(5, "Scanner not ready: unknown sense code\n");
352 return SANE_STATUS_IO_ERROR;
353 }
354 case 0x03: /* medium error */
355 DBG(5, "medium error: undocumented reason\n");
356 return SANE_STATUS_IO_ERROR;
357 case 0x04: /* hardware error */
358 DBG(1, "general hardware error\n");
359 return SANE_STATUS_IO_ERROR;
360 case 0x05: /* illegal request */
361 DBG(10, "error: illegal request\n");
362 return SANE_STATUS_IO_ERROR;
363 case 0x06: /* unit attention */
364 DBG(5, "unit attention: exact reason not documented\n");
365 return SANE_STATUS_IO_ERROR;
366 case 0x0B: /* data remains */
367 DBG(5, "error: aborted command\n");
368 return SANE_STATUS_IO_ERROR;
369 default:
370 DBG(5, "error: sense code not documented\n");
371 return SANE_STATUS_IO_ERROR;
372 }
373 }
374 }
375 return SANE_STATUS_IO_ERROR;
376 }
377
378 static SANE_Status
test_unit_ready(int fd)379 test_unit_ready (int fd)
380 {
381 static u_char cmd[] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
382 SANE_Status status;
383 DBG (11, "<< test_unit_ready ");
384
385 status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
386
387 DBG (11, ">>\n");
388 return (status);
389 }
390
391 #if 0
392 static SANE_Status
393 request_sense (int fd, void *sense_buf, size_t *sense_size)
394 {
395 static u_char cmd[] = {REQUEST_SENSE, 0, 0, 0, SENSE_LEN, 0};
396 SANE_Status status;
397 DBG (11, "<< request_sense ");
398
399 status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), sense_buf, sense_size);
400
401 DBG (11, ">>\n");
402 return (status);
403 }
404 #endif
405
406 static SANE_Status
inquiry(int fd, void *inq_buf, size_t *inq_size)407 inquiry (int fd, void *inq_buf, size_t *inq_size)
408 {
409 static u_char cmd[] = {INQUIRY, 0, 0, 0, INQUIRY_LEN, 0};
410 SANE_Status status;
411 DBG (11, "<< inquiry ");
412
413 status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), inq_buf, inq_size);
414
415 DBG (11, ">>\n");
416 return (status);
417 }
418
419 static SANE_Status
mode_select_mud(int fd, int mud)420 mode_select_mud (int fd, int mud)
421 {
422 static u_char cmd[6 + MODEPARAM_LEN] =
423 {MODE_SELECT6, 0x10, 0, 0, MODEPARAM_LEN, 0};
424 mode_select_param *mp;
425 SANE_Status status;
426 DBG (11, "<< mode_select_mud ");
427
428 mp = (mode_select_param *)(cmd + 6);
429 memset (mp, 0, MODEPARAM_LEN);
430 mp->mode_param_header1 = 11;
431 mp->page_code = 3;
432 mp->page_length = 6;
433 mp->mud[0] = mud >> 8;
434 mp->mud[1] = mud & 0xFF;
435
436 status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
437
438 DBG (11, ">>\n");
439 return (status);
440 }
441
442 #if 0
443 static SANE_Status
444 mode_select_adf_fsu (int fd, int mode)
445 {
446 static u_char cmd[6 + MODE_SUBDEV_LEN] =
447 {MODE_SELECT6, 0x10, 0, 0, MODE_SUBDEV_LEN, 0};
448 mode_select_subdevice *mp;
449 SANE_Status status;
450 DBG (11, "<< mode_select_adf_fsu ");
451
452 mp = (mode_select_subdevice *)(cmd + 6);
453 memset (mp, 0, MODE_SUBDEV_LEN);
454 mp->page_code = 0x20;
455 mp->page_length = 26;
456 switch (mode)
457 {
458 case SCAN_SIMPLE:
459 mp->a_mode = 0x40;
460 mp->f_mode = 0x40;
461 break;
462 case SCAN_WITH_FSU:
463 mp->a_mode = 0;
464 mp->f_mode = 0x40;
465 break;
466 case SCAN_WITH_ADF:
467 mp->a_mode = 0x40;
468 mp->f_mode = 0;
469 break;
470 }
471
472 status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
473
474 DBG (11, ">>\n");
475 return (status);
476 }
477 #endif
478
479 static SANE_Status wait_ready(int fd);
480
481 static SANE_Status
mode_sense(int fd, void *modeparam_buf, size_t * modeparam_size, int page)482 mode_sense (int fd, void *modeparam_buf, size_t * modeparam_size,
483 int page)
484 {
485 static u_char cmd[6] = {MODE_SENSE6, 0, 0, 0, 0, 0};
486 SANE_Status status;
487 DBG (11, "<< mode_sense ");
488 cmd[0] = 0x1a;
489 cmd[2] = page;
490 cmd[4] = *modeparam_size;
491 status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), modeparam_buf,
492 modeparam_size);
493
494 DBG (11, ">>\n");
495 return (status);
496 }
497
498 static SANE_Status
scan(int fd)499 scan (int fd)
500 {
501 static u_char cmd[] = {SCAN, 0, 0, 0, 0, 0};
502 SANE_Status status;
503 DBG (11, "<< scan ");
504
505 status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
506
507 DBG (11, ">>\n");
508 return (status);
509 }
510
511 #if 0
512 static SANE_Status
513 send_diagnostics (int fd)
514 {
515 static u_char cmd[] = {SEND_DIAGNOSTIC, 0x04, 0, 0, 0, 0};
516 SANE_Status status;
517 DBG (11, "<< send_diagnostics ");
518
519 status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
520
521 DBG (11, ">>\n");
522 return (status);
523 }
524 #endif
525
526 static SANE_Status
set_window(int fd, window_param *wp, int len)527 set_window (int fd, window_param *wp, int len)
528 {
529 static u_char cmd[10 + WINDOW_LEN] =
530 {SET_WINDOW, 0, 0, 0, 0, 0, 0, 0, 0, 0};
531 window_param *winp;
532 SANE_Status status;
533 DBG (11, "<< set_window ");
534
535 cmd[8] = len;
536 winp = (window_param *)(cmd + 10);
537 memset (winp, 0, WINDOW_LEN);
538 memcpy (winp, wp, len);
539 status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
540
541 DBG (11, ">>\n");
542 return (status);
543
544 }
545
546 static SANE_Status
get_window(int fd, void *buf, size_t * buf_size)547 get_window (int fd, void *buf, size_t * buf_size)
548 {
549 static u_char cmd[10] = {GET_WINDOW, 0, 0, 0, 0, 0, 0, 0, WINDOW_LEN, 0};
550 SANE_Status status;
551 DBG (11, "<< get_window ");
552
553 cmd[8] = *buf_size;
554 status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
555
556 DBG (11, ">>\n");
557 return (status);
558 }
559
560 #if 0
561 static SANE_Status
562 get_data_buffer_status (int fd, void *buf, size_t *buf_size)
563 {
564 static u_char cmd[10] =
565 {GET_DATA_BUFFER_STATUS, 0, 0, 0, 0, 0, 0, 0, 0, 0};
566 SANE_Status status;
567 DBG (11, "<< get_data_buffer_status ");
568
569 cmd[8] = *buf_size;
570 status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
571
572 DBG (11, ">>\n");
573 return (status);
574 }
575 #endif
576
577 #ifdef USE_FORK
578
579 /* the following four functions serve simply the purpose
580 to avoid "over-optimised" code when reader_process and
581 read_data wait for the buffer to become ready. The simple
582 while-loops in these functions which check the buffer
583 status may be optimised so that the machine code only
584 operates with registers instead of using the variable
585 values stored in memory. (This is only a workaround -
586 it would be better to set a compiler pragma, which ensures
587 that the program looks into the RAM in these while loops --
588 but unfortunately I could not find appropriate information
589 about this at least for gcc, not to speak about other
590 compilers...
591 Abel)
592 */
593
594 static int
cancel_requested(NEC_Scanner *s)595 cancel_requested(NEC_Scanner *s)
596 {
597 return s->rdr_ctl->cancel;
598 }
599
600 static SANE_Status
rdr_status(NEC_Scanner *s)601 rdr_status(NEC_Scanner *s)
602 {
603 return s->rdr_ctl->status;
604 }
605
606 static int
buf_status(NEC_shmem_ctl *s)607 buf_status(NEC_shmem_ctl *s)
608 {
609 return s->shm_status;
610 }
611
612 static int
reader_running(NEC_Scanner *s)613 reader_running(NEC_Scanner *s)
614 {
615 return s->rdr_ctl->running;
616 }
617
618 static int
reader_process(NEC_Scanner *s)619 reader_process(NEC_Scanner *s)
620 {
621 SANE_Status status;
622 sigset_t sigterm_set;
623 static u_char cmd[] = {READ, 0, 0, 0, 0, 0, 0, 0, 0, 0};
624 int full_count = 0, counted;
625 size_t waitindex, cmdindex;
626 size_t bytes_to_queue;
627 size_t nread;
628 size_t max_bytes_per_read;
629 int max_queue;
630 int i;
631 NEC_shmem_ctl *bc;
632
633 s->rdr_ctl->running = 1;
634 DBG(11, "<< reader_process\n");
635
636 sigemptyset (&sigterm_set);
637
638 bytes_to_queue = s->bytes_to_read;
639
640 max_bytes_per_read = s->dev->info.bufsize / s->params.bytes_per_line;
641 if (max_bytes_per_read)
642 max_bytes_per_read *= s->params.bytes_per_line;
643 else
644 /* this is a really tiny buffer..*/
645 max_bytes_per_read = s->dev->info.bufsize;
646
647 /* wait_ready(s->fd); */
648
649 if (s->dev->info.queued_reads <= s->dev->info.buffers)
650 max_queue = s->dev->info.queued_reads;
651 else
652 max_queue = s->dev->info.buffers;
653 for (i = 0; i < max_queue; i++)
654 {
655 bc = &s->rdr_ctl->buf_ctl[i];
656 if (bytes_to_queue)
657 {
658 nread = bytes_to_queue;
659 if (nread > max_bytes_per_read)
660 nread = max_bytes_per_read;
661 bc->used = nread;
662 cmd[6] = nread >> 16;
663 cmd[7] = nread >> 8;
664 cmd[8] = nread;
665 #ifdef QUEUEDEBUG
666 DBG(2, "reader: req_enter...\n");
667 #endif
668 status = sanei_scsi_req_enter (s->fd, cmd, sizeof (cmd),
669 bc->buffer,
670 &bc->used,
671 &bc->qid);
672 #ifdef QUEUEDEBUG
673 DBG(2, "reader: req_enter ok\n");
674 #endif
675 if (status != SANE_STATUS_GOOD)
676 {
677 DBG(1, "reader_process: read command failed: %s",
678 sane_strstatus(status));
679 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
680 sanei_scsi_req_flush_all_extended(s->fd);
681 #else
682 sanei_scsi_req_flush_all();
683 #endif
684 s->rdr_ctl->status = status;
685 s->rdr_ctl->running = 0;
686 return 2;
687 }
688 bc->shm_status = SHM_BUSY;
689 bc->nreq = bc->used;
690 bytes_to_queue -= bc->nreq;
691 }
692 else
693 {
694 bc->used = 0;
695 bc->shm_status = SHM_EMPTY;
696 }
697 }
698 waitindex = 0;
699 cmdindex = i % s->dev->info.buffers;
700
701 while(s->bytes_to_read > 0)
702 {
703 if (cancel_requested(s))
704 {
705 #ifdef QUEUEDEBUG
706 DBG(2, "reader: flushing requests...\n");
707 #endif
708 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
709 sanei_scsi_req_flush_all_extended(s->fd);
710 #else
711 sanei_scsi_req_flush_all();
712 #endif
713 #ifdef QUEUEDEBUG
714 DBG(2, "reader: flushing requests ok\n");
715 #endif
716 s->rdr_ctl->cancel = 0;
717 s->rdr_ctl->status = SANE_STATUS_CANCELLED;
718 s->rdr_ctl->running = 0;
719 DBG(11, " reader_process (cancelled) >>\n");
720 return 1;
721 }
722
723 bc = &s->rdr_ctl->buf_ctl[waitindex];
724 if (bc->shm_status == SHM_BUSY)
725 {
726 #ifdef DEBUG
727 {
728 struct timeval t;
729 gettimeofday(&t, 0);
730 DBG(2, "rd: waiting for data %li.%06li\n", t.tv_sec, t.tv_usec);
731 }
732 #endif
733 #ifdef QUEUEDEBUG
734 DBG(2, "reader: req_wait...\n");
735 #endif
736 status = sanei_scsi_req_wait(bc->qid);
737 #ifdef QUEUEDEBUG
738 DBG(2, "reader: req_wait ok\n");
739 #endif
740 #ifdef DEBUG
741 {
742 struct timeval t;
743 gettimeofday(&t, 0);
744 DBG(2, "rd: data received %li.%06li\n", t.tv_sec, t.tv_usec);
745 }
746 #endif
747 if (status != SANE_STATUS_GOOD)
748 {
749 DBG(1, "reader_process: read command failed: %s",
750 sane_strstatus(status));
751 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
752 sanei_scsi_req_flush_all_extended(s->fd);
753 #else
754 sanei_scsi_req_flush_all();
755 #endif
756 s->rdr_ctl->status = status;
757 s->rdr_ctl->running = 0;
758 return 2;
759 }
760 s->bytes_to_read -= bc->used;
761 bytes_to_queue += bc->nreq - bc->used;
762 bc->start = 0;
763 bc->shm_status = SHM_FULL;
764
765 waitindex++;
766 if (waitindex == s->dev->info.buffers)
767 waitindex = 0;
768
769 }
770
771 if (bytes_to_queue)
772 {
773 /* wait until the next buffer is completely read via read_data */
774 bc = &s->rdr_ctl->buf_ctl[cmdindex];
775 counted = 0;
776 while (buf_status(bc) != SHM_EMPTY)
777 {
778 if (!counted)
779 {
780 counted = 1;
781 full_count++;
782 }
783 if (cancel_requested(s))
784 {
785 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
786 sanei_scsi_req_flush_all_extended(s->fd);
787 #else
788 sanei_scsi_req_flush_all();
789 #endif
790 s->rdr_ctl->cancel = 0;
791 s->rdr_ctl->status = SANE_STATUS_CANCELLED;
792 s->rdr_ctl->running = 0;
793 DBG(11, " reader_process (cancelled) >>\n");
794 return 1;
795 }
796 }
797
798 nread = bytes_to_queue;
799 if (nread > max_bytes_per_read)
800 nread = max_bytes_per_read;
801 bc->used = nread;
802 cmd[6] = nread >> 16;
803 cmd[7] = nread >> 8;
804 cmd[8] = nread;
805 status = sanei_scsi_req_enter (s->fd, cmd, sizeof (cmd),
806 bc->buffer, &bc->used, &bc->qid);
807 if (status != SANE_STATUS_GOOD)
808 {
809 DBG(1, "reader_process: read command failed: %s",
810 sane_strstatus(status));
811 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
812 sanei_scsi_req_flush_all_extended(s->fd);
813 #else
814 sanei_scsi_req_flush_all();
815 #endif
816 s->rdr_ctl->status = status;
817 s->rdr_ctl->running = 0;
818 return 2;
819 }
820 bc->shm_status = SHM_BUSY;
821 bc->nreq = nread;
822 bytes_to_queue -= nread;
823
824 cmdindex++;
825 if (cmdindex == s->dev->info.buffers)
826 cmdindex = 0;
827 }
828
829 if (cancel_requested(s))
830 {
831 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
832 sanei_scsi_req_flush_all_extended(s->fd);
833 #else
834 sanei_scsi_req_flush_all();
835 #endif
836 s->rdr_ctl->cancel = 0;
837 s->rdr_ctl->status = SANE_STATUS_CANCELLED;
838 s->rdr_ctl->running = 0;
839 DBG(11, " reader_process (cancelled) >>\n");
840 return 1;
841 }
842 }
843
844 DBG(1, "buffer full conditions: %i\n", full_count);
845 DBG(11, " reader_process>>\n");
846
847 s->rdr_ctl->running = 0;
848 return 0;
849 }
850
851 static SANE_Status
read_data(NEC_Scanner *s, SANE_Byte *buf, size_t * buf_size)852 read_data (NEC_Scanner *s, SANE_Byte *buf, size_t * buf_size)
853 {
854 size_t copysize, copied = 0;
855 NEC_shmem_ctl *bc;
856
857 DBG(11, "<< read_data ");
858
859 bc = &s->rdr_ctl->buf_ctl[s->read_buff];
860
861 while (copied < *buf_size)
862 {
863 /* wait until the reader process delivers data or a scanner error occurs: */
864 while ( buf_status(bc) != SHM_FULL
865 && rdr_status(s) == SANE_STATUS_GOOD)
866 {
867 usleep(10); /* could perhaps be longer. make this user configurable?? */
868 }
869
870 if (rdr_status(s) != SANE_STATUS_GOOD)
871 {
872 return rdr_status(s);
873 DBG(11, ">>\n");
874 }
875
876 copysize = bc->used - bc->start;
877
878 if (copysize > *buf_size - copied )
879 copysize = *buf_size - copied;
880
881 memcpy(buf, &(bc->buffer[bc->start]), copysize);
882
883 copied += copysize;
884 buf = &buf[copysize];
885
886 bc->start += copysize;
887 if (bc->start >= bc->used)
888 {
889 bc->start = 0;
890 bc->shm_status = SHM_EMPTY;
891 s->read_buff++;
892 if (s->read_buff == s->dev->info.buffers)
893 s->read_buff = 0;
894 bc = &s->rdr_ctl->buf_ctl[s->read_buff];
895 }
896 }
897
898 DBG(11, ">>\n");
899 return SANE_STATUS_GOOD;
900 }
901
902 #else /* don't USE_FORK: */
903
904 static SANE_Status
read_data(NEC_Scanner *s, SANE_Byte *buf, size_t * buf_size)905 read_data (NEC_Scanner *s, SANE_Byte *buf, size_t * buf_size)
906 {
907 static u_char cmd[] = {READ, 0, 0, 0, 0, 0, 0, 0, 0, 0};
908 SANE_Status status = SANE_STATUS_GOOD;
909 size_t remain = *buf_size;
910 size_t nread;
911 DBG (11, "<< read_data ");
912
913 /* sane_read_shuffled requires that read_data returns
914 exactly *buf_size bytes, so it must be guaranteed here.
915 Further make sure that not more bytes are read in than
916 sanei_scsi_max_request_size allows, to avoid a failure
917 of the read command
918 */
919 while (remain > 0)
920 {
921 nread = remain;
922 if (nread > s->dev->info.bufsize)
923 nread = s->dev->info.bufsize;
924 cmd[6] = nread >> 16;
925 cmd[7] = nread >> 8;
926 cmd[8] = nread;
927 status = sanei_scsi_cmd (s->fd, cmd, sizeof (cmd),
928 &buf[*buf_size - remain], &nread);
929 if (status != SANE_STATUS_GOOD)
930 {
931 DBG(11, ">>\n");
932 return(status);
933 }
934 remain -= nread;
935 }
936 DBG (11, ">>\n");
937 return (status);
938 }
939 #endif
940
941 static size_t
max_string_size(const SANE_String_Const strings[])942 max_string_size (const SANE_String_Const strings[])
943 {
944 size_t size, max_size = 0;
945 int i;
946 DBG (10, "<< max_string_size ");
947
948 for (i = 0; strings[i]; ++i)
949 {
950 size = strlen (strings[i]) + 1;
951 if (size > max_size)
952 max_size = size;
953 }
954
955 DBG (10, ">>\n");
956 return max_size;
957 }
958
959 static SANE_Status
wait_ready(int fd)960 wait_ready(int fd)
961 {
962 SANE_Status status;
963 int retry = 0;
964
965 while ((status = test_unit_ready (fd)) != SANE_STATUS_GOOD)
966 {
967 DBG (5, "wait_ready failed (%d)\n", retry);
968 DBG (5, "wait_ready status = (%d)\n", status);
969 if (retry++ > 15){
970 return SANE_STATUS_IO_ERROR;
971 }
972 sleep(3);
973 }
974 return (status);
975
976 }
977
978 static SANE_Status
attach(const char *devnam, NEC_Device ** devp)979 attach (const char *devnam, NEC_Device ** devp)
980 {
981 SANE_Status status;
982 NEC_Device *dev;
983 NEC_Sense_Data sensedat;
984
985 int fd;
986 unsigned char inquiry_data[INQUIRY_LEN];
987 const unsigned char *model_name;
988 mode_sense_param msp;
989 size_t buf_size;
990 DBG (10, "<< attach ");
991
992 for (dev = first_dev; dev; dev = dev->next)
993 {
994 if (strcmp (dev->sane.name, devnam) == 0)
995 {
996 if (devp)
997 *devp = dev;
998 return (SANE_STATUS_GOOD);
999 }
1000 }
1001
1002 sensedat.model = unknown;
1003 sensedat.complain_on_adf_error = 0;
1004 DBG (3, "attach: opening %s\n", devnam);
1005 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
1006 {
1007 int bufsize = 4096;
1008 status = sanei_scsi_open_extended (devnam, &fd, &sense_handler, &sensedat, &bufsize);
1009 if (status != SANE_STATUS_GOOD)
1010 {
1011 DBG (1, "attach: open failed: %s\n", sane_strstatus (status));
1012 return (status);
1013 }
1014 if (bufsize < 4096)
1015 {
1016 DBG(1, "attach: open failed. no memory\n");
1017 sanei_scsi_close(fd);
1018 return SANE_STATUS_NO_MEM;
1019 }
1020 }
1021 #else
1022 status = sanei_scsi_open (devnam, &fd, &sense_handler, &sensedat);
1023 if (status != SANE_STATUS_GOOD)
1024 {
1025 DBG (1, "attach: open failed: %s\n", sane_strstatus (status));
1026 return (status);
1027 }
1028 #endif
1029
1030 DBG (3, "attach: sending INQUIRY\n");
1031 memset (inquiry_data, 0, sizeof (inquiry_data));
1032 buf_size = sizeof (inquiry_data);
1033 status = inquiry (fd, inquiry_data, &buf_size);
1034 if (status != SANE_STATUS_GOOD)
1035 {
1036 DBG (1, "attach: inquiry failed: %s\n", sane_strstatus (status));
1037 sanei_scsi_close (fd);
1038 return (status);
1039 }
1040
1041 if (inquiry_data[0] == 6 && strncmp ((char *)inquiry_data + 8, "NEC", 3) == 0)
1042 {
1043 if (strncmp ((char *)inquiry_data + 16, "PC-IN500/4C", 11) == 0)
1044 sensedat.model = PCIN500;
1045 else
1046 sensedat.model = unknown;
1047 }
1048
1049 if (sensedat.model == unknown)
1050 {
1051 DBG (1, "attach: device doesn't look like a NEC scanner\n");
1052 DBG (1, " : Only PC-IN500/4C is supported.\n");
1053 sanei_scsi_close (fd);
1054 return (SANE_STATUS_INVAL);
1055 }
1056
1057 DBG (3, "attach: sending TEST_UNIT_READY\n");
1058 status = test_unit_ready (fd);
1059 if (status != SANE_STATUS_GOOD)
1060 {
1061 DBG (1, "attach: test unit ready failed (%s)\n",
1062 sane_strstatus (status));
1063 sanei_scsi_close (fd);
1064 return (status);
1065 }
1066 DBG (3, "attach: sending MODE SELECT\n");
1067
1068 if (sensedat.model == PCIN500)
1069 status = mode_select_mud (fd, DEFAULT_MUD_1200);
1070
1071 if (status != SANE_STATUS_GOOD)
1072 {
1073 DBG (1, "attach: MODE_SELECT_MUD failed\n");
1074 sanei_scsi_close (fd);
1075 return (SANE_STATUS_INVAL);
1076 }
1077
1078 DBG (3, "attach: sending MODE SENSE/MUP page\n");
1079 memset (&msp, 0, sizeof (msp));
1080 buf_size = sizeof (msp);
1081 status = mode_sense (fd, &msp, &buf_size, 3);
1082 if (status != SANE_STATUS_GOOD)
1083 {
1084 DBG (1, "attach: MODE_SENSE/MUP page failed\n");
1085 sanei_scsi_close (fd);
1086 return (SANE_STATUS_INVAL);
1087 }
1088 #ifdef DEBUG_NEC
1089 DBG (3,"attach: MODE SENSE parameter\n");
1090 DBG(11, "%02x %02x %02x %02x "
1091 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
1092 msp.mode_data_length,
1093 msp.mode_param_header2,
1094 msp.mode_param_header3,
1095 msp.mode_desciptor_length,
1096 msp.page_code,
1097 msp.page_length,
1098 msp.bmu,
1099 msp.res2,
1100 msp.mud[0],
1101 msp.mud[1],
1102 msp.res3,
1103 msp.res4);
1104 #endif
1105 dev = malloc (sizeof (*dev));
1106 if (!dev)
1107 return (SANE_STATUS_NO_MEM);
1108 memset (dev, 0, sizeof (*dev));
1109
1110 dev->sane.name = (SANE_String) strdup (devnam);
1111 dev->sane.vendor = "NEC";
1112 model_name = inquiry_data + 16;
1113 dev->sane.model = strndup ((const char *)model_name, 10);
1114 dev->sane.type = "flatbed scanner";
1115
1116 dev->sensedat.model = sensedat.model;
1117
1118 DBG (5, "dev->sane.name = %s\n", dev->sane.name);
1119 DBG (5, "dev->sane.vendor = %s\n", dev->sane.vendor);
1120 DBG (5, "dev->sane.model = %s\n", dev->sane.model);
1121 DBG (5, "dev->sane.type = %s\n", dev->sane.type);
1122
1123 if (sensedat.model == PCIN500)
1124 dev->info.res_range.quant = 10;
1125 else
1126 dev->info.res_range.quant = 0;
1127
1128 dev->info.tl_x_ranges[SCAN_SIMPLE].min = SANE_FIX(0);
1129 dev->info.br_x_ranges[SCAN_SIMPLE].min = SANE_FIX(1);
1130 dev->info.tl_y_ranges[SCAN_SIMPLE].min = SANE_FIX(0);
1131 dev->info.br_y_ranges[SCAN_SIMPLE].min = SANE_FIX(1);
1132 dev->info.tl_x_ranges[SCAN_SIMPLE].quant = SANE_FIX(0);
1133 dev->info.br_x_ranges[SCAN_SIMPLE].quant = SANE_FIX(0);
1134 dev->info.tl_y_ranges[SCAN_SIMPLE].quant = SANE_FIX(0);
1135 dev->info.br_y_ranges[SCAN_SIMPLE].quant = SANE_FIX(0);
1136
1137 if (sensedat.model == PCIN500)
1138 dev->info.res_default = 15;
1139 else
1140 dev->info.res_default = 150;
1141 dev->info.tl_x_ranges[SCAN_SIMPLE].max = SANE_FIX(209);
1142 dev->info.br_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210);
1143 dev->info.tl_y_ranges[SCAN_SIMPLE].max = SANE_FIX(296);
1144 dev->info.br_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297);
1145
1146 dev->info.bmu = msp.bmu;
1147 dev->info.mud = (msp.mud[0] << 8) + msp.mud[1];
1148
1149 dev->info.adf_fsu_installed = 0;
1150 if (dev->sensedat.model == PCIN500)
1151 {
1152 dev->info.res_range.max = 48;
1153 dev->info.res_range.min = 5;
1154
1155 dev->info.x_default = SANE_FIX(210);
1156 dev->info.tl_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */
1157 dev->info.br_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */
1158
1159 dev->info.y_default = SANE_FIX(297);
1160 dev->info.tl_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */
1161 dev->info.br_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */
1162 }
1163 else
1164 {
1165 dev->info.res_range.max = 400;
1166 dev->info.res_range.min = 50;
1167
1168 dev->info.x_default = SANE_FIX(210);
1169 dev->info.tl_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */
1170 dev->info.br_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */
1171
1172 dev->info.y_default = SANE_FIX(297);
1173 dev->info.tl_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */
1174 dev->info.br_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */
1175 }
1176 sanei_scsi_close (fd);
1177
1178 dev->info.threshold_range.min = 1;
1179 dev->info.threshold_range.max = 255;
1180 dev->info.threshold_range.quant = 0;
1181
1182 dev->info.tint_range.min = 1;
1183 dev->info.tint_range.max = 255;
1184 dev->info.tint_range.quant = 0;
1185
1186 dev->info.color_range.min = 1;
1187 dev->info.color_range.max = 255;
1188 dev->info.color_range.quant = 0;
1189
1190 DBG (5, "res_default=%d\n", dev->info.res_default);
1191 DBG (5, "res_range.max=%d\n", dev->info.res_range.max);
1192 DBG (5, "res_range.min=%d\n", dev->info.res_range.min);
1193 DBG (5, "res_range.quant=%d\n", dev->info.res_range.quant);
1194
1195 DBG (5, "x_default=%f\n", SANE_UNFIX(dev->info.x_default));
1196 DBG (5, "tl_x_range[0].max=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_SIMPLE].max));
1197 DBG (5, "tl_x_range[0].min=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_SIMPLE].min));
1198 DBG (5, "tl_x_range[0].quant=%d\n", dev->info.tl_x_ranges[SCAN_SIMPLE].quant);
1199 DBG (5, "br_x_range[0].max=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_SIMPLE].max));
1200 DBG (5, "br_x_range[0].min=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_SIMPLE].min));
1201 DBG (5, "br_x_range[0].quant=%d\n", dev->info.br_x_ranges[SCAN_SIMPLE].quant);
1202 DBG (5, "y_default=%f\n", SANE_UNFIX(dev->info.y_default));
1203 DBG (5, "tl_y_range[0].max=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_SIMPLE].max));
1204 DBG (5, "tl_y_range[0].min=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_SIMPLE].min));
1205 DBG (5, "tl_y_range[0].quant=%d\n", dev->info.tl_y_ranges[SCAN_SIMPLE].quant);
1206 DBG (5, "br_y_range[0].max=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_SIMPLE].max));
1207 DBG (5, "br_y_range[0].min=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_SIMPLE].min));
1208 DBG (5, "br_y_range[0].quant=%d\n", dev->info.br_y_ranges[SCAN_SIMPLE].quant);
1209
1210 if (dev->info.adf_fsu_installed & HAVE_FSU)
1211 {
1212 DBG (5, "tl_x_range[1].max=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_FSU].max));
1213 DBG (5, "tl_x_range[1].min=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_FSU].min));
1214 DBG (5, "tl_x_range[1].quant=%d\n", dev->info.tl_x_ranges[SCAN_WITH_FSU].quant);
1215 DBG (5, "br_x_range[1].max=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_FSU].max));
1216 DBG (5, "br_x_range[1].min=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_FSU].min));
1217 DBG (5, "br_x_range[1].quant=%d\n", dev->info.br_x_ranges[SCAN_WITH_FSU].quant);
1218 DBG (5, "tl_y_range[1].max=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_FSU].max));
1219 DBG (5, "tl_y_range[1].min=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_FSU].min));
1220 DBG (5, "tl_y_range[1].quant=%d\n", dev->info.tl_y_ranges[SCAN_WITH_FSU].quant);
1221 DBG (5, "br_y_range[1].max=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_FSU].max));
1222 DBG (5, "br_y_range[1].min=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_FSU].min));
1223 DBG (5, "br_y_range[1].quant=%d\n", dev->info.br_y_ranges[SCAN_WITH_FSU].quant);
1224 }
1225
1226 if (dev->info.adf_fsu_installed & HAVE_ADF)
1227 {
1228 DBG (5, "tl_x_range[2].max=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_ADF].max));
1229 DBG (5, "tl_x_range[2].min=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_ADF].min));
1230 DBG (5, "tl_x_range[2].quant=%d\n", dev->info.tl_x_ranges[SCAN_WITH_ADF].quant);
1231 DBG (5, "br_x_range[2].max=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_ADF].max));
1232 DBG (5, "br_x_range[2].min=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_ADF].min));
1233 DBG (5, "br_x_range[2].quant=%d\n", dev->info.br_x_ranges[SCAN_WITH_ADF].quant);
1234 DBG (5, "tl_y_range[2].max=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_ADF].max));
1235 DBG (5, "tl_y_range[2].min=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_ADF].min));
1236 DBG (5, "tl_y_range[2].quant=%d\n", dev->info.tl_y_ranges[SCAN_WITH_ADF].quant);
1237 DBG (5, "br_y_range[2].max=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_ADF].max));
1238 DBG (5, "br_y_range[2].min=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_ADF].min));
1239 DBG (5, "br_y_range[2].quant=%d\n", dev->info.br_y_ranges[SCAN_WITH_ADF].quant);
1240 }
1241
1242 DBG (5, "bmu=%d\n", dev->info.bmu);
1243 DBG (5, "mud=%d\n", dev->info.mud);
1244
1245 ++num_devices;
1246 dev->next = first_dev;
1247 first_dev = dev;
1248
1249 if (devp)
1250 *devp = dev;
1251
1252 DBG (10, ">>\n");
1253 return (SANE_STATUS_GOOD);
1254 }
1255
1256 /* Enabling / disabling of gamma options.
1257 Depends on many user settable options, so lets put it into
1258 one function to be called by init_options and by sane_control_option
1259
1260 */
1261 #ifdef USE_CUSTOM_GAMMA
1262 static void
set_gamma_caps(NEC_Scanner *s)1263 set_gamma_caps(NEC_Scanner *s)
1264 {
1265 /* neither fixed nor custom gamma for line art modes */
1266 if ( strcmp(s->val[OPT_MODE].s, M_LINEART) == 0
1267 || strcmp(s->val[OPT_MODE].s, M_LINEART_COLOR) == 0)
1268 {
1269 s->opt[OPT_GAMMA].cap |= SANE_CAP_INACTIVE;
1270 s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
1271 s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1272 s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1273 s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1274 s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1275 }
1276 else if (strcmp(s->val[OPT_MODE].s, M_GRAY) == 0)
1277 {
1278 s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
1279 if (s->val[OPT_CUSTOM_GAMMA].w == SANE_FALSE)
1280 {
1281 s->opt[OPT_GAMMA].cap &= ~SANE_CAP_INACTIVE;
1282 s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1283 }
1284 else
1285 {
1286 s->opt[OPT_GAMMA].cap |= SANE_CAP_INACTIVE;
1287 s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
1288 }
1289 s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1290 s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1291 s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1292 }
1293 else
1294 {
1295 /* color mode */
1296 s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
1297 if (s->val[OPT_CUSTOM_GAMMA].w == SANE_FALSE)
1298 {
1299 s->opt[OPT_GAMMA].cap &= ~SANE_CAP_INACTIVE;
1300 s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1301 s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1302 s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1303 }
1304 else
1305 {
1306 s->opt[OPT_GAMMA].cap |= SANE_CAP_INACTIVE;
1307 s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
1308 s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
1309 s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
1310 }
1311 s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1312 }
1313 }
1314 #endif /* USE_CUSTOM_GAMMA */
1315
1316 /* The next function is a slightly modified version of sanei_constrain_value
1317 Instead of returning status information like STATUS_INVAL, it adjusts
1318 an invalid value to the nearest allowed one.
1319 */
1320 static void
clip_value(const SANE_Option_Descriptor * opt, void * value)1321 clip_value (const SANE_Option_Descriptor * opt, void * value)
1322 {
1323 const SANE_String_Const * string_list;
1324 const SANE_Word * word_list;
1325 int i, num_matches, match;
1326 const SANE_Range * range;
1327 SANE_Word w, v;
1328 size_t len;
1329
1330 switch (opt->constraint_type)
1331 {
1332 case SANE_CONSTRAINT_RANGE:
1333 w = *(SANE_Word *) value;
1334 range = opt->constraint.range;
1335
1336 if (w < range->min)
1337 w = range->min;
1338 else if (w > range->max)
1339 w = range->max;
1340
1341 if (range->quant)
1342 {
1343 v = (w - range->min + range->quant/2) / range->quant;
1344 w = v * range->quant + range->min;
1345 *(SANE_Word*) value = w;
1346 }
1347 break;
1348
1349 case SANE_CONSTRAINT_WORD_LIST:
1350 w = *(SANE_Word *) value;
1351 word_list = opt->constraint.word_list;
1352 for (i = 1; w != word_list[i]; ++i)
1353 if (i >= word_list[0])
1354 /* somewhat arbitrary... Would be better to have a default value
1355 explicitly defined.
1356 */
1357 *(SANE_Word*) value = word_list[1];
1358 break;
1359
1360 case SANE_CONSTRAINT_STRING_LIST:
1361 /* Matching algorithm: take the longest unique match ignoring
1362 case. If there is an exact match, it is admissible even if
1363 the same string is a prefix of a longer option name. */
1364 string_list = opt->constraint.string_list;
1365 len = strlen (value);
1366
1367 /* count how many matches of length LEN characters we have: */
1368 num_matches = 0;
1369 match = -1;
1370 for (i = 0; string_list[i]; ++i)
1371 if (strncasecmp (value, string_list[i], len) == 0
1372 && len <= strlen (string_list[i]))
1373 {
1374 match = i;
1375 if (len == strlen (string_list[i]))
1376 {
1377 /* exact match... */
1378 if (strcmp (value, string_list[i]) != 0)
1379 /* ...but case differs */
1380 strcpy (value, string_list[match]);
1381 }
1382 ++num_matches;
1383 }
1384
1385 if (num_matches > 1)
1386 /* xxx quite arbitrary... We could also choose the first match
1387 */
1388 strcpy(value, string_list[match]);
1389 else if (num_matches == 1)
1390 strcpy (value, string_list[match]);
1391 else
1392 strcpy (value, string_list[0]);
1393
1394 default:
1395 break;
1396 }
1397 }
1398
1399 /* make sure that enough memory is allocated for each string,
1400 so that the strcpy in sane_control_option / set value cannot
1401 write behind the end of the allocated memory.
1402 */
1403 static SANE_Status
init_string_option(NEC_Scanner *s, SANE_String_Const name, SANE_String_Const title, SANE_String_Const desc, const SANE_String_Const *string_list, int option, int default_index)1404 init_string_option(NEC_Scanner *s, SANE_String_Const name,
1405 SANE_String_Const title, SANE_String_Const desc,
1406 const SANE_String_Const *string_list, int option, int default_index)
1407 {
1408 int i;
1409
1410 s->opt[option].name = name;
1411 s->opt[option].title = title;
1412 s->opt[option].desc = desc;
1413 s->opt[option].type = SANE_TYPE_STRING;
1414 s->opt[option].size = max_string_size (string_list);
1415 s->opt[option].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1416 s->opt[option].constraint.string_list = string_list;
1417 s->val[option].s = malloc(s->opt[option].size);
1418 if (s->val[option].s == 0)
1419 {
1420 for (i = 1; i < NUM_OPTIONS; i++)
1421 {
1422 if (s->val[i].s && s->opt[i].type == SANE_TYPE_STRING)
1423 free(s->val[i].s);
1424 }
1425 return SANE_STATUS_NO_MEM;
1426 }
1427 strcpy(s->val[option].s, string_list[default_index]);
1428 return SANE_STATUS_GOOD;
1429 }
1430
1431 static SANE_Status
init_options(NEC_Scanner * s)1432 init_options (NEC_Scanner * s)
1433 {
1434 int i, default_source;
1435 SANE_Word scalar;
1436 DBG (10, "<< init_options ");
1437
1438 memset (s->opt, 0, sizeof (s->opt));
1439 memset (s->val, 0, sizeof (s->val));
1440
1441 for (i = 0; i < NUM_OPTIONS; ++i)
1442 {
1443 s->opt[i].size = sizeof (SANE_Word);
1444 s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1445 s->val[i].s = 0;
1446 }
1447
1448 s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
1449 s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
1450 s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
1451 s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
1452 s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
1453
1454 /* Mode group: */
1455 s->opt[OPT_MODE_GROUP].title = "Scan Mode";
1456 s->opt[OPT_MODE_GROUP].desc = "";
1457 s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
1458 s->opt[OPT_MODE_GROUP].cap = 0;
1459 s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1460
1461 /* scan mode */
1462 init_string_option(s, SANE_NAME_SCAN_MODE, SANE_TITLE_SCAN_MODE,
1463 SANE_DESC_SCAN_MODE, mode_list, OPT_MODE, MODES_COLOR);
1464
1465 /* half tone */
1466 init_string_option(s, SANE_NAME_HALFTONE_PATTERN, SANE_TITLE_HALFTONE_PATTERN,
1467 SANE_DESC_HALFTONE " (not support)", halftone_list, OPT_HALFTONE, 0);
1468
1469 if (s->dev->sensedat.model == PCIN500)
1470 s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE;
1471
1472 i = 0;
1473 default_source = -1;
1474
1475 if (s->dev->info.adf_fsu_installed & HAVE_ADF)
1476 {
1477 s->dev->info.scansources[i++] = use_adf;
1478 default_source = SCAN_WITH_ADF;
1479 }
1480 if (s->dev->info.adf_fsu_installed & HAVE_FSU)
1481 {
1482 s->dev->info.scansources[i++] = use_fsu;
1483 if (default_source < 0)
1484 default_source = SCAN_WITH_FSU;
1485 }
1486 s->dev->info.scansources[i++] = use_simple;
1487 if (default_source < 0)
1488 default_source = SCAN_SIMPLE;
1489 s->dev->info.scansources[i] = 0;
1490
1491 init_string_option(s, SANE_NAME_SCAN_SOURCE, SANE_TITLE_SCAN_SOURCE,
1492 SANE_DESC_SCAN_SOURCE, (SANE_String_Const*)s->dev->info.scansources,
1493 OPT_SCANSOURCE, 0);
1494
1495 if (i < 2)
1496 s->opt[OPT_SCANSOURCE].cap |= SANE_CAP_INACTIVE;
1497
1498 if (s->dev->sensedat.model == PCIN500)
1499 init_string_option(s, "Paper size", "Paper size",
1500 "Paper size", paper_list_pcin500, OPT_PAPER, 0);
1501 else
1502 init_string_option(s, "Paper size", "Paper size",
1503 "Paper size", paper_list_pcinxxx, OPT_PAPER, 1);
1504
1505 /* gamma */
1506 init_string_option(s, "Gamma", "Gamma", "Gamma", gamma_list, OPT_GAMMA, 0);
1507
1508 /* Resolution Group */
1509 s->opt[OPT_RESOLUTION_GROUP].title = "Resolution";
1510 s->opt[OPT_RESOLUTION_GROUP].desc = "";
1511 s->opt[OPT_RESOLUTION_GROUP].type = SANE_TYPE_GROUP;
1512 s->opt[OPT_RESOLUTION_GROUP].cap = 0;
1513 s->opt[OPT_RESOLUTION_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1514
1515 #ifdef USE_RESOLUTION_LIST
1516 /* select resolution */
1517 if (s->dev->sensedat.model == PCIN500)
1518 init_string_option(s, "Resolution", "Resolution", "Resolution",
1519 resolution_list_pcin500, OPT_RESOLUTION_LIST, RESOLUTION_MAX_PCIN500);
1520 else
1521 init_string_option(s, "Resolution", "Resolution", "Resolution",
1522 resolution_list_pcinxxx, OPT_RESOLUTION_LIST, RESOLUTION_MAX_PCINXXX);
1523 #endif
1524
1525 /* x & y resolution */
1526 s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
1527 if (s->dev->sensedat.model == PCIN500)
1528 s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION"(x 10)";
1529 else
1530 s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
1531 s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
1532 s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
1533 s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
1534 s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
1535 s->opt[OPT_RESOLUTION].constraint.range = &s->dev->info.res_range;
1536 s->val[OPT_RESOLUTION].w = s->dev->info.res_default;
1537
1538 /* "Geometry" group: */
1539 s->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
1540 s->opt[OPT_GEOMETRY_GROUP].desc = "";
1541 s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
1542 s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
1543 s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1544
1545 /* top-left x */
1546 s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
1547 s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
1548 s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
1549 s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
1550 s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
1551 s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1552 s->opt[OPT_TL_X].constraint.range = &s->dev->info.tl_x_ranges[default_source];
1553 s->val[OPT_TL_X].w = s->dev->info.tl_x_ranges[default_source].min;
1554
1555 /* top-left y */
1556 s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1557 s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1558 s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1559 s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
1560 s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
1561 s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1562 s->opt[OPT_TL_Y].constraint.range = &s->dev->info.tl_y_ranges[default_source];
1563 s->val[OPT_TL_Y].w = s->dev->info.tl_y_ranges[default_source].min;
1564
1565 /* bottom-right x */
1566 s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
1567 s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
1568 s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
1569 s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
1570 s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
1571 s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
1572 s->opt[OPT_BR_X].constraint.range = &s->dev->info.br_x_ranges[default_source];
1573 scalar = s->dev->info.x_default;
1574 clip_value (&s->opt[OPT_BR_X], &scalar);
1575 s->val[OPT_BR_X].w = scalar;
1576
1577 /* bottom-right y */
1578 s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
1579 s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
1580 s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
1581 s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
1582 s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
1583 s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1584 s->opt[OPT_BR_Y].constraint.range = &s->dev->info.br_y_ranges[default_source];
1585 scalar = s->dev->info.y_default;
1586 clip_value (&s->opt[OPT_BR_X], &scalar);
1587 s->val[OPT_BR_Y].w = scalar;
1588
1589 /* "Enhancement" group: */
1590 s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
1591 s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
1592 s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
1593 s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
1594 s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1595
1596 /* edge emphasis */
1597 init_string_option(s, "Edge emphasis", "Edge emphasis",
1598 "Edge emphasis", edge_emphasis_list,
1599 OPT_EDGE_EMPHASIS, 0);
1600
1601 if (s->dev->sensedat.model == PCIN500)
1602 s->opt[OPT_EDGE_EMPHASIS].cap |= SANE_CAP_INACTIVE;
1603
1604 /* OR */
1605 s->opt[OPT_OR].name = "OR";
1606 s->opt[OPT_OR].title = "OR";
1607 s->opt[OPT_OR].desc = "Select OR emphancement";
1608 s->opt[OPT_OR].type = SANE_TYPE_BOOL;
1609 s->val[OPT_OR].w = SANE_FALSE;
1610
1611 /* EDGE */
1612 s->opt[OPT_EDGE].name = "edge";
1613 s->opt[OPT_EDGE].title = "Edge";
1614 s->opt[OPT_EDGE].desc = "Select Edge emphancement";
1615 s->opt[OPT_EDGE].type = SANE_TYPE_BOOL;
1616 s->val[OPT_EDGE].w = SANE_FALSE;
1617
1618 /* NR */
1619 s->opt[OPT_NR].name = "NR";
1620 s->opt[OPT_NR].title = "NR";
1621 s->opt[OPT_NR].desc = "Select noise reduction";
1622 s->opt[OPT_NR].type = SANE_TYPE_BOOL;
1623 s->val[OPT_NR].w = SANE_FALSE;
1624
1625 if (s->dev->sensedat.model != PCIN500)
1626 {
1627 s->opt[OPT_EDGE].cap |= SANE_CAP_INACTIVE;
1628 s->opt[OPT_NR].cap |= SANE_CAP_INACTIVE;
1629 s->opt[OPT_OR].cap |= SANE_CAP_INACTIVE;
1630 }
1631 /* tint */
1632 s->opt[OPT_TINT].name = "tint";
1633 s->opt[OPT_TINT].title = "Tint";
1634 s->opt[OPT_TINT].desc = "Select tint";
1635 s->opt[OPT_TINT].type = SANE_TYPE_INT;
1636 s->opt[OPT_TINT].unit = SANE_UNIT_NONE;
1637 s->opt[OPT_TINT].constraint_type = SANE_CONSTRAINT_RANGE;
1638 s->opt[OPT_TINT].constraint.range = &s->dev->info.tint_range;
1639 s->val[OPT_TINT].w = 128;
1640 if (s->dev->sensedat.model != PCIN500)
1641 s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE;
1642
1643 /* color */
1644 s->opt[OPT_COLOR].name = "color";
1645 s->opt[OPT_COLOR].title = "Color";
1646 s->opt[OPT_COLOR].desc = "Select color";
1647 s->opt[OPT_COLOR].type = SANE_TYPE_INT;
1648 s->opt[OPT_COLOR].unit = SANE_UNIT_NONE;
1649 s->opt[OPT_COLOR].constraint_type = SANE_CONSTRAINT_RANGE;
1650 s->opt[OPT_COLOR].constraint.range = &s->dev->info.color_range;
1651 s->val[OPT_COLOR].w = 128;
1652 if (s->dev->sensedat.model != PCIN500)
1653 s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE;
1654
1655 /* threshold */
1656 s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
1657 s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
1658 s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
1659 s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
1660 s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
1661 s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
1662 s->opt[OPT_THRESHOLD].constraint.range = &s->dev->info.threshold_range;
1663 s->val[OPT_THRESHOLD].w = 128;
1664 s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
1665
1666 #ifdef USE_COLOR_THRESHOLD
1667 s->opt[OPT_THRESHOLD_R].name = SANE_NAME_THRESHOLD "-red";
1668 /* xxx the titles and descriptions are confusing:
1669 "set white point (red)"
1670 Any idea? maybe "threshold to get the red component on"
1671 */
1672 s->opt[OPT_THRESHOLD_R].title = SANE_TITLE_THRESHOLD " (red)";
1673 s->opt[OPT_THRESHOLD_R].desc = SANE_DESC_THRESHOLD " (red)";
1674 s->opt[OPT_THRESHOLD_R].type = SANE_TYPE_INT;
1675 s->opt[OPT_THRESHOLD_R].unit = SANE_UNIT_NONE;
1676 s->opt[OPT_THRESHOLD_R].constraint_type = SANE_CONSTRAINT_RANGE;
1677 s->opt[OPT_THRESHOLD_R].constraint.range = &s->dev->info.threshold_range;
1678 s->val[OPT_THRESHOLD_R].w = 128;
1679 s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE;
1680
1681 s->opt[OPT_THRESHOLD_G].name = SANE_NAME_THRESHOLD "-green";
1682 s->opt[OPT_THRESHOLD_G].title = SANE_TITLE_THRESHOLD " (green)";
1683 s->opt[OPT_THRESHOLD_G].desc = SANE_DESC_THRESHOLD " (green)";
1684 s->opt[OPT_THRESHOLD_G].type = SANE_TYPE_INT;
1685 s->opt[OPT_THRESHOLD_G].unit = SANE_UNIT_NONE;
1686 s->opt[OPT_THRESHOLD_G].constraint_type = SANE_CONSTRAINT_RANGE;
1687 s->opt[OPT_THRESHOLD_G].constraint.range = &s->dev->info.threshold_range;
1688 s->val[OPT_THRESHOLD_G].w = 128;
1689 s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE;
1690
1691 s->opt[OPT_THRESHOLD_B].name = SANE_NAME_THRESHOLD "-blue";
1692 s->opt[OPT_THRESHOLD_B].title = SANE_TITLE_THRESHOLD " (blue)";
1693 s->opt[OPT_THRESHOLD_B].desc = SANE_DESC_THRESHOLD " (blue)";
1694 s->opt[OPT_THRESHOLD_B].type = SANE_TYPE_INT;
1695 s->opt[OPT_THRESHOLD_B].unit = SANE_UNIT_NONE;
1696 s->opt[OPT_THRESHOLD_B].constraint_type = SANE_CONSTRAINT_RANGE;
1697 s->opt[OPT_THRESHOLD_B].constraint.range = &s->dev->info.threshold_range;
1698 s->val[OPT_THRESHOLD_B].w = 128;
1699 s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE;
1700
1701 #endif
1702
1703 /* light color (for gray scale and line art scans) */
1704 init_string_option(s, "LightColor", "LightColor", "LightColor",
1705 light_color_list, OPT_LIGHTCOLOR, 3);
1706 s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE;
1707
1708 s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
1709 s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
1710 s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
1711 s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
1712 s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
1713 s->val[OPT_PREVIEW].w = SANE_FALSE;
1714
1715
1716 #ifdef USE_CUSTOM_GAMMA
1717 /* custom-gamma table */
1718 s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA;
1719 s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
1720 s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA;
1721 s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
1722 s->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE;
1723
1724 /* grayscale gamma vector */
1725 s->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
1726 s->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
1727 s->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
1728 s->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
1729 #if 0
1730 s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1731 #endif
1732 s->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
1733 s->opt[OPT_GAMMA_VECTOR].size = 256 * sizeof (SANE_Word);
1734 s->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
1735 s->opt[OPT_GAMMA_VECTOR].constraint.range = &u8_range;
1736 s->val[OPT_GAMMA_VECTOR].wa = &s->gamma_table[0][0];
1737
1738 /* red gamma vector */
1739 s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
1740 s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
1741 s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
1742 s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
1743 #if 0
1744 s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1745 #endif
1746 s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
1747 s->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word);
1748 s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
1749 s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range;
1750 s->val[OPT_GAMMA_VECTOR_R].wa = &s->gamma_table[1][0];
1751
1752 /* green gamma vector */
1753 s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
1754 s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
1755 s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
1756 s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
1757 #if 0
1758 s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1759 #endif
1760 s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
1761 s->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word);
1762 s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
1763 s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range;
1764 s->val[OPT_GAMMA_VECTOR_G].wa = &s->gamma_table[2][0];
1765
1766 /* blue gamma vector */
1767 s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
1768 s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
1769 s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
1770 s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
1771 #if 0
1772 s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1773 #endif
1774 s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
1775 s->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word);
1776 s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
1777 s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;
1778 s->val[OPT_GAMMA_VECTOR_B].wa = &s->gamma_table[3][0];
1779 set_gamma_caps(s);
1780 #endif
1781
1782 DBG (10, ">>\n");
1783 return SANE_STATUS_GOOD;
1784 }
1785
1786 static SANE_Status
do_cancel(NEC_Scanner * s)1787 do_cancel (NEC_Scanner * s)
1788 {
1789 DBG (10, "<< do_cancel ");
1790
1791 #ifdef USE_FORK
1792 if (s->reader_pid > 0)
1793 {
1794 int exit_status;
1795 int count = 0;
1796 /* ensure child knows it's time to stop: */
1797
1798 DBG(11, "stopping reader process\n");
1799 s->rdr_ctl->cancel = 1;
1800 while(reader_running(s) && count < 100)
1801 {
1802 usleep(100000);
1803 count++;
1804 };
1805 if (reader_running(s))
1806 {
1807 kill(s->reader_pid, SIGKILL);
1808 }
1809 wait(&exit_status);
1810 DBG(11, "reader process stopped\n");
1811
1812 s->reader_pid = 0;
1813 }
1814
1815 #endif
1816 s->scanning = SANE_FALSE;
1817
1818 if (s->fd >= 0)
1819 {
1820 sanei_scsi_close (s->fd);
1821 s->fd = -1;
1822 }
1823 #ifdef USE_FORK
1824 {
1825 struct shmid_ds ds;
1826 if (s->shmid != -1)
1827 shmctl(s->shmid, IPC_RMID, &ds);
1828 s->shmid = -1;
1829 }
1830 #endif
1831 if (s->buffer)
1832 free(s->buffer);
1833 s->buffer = 0;
1834
1835 DBG (10, ">>\n");
1836 return (SANE_STATUS_CANCELLED);
1837 }
1838
1839 static NEC_New_Device *new_devs = 0;
1840 static NEC_New_Device *new_dev_pool = 0;
1841
1842 static SANE_Status
attach_and_list(const char *devnam)1843 attach_and_list(const char *devnam)
1844 {
1845 SANE_Status res;
1846 NEC_Device *devp;
1847 NEC_New_Device *np;
1848
1849 res = attach(devnam, &devp);
1850 if (res == SANE_STATUS_GOOD)
1851 {
1852 if (new_dev_pool)
1853 {
1854 np = new_dev_pool;
1855 new_dev_pool = np->next;
1856 }
1857 else
1858 {
1859 np = malloc(sizeof(NEC_New_Device));
1860 if (np == 0)
1861 return SANE_STATUS_NO_MEM;
1862 }
1863 np->next =new_devs;
1864 np->dev = devp;
1865 new_devs = np;
1866 }
1867 return res;
1868 }
1869
1870 SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)1871 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
1872 {
1873 char devnam[PATH_MAX] = "/dev/scanner";
1874 char line[PATH_MAX];
1875 const char *lp;
1876 char *word;
1877 char *end;
1878 FILE *fp;
1879 int opt_index = 0;
1880 int buffers[2] = {DEFAULT_BUFFERS, DEFAULT_BUFFERS};
1881 int bufsize[2] = {DEFAULT_BUFSIZE, DEFAULT_BUFSIZE};
1882 int queued_reads[2] = {DEFAULT_QUEUED_READS, DEFAULT_QUEUED_READS};
1883 int linecount = 0;
1884 #if 1
1885 NEC_Device nd;
1886 NEC_Device *dp = &nd;
1887 #else
1888 NEC_Device *dp;
1889 #endif
1890 NEC_New_Device *np;
1891 int i;
1892
1893 (void) authorize; /* silence compilation warnings */
1894
1895 DBG_INIT ();
1896 DBG (10, "<< sane_init ");
1897
1898 DBG (1, "sane_init: NEC (Ver %d.%d)\n", NEC_MAJOR, NEC_MINOR);
1899
1900 if (version_code)
1901 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
1902
1903 fp = sanei_config_open (NEC_CONFIG_FILE);
1904 if (!fp)
1905 {
1906 /* use "/dev/scanner" as the default device name if no
1907 config file is available
1908 */
1909 attach (devnam, &dp);
1910 /* make sure that there are at least two buffers */
1911 if (DEFAULT_BUFFERS < 2)
1912 dp->info.buffers = DEFAULT_BUFFERS;
1913 else
1914 dp->info.buffers = 2;
1915 dp->info.wanted_bufsize = DEFAULT_BUFSIZE;
1916 dp->info.queued_reads = DEFAULT_QUEUED_READS;
1917 return SANE_STATUS_GOOD;
1918 }
1919
1920 while (fgets(line, PATH_MAX, fp))
1921 {
1922 linecount++;
1923 word = 0;
1924 lp = sanei_config_get_string(line, &word);
1925 if (word)
1926 {
1927 if (word[0] != '#')
1928 {
1929 if (strcmp(word, "option") == 0)
1930 {
1931 free(word);
1932 word = 0;
1933 lp = sanei_config_get_string(lp, &word);
1934 if (strcmp(word, "buffers") == 0)
1935 {
1936 free(word);
1937 word = 0;
1938 sanei_config_get_string(lp, &word);
1939 i = strtol(word, &end, 0);
1940 if (end == word)
1941 {
1942 DBG(1, "error in config file, line %i: number expected:\n",
1943 linecount);
1944 DBG(1, "%s\n", line);
1945 }
1946 else
1947 if (i > 2)
1948 buffers[opt_index] = i;
1949 else
1950 buffers[opt_index] = 2;
1951 }
1952 else if (strcmp(word, "buffersize") == 0)
1953 {
1954 free(word);
1955 word = 0;
1956 sanei_config_get_string(lp, &word);
1957 i = strtol(word, &end, 0);
1958 if (word == end)
1959 {
1960 DBG(1, "error in config file, line %i: number expected:\n",
1961 linecount);
1962 DBG(1, "%s\n", line);
1963 }
1964 else
1965 bufsize[opt_index] = i;
1966 }
1967 else if (strcmp(word, "readqueue") == 0)
1968 {
1969 free(word);
1970 word = 0;
1971 sanei_config_get_string(lp, &word);
1972 i = strtol(word, &end, 0);
1973 if (word == end)
1974 {
1975 DBG(1, "error in config file, line %i: number expected:\n",
1976 linecount);
1977 DBG(1, "%s\n", line);
1978 }
1979 else
1980 queued_reads[opt_index] = i;
1981 }
1982 else
1983 {
1984 DBG(1, "error in config file, line %i: unknown option\n",
1985 linecount);
1986 DBG(1, "%s\n", line);
1987 }
1988 }
1989 else
1990 {
1991 while (new_devs)
1992 {
1993 if (buffers[1] >= 2)
1994 new_devs->dev->info.buffers = buffers[1];
1995 else
1996 new_devs->dev->info.buffers = 2;
1997 if (bufsize[1] > 0)
1998 new_devs->dev->info.wanted_bufsize = bufsize[1];
1999 else
2000 new_devs->dev->info.wanted_bufsize = DEFAULT_BUFSIZE;
2001 if (queued_reads[1] >= 0)
2002 new_devs->dev->info.queued_reads = queued_reads[1];
2003 else
2004 new_devs->dev->info.queued_reads = 0;
2005 np = new_devs->next;
2006 new_devs->next = new_dev_pool;
2007 new_dev_pool = new_devs;
2008 new_devs = np;
2009 }
2010 if (line[strlen(line)-1] == '\n')
2011 line[strlen(line)-1] = 0;
2012 sanei_config_attach_matching_devices(line, &attach_and_list);
2013 buffers[1] = buffers[0];
2014 bufsize[1] = bufsize[0];
2015 queued_reads[1] = queued_reads[0];
2016 opt_index = 1;
2017 }
2018 }
2019 if (word) free(word);
2020 }
2021 }
2022
2023 while (new_devs)
2024 {
2025 if (buffers[1] >= 2)
2026 new_devs->dev->info.buffers = buffers[1];
2027 else
2028 new_devs->dev->info.buffers = 2;
2029 if (bufsize[1] > 0)
2030 new_devs->dev->info.wanted_bufsize = bufsize[1];
2031 else
2032 new_devs->dev->info.wanted_bufsize = DEFAULT_BUFSIZE;
2033 if (queued_reads[1] >= 0)
2034 new_devs->dev->info.queued_reads = queued_reads[1];
2035 else
2036 new_devs->dev->info.queued_reads = 0;
2037 if (line[strlen(line)-1] == '\n')
2038 line[strlen(line)-1] = 0;
2039 np = new_devs->next;
2040 free(new_devs);
2041 new_devs = np;
2042 }
2043 while (new_dev_pool)
2044 {
2045 np = new_dev_pool->next;
2046 free(new_dev_pool);
2047 new_dev_pool = np;
2048 }
2049 fclose(fp);
2050 DBG (10, ">>\n");
2051 return (SANE_STATUS_GOOD);
2052 }
2053
2054 void
sane_exit(void)2055 sane_exit (void)
2056 {
2057 NEC_Device *dev, *next;
2058 DBG (10, "<< sane_exit ");
2059
2060 for (dev = first_dev; dev; dev = next)
2061 {
2062 next = dev->next;
2063 free ((void *) dev->sane.name);
2064 free ((void *) dev->sane.model);
2065 free (dev);
2066 }
2067 first_dev = 0;
2068
2069 if (devlist)
2070 free(devlist);
2071
2072 DBG (10, ">>\n");
2073 }
2074
2075 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)2076 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
2077 {
2078 NEC_Device *dev;
2079 int i;
2080 DBG (10, "<< sane_get_devices ");
2081
2082 (void) local_only; /* silence compilation warnings */
2083
2084 if (devlist)
2085 free (devlist);
2086 devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
2087 if (!devlist)
2088 return (SANE_STATUS_NO_MEM);
2089
2090 i = 0;
2091 for (dev = first_dev; dev; dev = dev->next)
2092 devlist[i++] = &dev->sane;
2093 devlist[i++] = 0;
2094
2095 *device_list = devlist;
2096
2097 DBG (10, ">>\n");
2098 return SANE_STATUS_GOOD;
2099 }
2100
2101 SANE_Status
sane_open(SANE_String_Const devnam, SANE_Handle * handle)2102 sane_open (SANE_String_Const devnam, SANE_Handle * handle)
2103 {
2104 SANE_Status status;
2105 NEC_Device *dev;
2106 NEC_Scanner *s;
2107 #ifdef USE_CUSTOM_GAMMA
2108 int i, j;
2109 #endif
2110
2111 DBG (10, "<< sane_open ");
2112
2113 if (devnam[0])
2114 {
2115 for (dev = first_dev; dev; dev = dev->next)
2116 {
2117 if (strcmp (dev->sane.name, devnam) == 0)
2118 break;
2119 }
2120
2121 if (!dev)
2122 {
2123 status = attach (devnam, &dev);
2124 if (status != SANE_STATUS_GOOD)
2125 return (status);
2126 }
2127 }
2128 else
2129 {
2130 dev = first_dev;
2131 }
2132
2133 if (!dev)
2134 return (SANE_STATUS_INVAL);
2135
2136 s = malloc (sizeof (*s));
2137 if (!s)
2138 return SANE_STATUS_NO_MEM;
2139 memset (s, 0, sizeof (*s));
2140
2141 s->fd = -1;
2142 s->dev = dev;
2143
2144 s->buffer = 0;
2145 #ifdef USE_CUSTOM_GAMMA
2146 for (i = 0; i < 4; ++i)
2147 for (j = 0; j < 256; ++j)
2148 s->gamma_table[i][j] = j;
2149 #endif
2150 status = init_options (s);
2151 if (status != SANE_STATUS_GOOD)
2152 {
2153 /* xxx clean up mallocs */
2154 return status;
2155 }
2156
2157 s->next = first_handle;
2158 first_handle = s;
2159
2160 *handle = s;
2161
2162 DBG (10, ">>\n");
2163 return SANE_STATUS_GOOD;
2164 }
2165
2166 void
sane_close(SANE_Handle handle)2167 sane_close (SANE_Handle handle)
2168 {
2169 NEC_Scanner *s = (NEC_Scanner *) handle;
2170 DBG (10, "<< sane_close ");
2171
2172 if (s->fd != -1)
2173 sanei_scsi_close (s->fd);
2174 #ifdef USE_FORK
2175 {
2176 struct shmid_ds ds;
2177 if (s->shmid != -1)
2178 shmctl(s->shmid, IPC_RMID, &ds);
2179 }
2180 #endif
2181 if (s->buffer)
2182 free(s->buffer);
2183 free (s);
2184
2185 DBG (10, ">>\n");
2186 }
2187
2188 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)2189 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
2190 {
2191 NEC_Scanner *s = handle;
2192 DBG (10, "<< sane_get_option_descriptor ");
2193
2194 if ((unsigned) option >= NUM_OPTIONS)
2195 return (0);
2196
2197 DBG (10, ">>\n");
2198 return (s->opt + option);
2199 }
2200
2201 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int * info)2202 sane_control_option (SANE_Handle handle, SANE_Int option,
2203 SANE_Action action, void *val, SANE_Int * info)
2204 {
2205 NEC_Scanner *s = handle;
2206 SANE_Status status;
2207 #ifdef USE_CUSTOM_GAMMA
2208 SANE_Word w, cap;
2209 #else
2210 SANE_Word cap;
2211 #endif
2212 int range_index;
2213 DBG (10, "<< sane_control_option %i", option);
2214
2215 if (info)
2216 *info = 0;
2217
2218 if (s->scanning)
2219 return (SANE_STATUS_DEVICE_BUSY);
2220 if (option >= NUM_OPTIONS)
2221 return (SANE_STATUS_INVAL);
2222
2223 cap = s->opt[option].cap;
2224 if (!SANE_OPTION_IS_ACTIVE (cap))
2225 return (SANE_STATUS_INVAL);
2226
2227 if (action == SANE_ACTION_GET_VALUE)
2228 {
2229 switch (option)
2230 {
2231 /* word options: */
2232 case OPT_RESOLUTION:
2233 case OPT_TL_X:
2234 case OPT_TL_Y:
2235 case OPT_BR_X:
2236 case OPT_BR_Y:
2237 case OPT_NUM_OPTS:
2238 case OPT_THRESHOLD:
2239 case OPT_TINT:
2240 case OPT_COLOR:
2241 #ifdef USE_COLOR_THRESHOLD
2242 case OPT_THRESHOLD_R:
2243 case OPT_THRESHOLD_G:
2244 case OPT_THRESHOLD_B:
2245 #endif
2246 case OPT_OR:
2247 case OPT_NR:
2248 case OPT_EDGE:
2249 case OPT_PREVIEW:
2250 #ifdef USE_CUSTOM_GAMMA
2251 case OPT_CUSTOM_GAMMA:
2252 #endif
2253 *(SANE_Word *) val = s->val[option].w;
2254 #if 0 /* here, values are read; reload should not be necessary */
2255 if (info)
2256 *info |= SANE_INFO_RELOAD_PARAMS;
2257 #endif
2258 return (SANE_STATUS_GOOD);
2259
2260 #ifdef USE_CUSTOM_GAMMA
2261 /* word-array options: */
2262 case OPT_GAMMA_VECTOR:
2263 case OPT_GAMMA_VECTOR_R:
2264 case OPT_GAMMA_VECTOR_G:
2265 case OPT_GAMMA_VECTOR_B:
2266 memcpy (val, s->val[option].wa, s->opt[option].size);
2267 return SANE_STATUS_GOOD;
2268 #endif
2269
2270 /* string options: */
2271 case OPT_MODE:
2272 case OPT_HALFTONE:
2273 case OPT_PAPER:
2274 case OPT_GAMMA:
2275 #ifdef USE_RESOLUTION_LIST
2276 case OPT_RESOLUTION_LIST:
2277 #endif
2278 case OPT_EDGE_EMPHASIS:
2279 case OPT_LIGHTCOLOR:
2280 case OPT_SCANSOURCE:
2281 strcpy (val, s->val[option].s);
2282 #if 0
2283 if (info)
2284 *info |= SANE_INFO_RELOAD_PARAMS;
2285 #endif
2286
2287 return (SANE_STATUS_GOOD);
2288
2289 }
2290 }
2291 else if (action == SANE_ACTION_SET_VALUE)
2292 {
2293 if (!SANE_OPTION_IS_SETTABLE (cap))
2294 return (SANE_STATUS_INVAL);
2295
2296 status = sanei_constrain_value (s->opt + option, val, info);
2297 if (status != SANE_STATUS_GOOD)
2298 return status;
2299
2300 switch (option)
2301 {
2302 /* (mostly) side-effect-free word options: */
2303 case OPT_RESOLUTION:
2304 case OPT_TL_X:
2305 case OPT_TL_Y:
2306 case OPT_BR_X:
2307 case OPT_BR_Y:
2308 if (info && s->val[option].w != *(SANE_Word *) val)
2309 *info |= SANE_INFO_RELOAD_PARAMS;
2310 // fall through
2311 case OPT_NUM_OPTS:
2312 case OPT_THRESHOLD:
2313 /* xxx theoretically, we could use OPT_THRESHOLD in
2314 bi-level color mode to adjust all three other
2315 threshold together. But this would require to set
2316 the bit SANE_INFO_RELOAD_OPTIONS in *info, and that
2317 would unfortunately cause a crash in both xscanimage
2318 and xsane... Therefore, OPT_THRESHOLD is disabled
2319 for bi-level color scan right now.
2320 */
2321 case OPT_TINT:
2322 case OPT_COLOR:
2323 #ifdef USE_COLOR_THRESHOLD
2324 case OPT_THRESHOLD_R:
2325 case OPT_THRESHOLD_G:
2326 case OPT_THRESHOLD_B:
2327 #endif
2328 case OPT_OR:
2329 case OPT_NR:
2330 case OPT_EDGE:
2331 case OPT_PREVIEW:
2332 s->val[option].w = *(SANE_Word *) val;
2333 return (SANE_STATUS_GOOD);
2334
2335 case OPT_MODE:
2336 if (strcmp (val, M_LINEART) == 0)
2337 {
2338 s->opt[OPT_LIGHTCOLOR].cap &= ~SANE_CAP_INACTIVE;
2339 s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
2340 s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE;
2341 s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE;
2342 #ifdef USE_COLOR_THRESHOLD
2343 s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE;
2344 s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE;
2345 s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE;
2346 #endif
2347 if (s->dev->sensedat.model == PCIN500)
2348 s->opt[OPT_HALFTONE].cap &= ~SANE_CAP_INACTIVE;
2349 }
2350 else if (strcmp (val, M_LINEART_COLOR) == 0)
2351 {
2352 s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE;
2353 s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
2354 s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE;
2355 s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE;
2356 #ifdef USE_COLOR_THRESHOLD
2357 s->opt[OPT_THRESHOLD_R].cap &= ~SANE_CAP_INACTIVE;
2358 s->opt[OPT_THRESHOLD_G].cap &= ~SANE_CAP_INACTIVE;
2359 s->opt[OPT_THRESHOLD_B].cap &= ~SANE_CAP_INACTIVE;
2360 #endif
2361 if (s->dev->sensedat.model == PCIN500)
2362 s->opt[OPT_HALFTONE].cap &= ~SANE_CAP_INACTIVE;
2363 }
2364 else if (strcmp (val, M_GRAY) == 0)
2365 {
2366 s->opt[OPT_LIGHTCOLOR].cap &= ~SANE_CAP_INACTIVE;
2367 s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
2368 s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE;
2369 s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE;
2370 #ifdef USE_COLOR_THRESHOLD
2371 s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE;
2372 s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE;
2373 s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE;
2374 #endif
2375 s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE;
2376 }
2377 else
2378 {
2379 s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE;
2380 s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
2381 s->opt[OPT_TINT].cap &= ~SANE_CAP_INACTIVE;
2382 s->opt[OPT_COLOR].cap &= ~SANE_CAP_INACTIVE;
2383 #ifdef USE_COLOR_THRESHOLD
2384 s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE;
2385 s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE;
2386 s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE;
2387 #endif
2388 s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE;
2389 }
2390 #if 0
2391 if ( strcmp (val, M_LINEART) == 0
2392 || strcmp (val, M_GRAY) == 0)
2393 {
2394 s->opt[OPT_LIGHTCOLOR].cap &= ~SANE_CAP_INACTIVE;
2395 }
2396 else
2397 {
2398 s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE;
2399 }
2400 #endif
2401 strcpy(s->val[option].s, val);
2402 #ifdef USE_CUSTOM_GAMMA
2403 set_gamma_caps(s);
2404 #endif
2405 if (info)
2406 *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2407 return (SANE_STATUS_GOOD);
2408
2409 case OPT_GAMMA:
2410 case OPT_HALFTONE:
2411 case OPT_EDGE_EMPHASIS:
2412 case OPT_LIGHTCOLOR:
2413 #if 0
2414 if (s->val[option].s)
2415 free (s->val[option].s);
2416 s->val[option].s = strdup (val);
2417 #endif
2418 strcpy(s->val[option].s, val);
2419 return (SANE_STATUS_GOOD);
2420
2421 case OPT_SCANSOURCE:
2422 if (info && strcmp (s->val[option].s, (SANE_String) val))
2423 *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2424 #if 0
2425 if (s->val[option].s)
2426 free (s->val[option].s);
2427 s->val[option].s = strdup (val);
2428 #endif
2429 strcpy(s->val[option].s, val);
2430 if (strcmp(val, use_fsu) == 0)
2431 range_index = SCAN_WITH_FSU;
2432 else if (strcmp(val, use_adf) == 0)
2433 range_index = SCAN_WITH_ADF;
2434 else
2435 range_index = SCAN_SIMPLE;
2436
2437 s->opt[OPT_TL_X].constraint.range
2438 = &s->dev->info.tl_x_ranges[range_index];
2439 clip_value (&s->opt[OPT_TL_X], &s->val[OPT_TL_X].w);
2440
2441 s->opt[OPT_TL_Y].constraint.range
2442 = &s->dev->info.tl_y_ranges[range_index];
2443 clip_value (&s->opt[OPT_TL_Y], &s->val[OPT_TL_Y].w);
2444
2445 s->opt[OPT_BR_X].constraint.range
2446 = &s->dev->info.br_x_ranges[range_index];
2447 clip_value (&s->opt[OPT_BR_X], &s->val[OPT_BR_X].w);
2448
2449 s->opt[OPT_BR_Y].constraint.range
2450 = &s->dev->info.br_y_ranges[range_index];
2451 clip_value (&s->opt[OPT_BR_Y], &s->val[OPT_BR_Y].w);
2452
2453 return (SANE_STATUS_GOOD);
2454
2455 case OPT_PAPER:
2456 if (info)
2457 *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2458 #if 0
2459 if (s->val[option].s)
2460 free (s->val[option].s);
2461 s->val[option].s = strdup (val);
2462 #endif
2463 strcpy(s->val[option].s, val);
2464 s->val[OPT_TL_X].w = SANE_FIX(0);
2465 s->val[OPT_TL_Y].w = SANE_FIX(0);
2466 if (strcmp (s->val[option].s, "A3") == 0){
2467 s->val[OPT_BR_X].w = SANE_FIX(297);
2468 s->val[OPT_BR_Y].w = SANE_FIX(420);
2469 }else if (strcmp (s->val[option].s, "A4") == 0){
2470 s->val[OPT_BR_X].w = SANE_FIX(210);
2471 s->val[OPT_BR_Y].w = SANE_FIX(297);
2472 }else if (strcmp (s->val[option].s, "A5") == 0){
2473 s->val[OPT_BR_X].w = SANE_FIX(148.5);
2474 s->val[OPT_BR_Y].w = SANE_FIX(210);
2475 }else if (strcmp (s->val[option].s, "A6") == 0){
2476 s->val[OPT_BR_X].w = SANE_FIX(105);
2477 s->val[OPT_BR_Y].w = SANE_FIX(148.5);
2478 }else if (strcmp (s->val[option].s, "B4") == 0){
2479 s->val[OPT_BR_X].w = SANE_FIX(250);
2480 s->val[OPT_BR_Y].w = SANE_FIX(353);
2481 }else if (strcmp (s->val[option].s, "B5") == 0){
2482 s->val[OPT_BR_X].w = SANE_FIX(182);
2483 s->val[OPT_BR_Y].w = SANE_FIX(257);
2484 }else if (strcmp (s->val[option].s, W_LETTER) == 0){
2485 s->val[OPT_BR_X].w = SANE_FIX(279.4);
2486 s->val[OPT_BR_Y].w = SANE_FIX(431.8);
2487 }else if (strcmp (s->val[option].s, "Legal") == 0){
2488 s->val[OPT_BR_X].w = SANE_FIX(215.9);
2489 s->val[OPT_BR_Y].w = SANE_FIX(355.6);
2490 }else if (strcmp (s->val[option].s, "Letter") == 0){
2491 s->val[OPT_BR_X].w = SANE_FIX(215.9);
2492 s->val[OPT_BR_Y].w = SANE_FIX(279.4);
2493 }else if (strcmp (s->val[option].s, INVOICE) == 0){
2494 s->val[OPT_BR_X].w = SANE_FIX(215.9);
2495 s->val[OPT_BR_Y].w = SANE_FIX(139.7);
2496 }else{
2497 }
2498 return (SANE_STATUS_GOOD);
2499
2500 #ifdef USE_RESOLUTION_LIST
2501 case OPT_RESOLUTION_LIST:
2502 if (info)
2503 *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2504 #if 0
2505 if (s->val[option].s)
2506 free (s->val[option].s);
2507 s->val[option].s = strdup (val);
2508 #endif
2509 for (i = 0; s->opt[OPT_RESOLUTION_LIST].constraint.string_list[i]; i++) {
2510 if (strcmp (val,
2511 s->opt[OPT_RESOLUTION_LIST].constraint.string_list[i]) == 0){
2512 s->val[OPT_RESOLUTION].w
2513 = atoi(s->opt[OPT_RESOLUTION_LIST].constraint.string_list[i]);
2514 if (info)
2515 *info |= SANE_INFO_RELOAD_PARAMS;
2516 break;
2517 }
2518 }
2519 return (SANE_STATUS_GOOD);
2520 #endif
2521
2522 #ifdef USE_CUSTOM_GAMMA
2523 /* side-effect-free word-array options: */
2524 case OPT_GAMMA_VECTOR:
2525 case OPT_GAMMA_VECTOR_R:
2526 case OPT_GAMMA_VECTOR_G:
2527 case OPT_GAMMA_VECTOR_B:
2528 memcpy (s->val[option].wa, val, s->opt[option].size);
2529 return SANE_STATUS_GOOD;
2530
2531 case OPT_CUSTOM_GAMMA:
2532 w = *(SANE_Word *) val;
2533
2534 if (w == s->val[OPT_CUSTOM_GAMMA].w)
2535 return SANE_STATUS_GOOD; /* no change */
2536
2537 if (info)
2538 *info |= SANE_INFO_RELOAD_OPTIONS;
2539 s->val[OPT_CUSTOM_GAMMA].w = w;
2540 set_gamma_caps(s);
2541 return SANE_STATUS_GOOD;
2542 #endif
2543 }
2544 }
2545
2546 DBG (10, ">>\n");
2547 return (SANE_STATUS_INVAL);
2548 }
2549
2550 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)2551 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
2552 {
2553 int width, length, res;
2554 const char *mode;
2555 NEC_Scanner *s = handle;
2556 DBG (10, "<< sane_get_parameters ");
2557
2558 res = s->val[OPT_RESOLUTION].w * s->dev->info.res_range.quant;
2559 if (!s->scanning)
2560 {
2561 /* make best-effort guess at what parameters will look like once
2562 scanning starts. */
2563 memset (&s->params, 0, sizeof (s->params));
2564
2565 width = MM_TO_PIX( SANE_UNFIX(s->val[OPT_BR_X].w)
2566 - SANE_UNFIX(s->val[OPT_TL_X].w),
2567 s->dev->info.mud);
2568 length = MM_TO_PIX( SANE_UNFIX(s->val[OPT_BR_Y].w)
2569 - SANE_UNFIX(s->val[OPT_TL_Y].w),
2570 s->dev->info.mud);
2571
2572 s->width = width;
2573 s->length = length;
2574 s->params.pixels_per_line = width * res / s->dev->info.mud;
2575 s->params.lines = length * res / s->dev->info.mud;
2576
2577 if (s->dev->sensedat.model == PCIN500)
2578 {
2579 s->params.pixels_per_line += 1;
2580 s->params.lines += 1;
2581 }
2582 s->unscanned_lines = s->params.lines;
2583 }
2584 #if 0
2585 else
2586 {
2587 buffer_status bs;
2588 SANE_Status status;
2589 size_t len = sizeof (buffer_status);
2590 status = get_data_buffer_status (s->fd, &bs, &len);
2591 DBG (11, "<< get_data_buffer_status ");
2592
2593 if (status != SANE_STATUS_GOOD)
2594 {
2595 do_cancel(s);
2596 return (status);
2597 }
2598 DBG (11, ">>\n ");
2599 {
2600 #ifdef DEBUG_NEC
2601 int i;
2602 u_char *buf = &bs;
2603 DBG(11, "get data buffer status(debug):\n");
2604 for (i = 0; i < len; i += 16)
2605 {
2606 DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x \n",
2607 buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7], buf[i+8],
2608 buf[i+9], buf[i+10], buf[i+11]);
2609 }
2610 #endif
2611 }
2612 }
2613 #endif
2614 res = s->val[OPT_RESOLUTION].w * s->dev->info.res_range.quant;
2615
2616 mode = s->val[OPT_MODE].s;
2617
2618 if (strcmp (mode, M_LINEART) == 0)
2619 {
2620 s->params.format = SANE_FRAME_GRAY;
2621 s->params.bytes_per_line = (s->params.pixels_per_line + 7) / 8;
2622 s->params.depth = 1;
2623 s->modes = MODES_LINEART;
2624 }
2625 else if (strcmp (mode, M_GRAY) == 0)
2626 {
2627 s->params.format = SANE_FRAME_GRAY;
2628 s->params.bytes_per_line = s->params.pixels_per_line;
2629 s->params.depth = 8;
2630 s->modes = MODES_GRAY;
2631 }
2632 else if (strcmp (mode, M_LINEART_COLOR) == 0)
2633 {
2634 s->params.format = SANE_FRAME_RGB;
2635 s->params.bytes_per_line = 3 * (s->params.pixels_per_line + 7) / 8;
2636 s->params.depth = 8;
2637 s->modes = MODES_LINEART_COLOR;
2638 }
2639 else
2640 {
2641 s->params.format = SANE_FRAME_RGB;
2642 s->params.bytes_per_line = 3 * s->params.pixels_per_line;
2643 s->params.depth = 8;
2644 s->modes = MODES_COLOR;
2645 }
2646 s->params.last_frame = SANE_TRUE;
2647
2648 if (params)
2649 *params = s->params;
2650
2651 DBG (10, ">>\n");
2652 return (SANE_STATUS_GOOD);
2653 }
2654
2655 #ifdef USE_CUSTOM_GAMMA
2656
2657 static int
sprint_gamma(Option_Value val, SANE_Byte *dst)2658 sprint_gamma(Option_Value val, SANE_Byte *dst)
2659 {
2660 int i;
2661 SANE_Byte *p = dst;
2662
2663 p += sprintf((char *) p, "%i", val.wa[0]);
2664 for (i = 1; i < 256; i++)
2665 p += sprintf((char *) p, ",%i", val.wa[i] > 255 ? 255 : val.wa[i]);
2666 return p - dst;
2667 }
2668
2669 static SANE_Status
send_ascii_gamma_tables(NEC_Scanner *s)2670 send_ascii_gamma_tables (NEC_Scanner *s)
2671 {
2672 SANE_Status status;
2673 int i;
2674
2675 DBG(11, "<< send_ascii_gamma_tables ");
2676
2677 /* we need: 4 bytes for each gamma value (3 digits + delimiter)
2678 + 10 bytes for the command header
2679 i.e. 4 * 4 * 256 + 10 = 4106 bytes
2680 */
2681
2682 if (s->dev->info.bufsize < 4106)
2683 return SANE_STATUS_NO_MEM;
2684
2685 memset(s->buffer, 0, 4106);
2686
2687 i = sprint_gamma(s->val[OPT_GAMMA_VECTOR_R], &s->buffer[10]);
2688 s->buffer[10+i++] = '/';
2689 i += sprint_gamma(s->val[OPT_GAMMA_VECTOR_G], &s->buffer[10+i]);
2690 s->buffer[10+i++] = '/';
2691 i += sprint_gamma(s->val[OPT_GAMMA_VECTOR_B], &s->buffer[10+i]);
2692 s->buffer[10+i++] = '/';
2693 i += sprint_gamma(s->val[OPT_GAMMA_VECTOR], &s->buffer[10+i]);
2694
2695 DBG(12, "%s\n", &s->buffer[10]);
2696
2697 s->buffer[0] = SEND;
2698 s->buffer[2] = 0x03;
2699 s->buffer[7] = i >> 8;
2700 s->buffer[8] = i & 0xff;
2701
2702 wait_ready(s->fd);
2703 status = sanei_scsi_cmd (s->fd, s->buffer, i+10, 0, 0);
2704
2705 DBG(11, ">>\n");
2706
2707 return status;
2708 }
2709 #endif
2710
2711 static SANE_Status
send_binary_g_table(NEC_Scanner *s, SANE_Word *a, int dtq)2712 send_binary_g_table(NEC_Scanner *s, SANE_Word *a, int dtq)
2713 {
2714 SANE_Status status;
2715 unsigned int i, j;
2716
2717 (void) dtq; /* silence compilation warnings */
2718
2719 DBG(11, "<< send_binary_g_table\n");
2720
2721 i = 256;
2722 if (s->dev->info.bufsize < i)
2723 return SANE_STATUS_NO_MEM;
2724 memset(s->buffer, 0, i+10);
2725
2726 s->buffer[0] = SEND;
2727 s->buffer[2] = 0x03;
2728 s->buffer[7] = i >> 8;
2729 s->buffer[8] = i & 0xff;
2730
2731 for (i = 0; i < 256; i++)
2732 {
2733 s->buffer[i+11] = a[i&0xff] & 0xff;
2734 }
2735
2736 for (j = 0; j < 256; j += 16)
2737 {
2738 DBG(11, "%02x %02x %02x %02x %02x %02x %02x %02x "
2739 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
2740 a[j ], a[j+1], a[j+2], a[j+3],
2741 a[j+4], a[j+5], a[j+6], a[j+7],
2742 a[j+8], a[j+9], a[j+10], a[j+11],
2743 a[j+12], a[j+13], a[j+14], a[j+15]);
2744 }
2745 DBG(12, "transfer length = %d\n", i);
2746 DBG(12, "buffer[7] = %d\n", s->buffer[7]);
2747 DBG(12, "buffer[8] = %d\n", s->buffer[8]);
2748
2749 /* wait_ready(s->fd); */
2750 status = sanei_scsi_cmd (s->fd, s->buffer, i+10, 0, 0);
2751
2752 DBG(11, ">>\n");
2753
2754 return status;
2755 }
2756
2757 #ifdef USE_CUSTOM_GAMMA
2758 static SANE_Status
send_binary_gamma_tables(NEC_Scanner *s)2759 send_binary_gamma_tables (NEC_Scanner *s)
2760 {
2761 SANE_Status status;
2762
2763 status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR].wa, 0x10);
2764 if (status != SANE_STATUS_GOOD)
2765 return status;
2766 DBG(11, "send_binary_gamma_tables\n");
2767 #if 0
2768 status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR_R].wa, 0x11);
2769 if (status != SANE_STATUS_GOOD)
2770 return status;
2771
2772 status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR_G].wa, 0x12);
2773 if (status != SANE_STATUS_GOOD)
2774 return status;
2775
2776 status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR_B].wa, 0x13);
2777 #endif
2778 return status;
2779 }
2780
2781 static SANE_Status
send_gamma_tables(NEC_Scanner *s)2782 send_gamma_tables (NEC_Scanner *s)
2783 {
2784 if (s->dev->sensedat.model == PCIN500)
2785 {
2786 return send_binary_gamma_tables(s);
2787 }
2788 else
2789 {
2790 return send_ascii_gamma_tables(s);
2791 }
2792
2793 }
2794 #endif
2795
2796 #ifdef USE_COLOR_THRESHOLD
2797 /* not used? */
2798 #if 0
2799 static SANE_Status
2800 send_threshold_data(NEC_Scanner *s)
2801 {
2802 SANE_Status status;
2803 SANE_Byte cmd[26] = {SEND, 0, 0x82, 0, 0, 0, 0, 0, 0, 0};
2804 int len;
2805
2806 memset(cmd, 0, sizeof(cmd));
2807 /* maximum string length: 3 bytes for each number (they are
2808 restricted to the range 0..255), 3 '/' and the null-byte,
2809 total: 16 bytes.
2810 */
2811 len = sprintf((char *) &cmd[10], "%i/%i/%i/%i",
2812 s->val[OPT_THRESHOLD_R].w,
2813 s->val[OPT_THRESHOLD_G].w,
2814 s->val[OPT_THRESHOLD_B].w,
2815 s->val[OPT_THRESHOLD].w);
2816 cmd[8] = len;
2817
2818 wait_ready(s->fd);
2819 status = sanei_scsi_cmd(s->fd, cmd, len + 10, 0, 0);
2820 return status;
2821 }
2822 #endif
2823 #endif
2824
2825 SANE_Status
sane_start(SANE_Handle handle)2826 sane_start (SANE_Handle handle)
2827 {
2828 char *mode, *halftone, *gamma, *edge, *lightcolor, *adf_fsu;
2829 NEC_Scanner *s = handle;
2830 SANE_Status status;
2831 size_t buf_size;
2832 window_param wp;
2833
2834 DBG (10, "<< sane_start ");
2835
2836 /* First make sure we have a current parameter set. Some of the
2837 parameters will be overwritten below, but that's OK. */
2838 status = sane_get_parameters (s, 0);
2839 if (status != SANE_STATUS_GOOD)
2840 return status;
2841
2842 s->dev->sensedat.complain_on_adf_error = 1;
2843
2844 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
2845 s->dev->info.bufsize = s->dev->info.wanted_bufsize;
2846 if (s->dev->info.bufsize < 32 * 1024)
2847 s->dev->info.bufsize = 32 * 1024;
2848 {
2849 int bsize = s->dev->info.bufsize;
2850 status = sanei_scsi_open_extended (s->dev->sane.name, &s->fd,
2851 &sense_handler, &s->dev->sensedat, &bsize);
2852 s->dev->info.bufsize = bsize;
2853 }
2854
2855 if (status != SANE_STATUS_GOOD)
2856 {
2857 DBG (1, "open of %s failed: %s\n",
2858 s->dev->sane.name, sane_strstatus (status));
2859 return (status);
2860 }
2861
2862 /* make sure that we got at least 32 kB. Even then, the scan will be
2863 awfully slow.
2864
2865 */
2866 if (s->dev->info.bufsize < 32 * 1024)
2867 {
2868 sanei_scsi_close(s->fd);
2869 s->fd = -1;
2870 return SANE_STATUS_NO_MEM;
2871 }
2872 #else
2873 status = sanei_scsi_open(s->dev->sane.name, &s->fd, &sense_handler,
2874 &s->dev->sensedat);
2875 if (s->dev->info.wanted_bufsize < sanei_scsi_max_request_size)
2876 s->dev->info.bufsize = s->dev->info.wanted_bufsize;
2877 else
2878 s->dev->info.bufsize = sanei_scsi_max_request_size;
2879
2880 if (status != SANE_STATUS_GOOD)
2881 {
2882 DBG (1, "open of %s failed: %s\n",
2883 s->dev->sane.name, sane_strstatus (status));
2884 return (status);
2885 }
2886 #endif
2887
2888 s->buffer = malloc(s->dev->info.bufsize);
2889 if (!s->buffer) {
2890 sanei_scsi_close(s->fd);
2891 s->fd = -1;
2892 free(s);
2893 return SANE_STATUS_NO_MEM;
2894 }
2895
2896 #ifdef USE_FORK
2897 {
2898 struct shmid_ds ds;
2899 size_t n;
2900
2901 s->shmid = shmget(IPC_PRIVATE,
2902 sizeof(NEC_rdr_ctl)
2903 + s->dev->info.buffers *
2904 (sizeof(NEC_shmem_ctl) + s->dev->info.bufsize),
2905 IPC_CREAT | 0600);
2906 if (s->shmid == -1)
2907 {
2908 free(s->buffer);
2909 s->buffer = 0;
2910 sanei_scsi_close(s->fd);
2911 s->fd = -1;
2912 return SANE_STATUS_NO_MEM;
2913 }
2914 s->rdr_ctl = (NEC_rdr_ctl*) shmat(s->shmid, 0, 0);
2915 if ((int)s->rdr_ctl == -1)
2916 {
2917 shmctl(s->shmid, IPC_RMID, &ds);
2918 free(s->buffer);
2919 s->buffer = 0;
2920 sanei_scsi_close(s->fd);
2921 s->fd = -1;
2922 return SANE_STATUS_NO_MEM;
2923 }
2924
2925 s->rdr_ctl->buf_ctl = (NEC_shmem_ctl*) &s->rdr_ctl[1];
2926 for (n = 0; n < s->dev->info.buffers; n++)
2927 {
2928 s->rdr_ctl->buf_ctl[n].buffer =
2929 (SANE_Byte*) &s->rdr_ctl->buf_ctl[s->dev->info.buffers]
2930 + n * s->dev->info.bufsize;
2931 }
2932 }
2933 #endif /* USE_FORK */
2934
2935 DBG (5, "start: TEST_UNIT_READY\n");
2936 status = test_unit_ready (s->fd);
2937
2938 if (status != SANE_STATUS_GOOD)
2939 {
2940 DBG (1, "TEST UNIT READY failed: %s\n", sane_strstatus (status));
2941 sanei_scsi_close (s->fd);
2942 s->fd = -1;
2943 return (status);
2944 }
2945
2946 DBG (3, "start: sending MODE SELECT\n");
2947 status = mode_select_mud (s->fd, s->dev->info.mud);
2948 if (status != SANE_STATUS_GOOD)
2949 {
2950 DBG (1, "start: MODE_SELECT6 failed\n");
2951 sanei_scsi_close (s->fd);
2952 s->fd = -1;
2953 return (status);
2954 }
2955
2956 mode = s->val[OPT_MODE].s;
2957 halftone = s->val[OPT_HALFTONE].s;
2958 gamma = s->val[OPT_GAMMA].s;
2959 edge = s->val[OPT_EDGE_EMPHASIS].s;
2960 lightcolor = s->val[OPT_LIGHTCOLOR].s;
2961 adf_fsu = s->val[OPT_SCANSOURCE].s;
2962
2963 if (s->val[OPT_PREVIEW].w == SANE_FALSE)
2964 {
2965 s->res = s->val[OPT_RESOLUTION].w * s->dev->info.res_range.quant;
2966 }
2967 else
2968 {
2969 s->res = 75;
2970 }
2971 s->ulx = MM_TO_PIX(SANE_UNFIX(s->val[OPT_TL_X].w), s->dev->info.mud);
2972 s->uly = MM_TO_PIX(SANE_UNFIX(s->val[OPT_TL_Y].w), s->dev->info.mud);
2973 s->threshold = s->val[OPT_THRESHOLD].w;
2974
2975 if (strcmp (mode, M_LINEART_COLOR) == 0)
2976 s->bpp = 1;
2977 else
2978 s->bpp = s->params.depth;
2979
2980 s->adf_fsu_mode = SCAN_SIMPLE; /* default: scan without ADF and FSU */
2981
2982 if (strcmp(adf_fsu, use_fsu) == 0)
2983 s->adf_fsu_mode = SCAN_WITH_FSU;
2984 else if (strcmp(adf_fsu, use_adf) == 0)
2985 s->adf_fsu_mode = SCAN_WITH_ADF;
2986 else if (strcmp(adf_fsu, use_adf) == 0)
2987 s->adf_fsu_mode = SCAN_SIMPLE;
2988
2989 /* halftone must not set to be zero PC-IN500 */
2990 s->halftone = 0x01;
2991 if (strcmp (mode, M_LINEART) == 0)
2992 {
2993 s->reverse = 0;
2994 s->image_composition = 1;
2995 if (strcmp(halftone, M_BILEVEL) == 0)
2996 {
2997 s->image_composition = 0;
2998 s->halftone = 0x01;
2999 }
3000 else if (strcmp(halftone, M_DITHER1) == 0)
3001 s->halftone = 0x01;
3002 else if (strcmp(halftone, M_DITHER2) == 0)
3003 s->halftone = 0x10;
3004 else if (strcmp(halftone, M_DITHER3) == 0)
3005 s->halftone = 0x20;
3006 }
3007 else if (strcmp (mode, M_GRAY) == 0)
3008 {
3009 s->image_composition = 2;
3010 s->reverse = 1;
3011 }
3012 else if (strcmp (mode, M_LINEART_COLOR) == 0)
3013 {
3014 s->reverse = 1;
3015 s->image_composition = 4;
3016 if (strcmp(halftone, M_BILEVEL) == 0)
3017 {
3018 s->image_composition = 3;
3019 s->halftone = 0x01;
3020 }
3021 else if (strcmp(halftone, M_DITHER1) == 0)
3022 s->halftone = 0x01;
3023 else if (strcmp(halftone, M_DITHER2) == 0)
3024 s->halftone = 0x10;
3025 else if (strcmp(halftone, M_DITHER3) == 0)
3026 s->halftone = 0x20;
3027 }
3028 else if (strcmp (mode, M_COLOR) == 0)
3029 {
3030 s->image_composition = 5;
3031 s->reverse = 1;
3032 }
3033
3034 if (s->dev->sensedat.model == PCIN500)
3035 {
3036 s->or = s->val[OPT_OR].w;
3037 s->nr = s->val[OPT_NR].w;
3038 s->edge = s->val[OPT_EDGE].w;
3039 }
3040 else
3041 {
3042 if (strcmp (edge, EDGE_NONE) == 0)
3043 s->edge = 0;
3044 else if (strcmp (edge, EDGE_MIDDLE) == 0)
3045 s->edge = 1;
3046 else if (strcmp (edge, EDGE_STRONG) == 0)
3047 s->edge = 2;
3048 else if (strcmp (edge, EDGE_BLUR) == 0)
3049 s->edge = 3;
3050 }
3051
3052 s->lightcolor = 3;
3053 if (strcmp(lightcolor, LIGHT_GREEN) == 0)
3054 s->lightcolor = 0;
3055 else if (strcmp(lightcolor, LIGHT_RED) == 0)
3056 s->lightcolor = 1;
3057 else if (strcmp(lightcolor, LIGHT_BLUE) == 0)
3058 s->lightcolor = 2;
3059 else if (strcmp(lightcolor, LIGHT_NONE) == 0)
3060 s->lightcolor = 3;
3061
3062 s->adf_scan = 0;
3063
3064 #ifdef USE_CUSTOM_GAMMA
3065 if (s->val[OPT_CUSTOM_GAMMA].w == SANE_FALSE)
3066 {
3067 #endif
3068 if (s->dev->sensedat.model == PCIN500)
3069 {
3070 if (strcmp (gamma, CRT1))
3071 s->gamma = 1;
3072 else if (strcmp (gamma, CRT2))
3073 s->gamma = 2;
3074 else if (strcmp (gamma, PRINTER1))
3075 s->gamma = 3;
3076 else if (strcmp (gamma, PRINTER2))
3077 s->gamma = 4;
3078 else if (strcmp (gamma, NONE))
3079 s->gamma = 5;
3080 }
3081 #if 0
3082 if (s->dev->sensedat.model != PCIN500)
3083 {
3084 ss.dtc = 0x03;
3085 if (strcmp (gamma, GAMMA10) == 0)
3086 ss.dtq = 0x01;
3087 else
3088 ss.dtq = 0x02;
3089 ss.length = 0;
3090 DBG (5, "start: SEND\n");
3091 status = send (s->fd, &ss);
3092 if (status != SANE_STATUS_GOOD)
3093 {
3094 DBG (1, "send failed: %s\n", sane_strstatus (status));
3095 sanei_scsi_close (s->fd);
3096 s->fd = -1;
3097 return (status);
3098 }
3099 }
3100 else
3101 #else
3102 {
3103 int i;
3104 SANE_Word gtbl[256];
3105 #if 0
3106 if (strcmp (gamma, GAMMA10) == 0)
3107 for (i = 0; i < 256; i++)
3108 gtbl[i] = i;
3109 else
3110 #endif
3111 {
3112 gtbl[0] = 0;
3113 for (i = 1; i < 256; i++)
3114 gtbl[i] = 255 * exp(0.45 * log(i/255.0));
3115 }
3116 send_binary_g_table(s, gtbl, 0x10);
3117 send_binary_g_table(s, gtbl, 0x11);
3118 send_binary_g_table(s, gtbl, 0x12);
3119 send_binary_g_table(s, gtbl, 0x13);
3120 }
3121 #endif /* DEBUG_NEC */
3122 #ifdef USE_CUSTOM_GAMMA
3123 }
3124 else
3125 {
3126 s->gamma = 9;
3127 status = send_gamma_tables(s);
3128 }
3129 if (status != SANE_STATUS_GOOD)
3130 {
3131 sanei_scsi_close (s->fd);
3132 s->fd = -1;
3133 return (status);
3134 }
3135 #endif
3136
3137 s->tint = s->val[OPT_TINT].w;
3138 s->color = s->val[OPT_COLOR].w;
3139
3140 memset (&wp, 0, sizeof (wp));
3141 /* every NEC scanner seems to have a different
3142 window descriptor block...
3143 */
3144 if (s->dev->sensedat.model == PCIN500)
3145 buf_size = sizeof(WDB) + sizeof(WDBX500);
3146 else
3147 buf_size = sizeof(WDB);
3148
3149 wp.wpdh.wdl[0] = buf_size >> 8;
3150 wp.wpdh.wdl[1] = buf_size;
3151 wp.wdb.x_res[0] = s->res >> 8;
3152 wp.wdb.x_res[1] = s->res;
3153 wp.wdb.y_res[0] = s->res >> 8;
3154 wp.wdb.y_res[1] = s->res;
3155 wp.wdb.x_ul[0] = s->ulx >> 24;
3156 wp.wdb.x_ul[1] = s->ulx >> 16;
3157 wp.wdb.x_ul[2] = s->ulx >> 8;
3158 wp.wdb.x_ul[3] = s->ulx;
3159 wp.wdb.y_ul[0] = s->uly >> 24;
3160 wp.wdb.y_ul[1] = s->uly >> 16;
3161 wp.wdb.y_ul[2] = s->uly >> 8;
3162 wp.wdb.y_ul[3] = s->uly;
3163 wp.wdb.width[0] = s->width >> 24;
3164 wp.wdb.width[1] = s->width >> 16;
3165 wp.wdb.width[2] = s->width >> 8;
3166 wp.wdb.width[3] = s->width;
3167 wp.wdb.length[0] = s->length >> 24;
3168 wp.wdb.length[1] = s->length >> 16;
3169 wp.wdb.length[2] = s->length >> 8;
3170 wp.wdb.length[3] = s->length;
3171 wp.wdb.brightness = 0;
3172 wp.wdb.threshold = s->threshold;
3173 wp.wdb.brightness = 128;
3174 wp.wdb.contrast = 128;
3175 wp.wdb.image_composition = s->image_composition;
3176 if (s->image_composition <= 2 || s->image_composition >= 5)
3177 wp.wdb.bpp = s->bpp;
3178 else
3179 wp.wdb.bpp = 1;
3180 wp.wdb.ht_pattern[0] = 0;
3181 wp.wdb.ht_pattern[1] = 0;
3182 if (s->dev->sensedat.model == PCIN500)
3183 wp.wdb.ht_pattern[1] = s->halftone;
3184 wp.wdb.rif_padding = (s->reverse * 128) + 0;
3185
3186 if (s->dev->sensedat.model == PCIN500)
3187 {
3188 wp.wdbx500.data_length = 0x07;
3189 wp.wdbx500.control = 0 | (s->or << 7) | (s->edge << 6) | (s->nr << 5) |
3190 (s->lightcolor << 2);
3191 wp.wdbx500.format = 0;
3192 wp.wdbx500.gamma = s->gamma;
3193 wp.wdbx500.tint = s->tint;
3194 wp.wdbx500.color = s->color;
3195 wp.wdbx500.reserved1 = 0;
3196 wp.wdbx500.reserved2 = 0;
3197 }
3198
3199 DBG (5, "wdl=%d\n", (wp.wpdh.wdl[0] << 8) + wp.wpdh.wdl[1]);
3200 DBG (5, "xres=%d\n", (wp.wdb.x_res[0] << 8) + wp.wdb.x_res[1]);
3201 DBG (5, "yres=%d\n", (wp.wdb.y_res[0] << 8) + wp.wdb.y_res[1]);
3202 DBG (5, "ulx=%d\n", (wp.wdb.x_ul[0] << 24) + (wp.wdb.x_ul[1] << 16) +
3203 (wp.wdb.x_ul[2] << 8) + wp.wdb.x_ul[3]);
3204 DBG (5, "uly=%d\n", (wp.wdb.y_ul[0] << 24) + (wp.wdb.y_ul[1] << 16) +
3205 (wp.wdb.y_ul[2] << 8) + wp.wdb.y_ul[3]);
3206 DBG (5, "width=%d\n", (wp.wdb.width[0] << 8) + (wp.wdb.width[1] << 16) +
3207 (wp.wdb.width[2] << 8) + wp.wdb.width[3]);
3208 DBG (5, "length=%d\n", (wp.wdb.length[0] << 16) + (wp.wdb.length[1] << 16) +
3209 (wp.wdb.length[2] << 8) + wp.wdb.length[3]);
3210
3211 DBG (5, "threshold=%d\n", wp.wdb.threshold);
3212 DBG (5, "image_composition=%d\n", wp.wdb.image_composition);
3213 DBG (5, "bpp=%d\n", wp.wdb.bpp);
3214 DBG (5, "rif_padding=%d\n", wp.wdb.rif_padding);
3215
3216 #ifdef DEBUG_NEC
3217 {
3218 window_param foo;
3219 size_t len = buf_size;
3220 len += sizeof(WPDH);
3221 DBG (5, "start: GET WINDOW\n");
3222 status = get_window (s->fd, &foo, &len);
3223 if (status != SANE_STATUS_GOOD)
3224 {
3225 DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status));
3226 sanei_scsi_close (s->fd);
3227 s->fd = -1;
3228 return (status);
3229 }
3230 #if 1
3231 {
3232 unsigned char *p = (unsigned char*) &foo;
3233 int i;
3234 DBG(11, "get window(debug):\n");
3235 for (i = 0; i < len; i += 16)
3236 {
3237 DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n",
3238 p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8],
3239 p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]);
3240 }
3241 }
3242 #endif
3243 foo.wpdh.wpdh[1] = 0;
3244 status = set_window (s->fd, &foo, len);
3245 if (status != SANE_STATUS_GOOD)
3246 {
3247 DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status));
3248 sanei_scsi_close (s->fd);
3249 s->fd = -1;
3250 return (status);
3251 }
3252 #if 1
3253 {
3254 unsigned char *p = (unsigned char*) &foo;
3255 int i;
3256 DBG(11, "set window(debug):\n");
3257 for (i = 0; i < len; i += 16)
3258 {
3259 DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n",
3260 p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8],
3261 p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]);
3262 }
3263 }
3264 #endif
3265 }
3266 #endif /* debug_nec */
3267
3268 #ifdef DEBUG_NEC
3269 {
3270 unsigned char *p = (unsigned char*) ℘
3271 int i;
3272 DBG(11, "set window(debug):\n");
3273 for (i = 0; i < sizeof(wp.wdb) + sizeof(wp.wdbx500); i += 16)
3274 {
3275 DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n",
3276 p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8],
3277 p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]);
3278 }
3279 }
3280 #endif /* debug_nec */
3281
3282 buf_size += sizeof(WPDH);
3283 DBG (5, "start: SET WINDOW\n");
3284 status = set_window (s->fd, &wp, buf_size);
3285 if (status != SANE_STATUS_GOOD)
3286 {
3287 DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status));
3288 sanei_scsi_close (s->fd);
3289 s->fd = -1;
3290 return (status);
3291 }
3292
3293 memset (&wp, 0, buf_size);
3294 DBG (5, "start: GET WINDOW\n");
3295 status = get_window (s->fd, &wp, &buf_size);
3296 if (status != SANE_STATUS_GOOD)
3297 {
3298 DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status));
3299 sanei_scsi_close (s->fd);
3300 s->fd = -1;
3301 return (status);
3302 }
3303 #ifdef DEBUG_NEC
3304 {
3305 unsigned char *p = (unsigned char*) ℘
3306 int i;
3307 DBG(11, "get window(debug):\n");
3308 for (i = 0; i < buf_size; i += 16)
3309 {
3310 DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n",
3311 p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8],
3312 p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]);
3313 }
3314 }
3315 #endif
3316 DBG (5, "xres=%d\n", (wp.wdb.x_res[0] << 8) + wp.wdb.x_res[1]);
3317 DBG (5, "yres=%d\n", (wp.wdb.y_res[0] << 8) + wp.wdb.y_res[1]);
3318 DBG (5, "ulx=%d\n", (wp.wdb.x_ul[0] << 24) + (wp.wdb.x_ul[1] << 16) +
3319 (wp.wdb.x_ul[2] << 8) + wp.wdb.x_ul[3]);
3320 DBG (5, "uly=%d\n", (wp.wdb.y_ul[0] << 24) + (wp.wdb.y_ul[1] << 16) +
3321 (wp.wdb.y_ul[2] << 8) + wp.wdb.y_ul[3]);
3322 DBG (5, "width=%d\n", (wp.wdb.width[0] << 24) + (wp.wdb.width[1] << 16) +
3323 (wp.wdb.width[2] << 8) + wp.wdb.width[3]);
3324 DBG (5, "length=%d\n", (wp.wdb.length[0] << 24) + (wp.wdb.length[1] << 16) +
3325 (wp.wdb.length[2] << 8) + wp.wdb.length[3]);
3326 DBG (5, "start: SCAN\n");
3327 s->scanning = SANE_TRUE;
3328 s->busy = SANE_TRUE;
3329 s->cancel = SANE_FALSE;
3330 s->get_params_called = 0;
3331
3332 status = scan (s->fd);
3333 #ifdef DEBUG
3334 {
3335 struct timeval t;
3336 gettimeofday(&t, 0);
3337 DBG(2, "rd: scan started %li.%06li\n", t.tv_sec, t.tv_usec);
3338 }
3339 #endif
3340 if (status != SANE_STATUS_GOOD)
3341 {
3342 DBG (1, "start of scan failed: %s\n", sane_strstatus (status));
3343 sanei_scsi_close (s->fd);
3344 s->fd = -1;
3345 s->busy = SANE_FALSE;
3346 s->cancel = SANE_FALSE;
3347 return (status);
3348 }
3349
3350 /* ask the scanner for the scan size */
3351 /* wait_ready(s->fd); */
3352 #ifdef DEBUG
3353 {
3354 struct timeval t;
3355 gettimeofday(&t, 0);
3356 DBG(2, "rd: wait_ready ok %li.%06li\n", t.tv_sec, t.tv_usec);
3357 }
3358 #endif
3359 sane_get_parameters(s, 0);
3360 #ifdef DEBUG
3361 {
3362 struct timeval t;
3363 gettimeofday(&t, 0);
3364 DBG(2, "rd: get_params ok %li.%06li\n", t.tv_sec, t.tv_usec);
3365 }
3366 #endif
3367 if (strcmp (mode, M_LINEART_COLOR) != 0)
3368 s->bytes_to_read = s->params.bytes_per_line * s->params.lines;
3369 else
3370 {
3371 s->bytes_to_read = s->params.bytes_per_line * s->params.lines;
3372 }
3373
3374 #ifdef USE_FORK
3375 {
3376 size_t i;
3377 for (i = 0; i < s->dev->info.buffers; i++)
3378 s->rdr_ctl->buf_ctl[i].shm_status = SHM_EMPTY;
3379 s->read_buff = 0;
3380 s->rdr_ctl->cancel = 0;
3381 s->rdr_ctl->running = 0;
3382 s->rdr_ctl->status = SANE_STATUS_GOOD;
3383 }
3384 s->reader_pid = fork();
3385 #ifdef DEBUG
3386 {
3387 struct timeval t;
3388 gettimeofday(&t, 0);
3389 DBG(2, "rd: forked %li.%06li %i\n", t.tv_sec, t.tv_usec,
3390 s->reader_pid);
3391 }
3392 #endif
3393 if (s->reader_pid == 0)
3394 {
3395 sigset_t ignore_set;
3396 struct SIGACTION act;
3397
3398 sigfillset (&ignore_set);
3399 sigdelset (&ignore_set, SIGTERM);
3400 sigprocmask (SIG_SETMASK, &ignore_set, 0);
3401
3402 memset (&act, 0, sizeof (act));
3403 sigaction (SIGTERM, &act, 0);
3404
3405 /* don't use exit() since that would run the atexit() handlers... */
3406 _exit (reader_process (s));
3407 }
3408 else if (s->reader_pid == -1)
3409 {
3410 s->busy = SANE_FALSE;
3411 do_cancel(s);
3412 return SANE_STATUS_NO_MEM;
3413 }
3414
3415 #endif /* USE_FORK */
3416
3417
3418 DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, "
3419 "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line,
3420 s->params.lines, (u_long) s->bytes_to_read, s->val[OPT_RESOLUTION].w);
3421
3422 s->busy = SANE_FALSE;
3423 s->buf_used = 0;
3424 s->buf_pos = 0;
3425
3426 if (s->cancel == SANE_TRUE)
3427 {
3428 do_cancel(s);
3429 DBG (10, ">>\n");
3430 return(SANE_STATUS_CANCELLED);
3431 }
3432
3433 DBG (10, ">>\n");
3434 return (SANE_STATUS_GOOD);
3435
3436 }
3437
3438 static SANE_Status
sane_read_direct(SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len, SANE_Int * len)3439 sane_read_direct (SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len,
3440 SANE_Int * len)
3441 {
3442 NEC_Scanner *s = handle;
3443 SANE_Status status;
3444 size_t nread;
3445 DBG (10, "<< sane_read_direct ");
3446
3447 #if 0
3448 {
3449 buffer_status bs;
3450 size_t len = sizeof (buffer_status);
3451 get_data_buffer_status (s->fd, &bs, &len);
3452 DBG (20, "buffer_status: %i ", bs.fdb[0]*256*256 + bs.fdb[1]*256 + bs.fdb[2]);
3453 }
3454 #endif
3455 DBG (20, "remaining: %lu ", (u_long) s->bytes_to_read);
3456 *len = 0;
3457
3458 if (s->bytes_to_read == 0)
3459 {
3460 do_cancel (s);
3461 return (SANE_STATUS_EOF);
3462 }
3463
3464 if (!s->scanning)
3465 return (do_cancel (s));
3466 nread = max_len;
3467 if (nread > s->bytes_to_read)
3468 nread = s->bytes_to_read;
3469 if (nread > s->dev->info.bufsize)
3470 nread = s->dev->info.bufsize;
3471
3472 #ifdef USE_FORK
3473 status = read_data(s, dst_buf, &nread);
3474 #else
3475 #ifdef NOTUSE_PCIN500
3476 wait_ready(s->fd);
3477 #endif
3478 status = read_data (s, dst_buf, &nread);
3479 #endif
3480 if (status != SANE_STATUS_GOOD)
3481 {
3482 do_cancel (s);
3483 return (SANE_STATUS_IO_ERROR);
3484 }
3485 *len = nread;
3486 s->bytes_to_read -= nread;
3487 DBG (20, "remaining: %lu ", (u_long) s->bytes_to_read);
3488
3489 DBG (10, ">>\n");
3490 return (SANE_STATUS_GOOD);
3491 }
3492
3493 static SANE_Status
sane_read_shuffled(SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len, SANE_Int * len, int eight_bit_data)3494 sane_read_shuffled (SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len,
3495 SANE_Int * len, int eight_bit_data)
3496 {
3497 NEC_Scanner *s = handle;
3498 SANE_Status status;
3499 SANE_Byte *dest, *red, *green, *blue, mask;
3500 SANE_Int transfer;
3501 size_t nread, ntest, pixel, max_pixel, line, max_line;
3502 size_t start_input, bytes_per_line_in;
3503 DBG (10, "<< sane_read_shuffled ");
3504
3505 #if 0
3506 {
3507 buffer_status bs;
3508 size_t len = sizeof (buffer_status);
3509 get_data_buffer_status (s->fd, &bs, &len);
3510 DBG (20, "buffer_status: %i ", bs.fdb[0]*256*256 + bs.fdb[1]*256 + bs.fdb[2]);
3511 }
3512 #endif
3513 *len = 0;
3514 if (s->bytes_to_read == 0 && s->buf_pos == s->buf_used)
3515 {
3516 do_cancel (s);
3517 DBG (10, ">>\n");
3518 return (SANE_STATUS_EOF);
3519 }
3520
3521 if (!s->scanning)
3522 {
3523 DBG (10, ">>\n");
3524 return(do_cancel(s));
3525 }
3526
3527 if (s->buf_pos < s->buf_used)
3528 {
3529 transfer = s->buf_used - s->buf_pos;
3530 if (transfer > max_len)
3531 transfer = max_len;
3532
3533 memcpy(dst_buf, &(s->buffer[s->buf_pos]), transfer);
3534 s->buf_pos += transfer;
3535 max_len -= transfer;
3536 *len = transfer;
3537 }
3538
3539 while (max_len > 0 && s->bytes_to_read > 0)
3540 {
3541 if (eight_bit_data)
3542 {
3543 nread = s->dev->info.bufsize / s->params.bytes_per_line - 1;
3544 nread *= s->params.bytes_per_line;
3545 if (nread > s->bytes_to_read)
3546 nread = s->bytes_to_read;
3547 max_line = nread / s->params.bytes_per_line;
3548 start_input = s->params.bytes_per_line;
3549 bytes_per_line_in = s->params.bytes_per_line;
3550 }
3551 else
3552 {
3553 bytes_per_line_in = (s->params.pixels_per_line + 7) / 8;
3554 bytes_per_line_in *= 3;
3555 max_line = s->params.bytes_per_line + bytes_per_line_in;
3556 max_line = s->dev->info.bufsize / max_line;
3557 nread = max_line * bytes_per_line_in;
3558 if (nread > s->bytes_to_read)
3559 {
3560 nread = s->bytes_to_read;
3561 max_line = nread / bytes_per_line_in;
3562 }
3563 start_input = s->dev->info.bufsize - nread;
3564 }
3565 ntest = nread;
3566
3567 #ifdef USE_FORK
3568 status = read_data (s, &(s->buffer[start_input]), &nread);
3569 #else
3570 status = read_data (s, &(s->buffer[start_input]), &nread);
3571 #endif
3572 if (status != SANE_STATUS_GOOD)
3573 {
3574 do_cancel (s);
3575 DBG (10, ">>\n");
3576 return (SANE_STATUS_IO_ERROR);
3577 }
3578
3579 if (nread != ntest)
3580 {
3581 /* if this happens, something is wrong in the input buffer
3582 management...
3583 */
3584 DBG(1, "Warning: could not read an integral number of scan lines\n");
3585 DBG(1, " image will be scrambled\n");
3586 }
3587
3588
3589 s->buf_used = max_line * s->params.bytes_per_line;
3590 s->buf_pos = 0;
3591 s->bytes_to_read -= nread;
3592 dest = s->buffer;
3593 max_pixel = s->params.pixels_per_line;
3594
3595 if (eight_bit_data)
3596 for (line = 1; line <= max_line; line++)
3597 {
3598 red = &(s->buffer[line * s->params.bytes_per_line]);
3599 green = &(red[max_pixel]);
3600 blue = &(green[max_pixel]);
3601 for (pixel = 0; pixel < max_pixel; pixel++)
3602 {
3603 *dest++ = *red++;
3604 *dest++ = *green++;
3605 *dest++ = *blue++;
3606 }
3607 }
3608 else
3609 for (line = 0; line < max_line; line++)
3610 {
3611 red = &(s->buffer[start_input + line * bytes_per_line_in]);
3612 green = &(red[(max_pixel+7)/8]);
3613 blue = &(green[(max_pixel+7)/8]);
3614 mask = 0x80;
3615 for (pixel = 0; pixel < max_pixel; pixel++)
3616 {
3617 *dest++ = (*red & mask) ? 0xff : 0;
3618 *dest++ = (*green & mask) ? 0xff : 0;
3619 *dest++ = (*blue & mask) ? 0xff : 0;
3620 mask = mask >> 1;
3621 if (mask == 0)
3622 {
3623 mask = 0x80;
3624 red++;
3625 green++;
3626 blue++;
3627 }
3628 }
3629 }
3630
3631 transfer = max_len;
3632 if (transfer > s->buf_used)
3633 transfer = s->buf_used;
3634 memcpy(&(dst_buf[*len]), s->buffer, transfer);
3635
3636 max_len -= transfer;
3637 s->buf_pos += transfer;
3638 *len += transfer;
3639 }
3640
3641 if (s->bytes_to_read == 0 && s->buf_pos == s->buf_used)
3642 do_cancel (s);
3643 DBG (10, ">>\n");
3644 return (SANE_STATUS_GOOD);
3645 }
3646
3647 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len, SANE_Int * len)3648 sane_read (SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len,
3649 SANE_Int * len)
3650 {
3651 NEC_Scanner *s = handle;
3652 SANE_Status status;
3653
3654 DBG (10, "<< sane_read ");
3655 s->busy = SANE_TRUE;
3656 if (s->cancel == SANE_TRUE)
3657 {
3658 do_cancel(s);
3659 *len = 0;
3660 return (SANE_STATUS_CANCELLED);
3661 }
3662
3663 if (s->image_composition <= 2)
3664 status = sane_read_direct(handle, dst_buf, max_len, len);
3665 else if (s->image_composition <= 4)
3666 status = sane_read_shuffled(handle, dst_buf, max_len, len, 0);
3667 else if (s->dev->sensedat.model == PCIN500)
3668 status = sane_read_direct(handle, dst_buf, max_len, len);
3669 else
3670 status = sane_read_shuffled(handle, dst_buf, max_len, len, 1);
3671
3672 s->busy = SANE_FALSE;
3673 if (s->cancel == SANE_TRUE)
3674 {
3675 do_cancel(s);
3676 return (SANE_STATUS_CANCELLED);
3677 }
3678
3679 DBG (10, ">> \n");
3680 return (status);
3681 }
3682
3683 void
sane_cancel(SANE_Handle handle)3684 sane_cancel (SANE_Handle handle)
3685 {
3686 NEC_Scanner *s = handle;
3687 DBG (10, "<< sane_cancel ");
3688
3689 s->cancel = SANE_TRUE;
3690 if (s->busy == SANE_FALSE)
3691 do_cancel(s);
3692
3693 DBG (10, ">>\n");
3694 }
3695
3696 SANE_Status
sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)3697 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
3698 {
3699 (void) handle;
3700 (void) non_blocking; /* silence compilation warnings */
3701
3702 DBG (10, "<< sane_set_io_mode");
3703 DBG (10, ">>\n");
3704
3705 return SANE_STATUS_UNSUPPORTED;
3706 }
3707
3708 SANE_Status
sane_get_select_fd(SANE_Handle handle, SANE_Int * fd)3709 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
3710 {
3711 (void) handle;
3712 (void) fd; /* silence compilation warnings */
3713
3714 DBG (10, "<< sane_get_select_fd");
3715 DBG (10, ">>\n");
3716
3717 return SANE_STATUS_UNSUPPORTED;
3718 }
3719