1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 2007 Ilia Sotnikov <hostcc@gmail.com>
3 HP ScanJet 4570c support by Markham Thomas
4 ADF page detection and high DPI fixes by Bernard Badeer
5 scanbd integration by Damiano Scaramuzza and Bernard Badeer
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 is part of a SANE backend for
43 HP ScanJet 4500C/4570C/5500C/5550C/5590/7650 Scanners
44 */
45
46 #include "../include/sane/config.h"
47
48 #include <stdio.h>
49 #include <string.h>
50 #include <unistd.h>
51 #ifdef HAVE_SYS_TYPES_H
52 #include <sys/types.h>
53 #endif
54
55 #include "../include/sane/sane.h"
56 #define BACKEND_NAME hp5590
57 #include "../include/sane/sanei_backend.h"
58 #include "../include/sane/sanei_usb.h"
59 #include "../include/sane/saneopts.h"
60 #include "hp5590_cmds.c"
61 #include "hp5590_low.c"
62 #include "../include/sane/sanei_net.h"
63
64 /* Debug levels */
65 #define DBG_err 0
66 #define DBG_proc 10
67 #define DBG_verbose 20
68 #define DBG_details 30
69
70 #define hp5590_assert(exp) if(!(exp)) { \
71 DBG (DBG_err, "Assertion '%s' failed at %s:%u\n", #exp, __FILE__, __LINE__);\
72 return SANE_STATUS_INVAL; \
73 }
74
75 #define hp5590_assert_void_return(exp) if(!(exp)) { \
76 DBG (DBG_err, "Assertion '%s' failed at %s:%u\n", #exp, __FILE__, __LINE__);\
77 return; \
78 }
79
80 #define MY_MIN(a, b) (((a) < (b)) ? (a) : (b))
81 #define MY_MAX(a, b) (((a) > (b)) ? (a) : (b))
82
83 /* #define HAS_WORKING_COLOR_48 */
84 #define BUILD 8
85 #define USB_TIMEOUT 30 * 1000
86
87 static SANE_Word
88 res_list[] = { 6, 100, 200, 300, 600, 1200, 2400 };
89
90 #define SANE_VALUE_SCAN_SOURCE_FLATBED SANE_I18N("Flatbed")
91 #define SANE_VALUE_SCAN_SOURCE_ADF SANE_I18N("ADF")
92 #define SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX SANE_I18N("ADF Duplex")
93 #define SANE_VALUE_SCAN_SOURCE_TMA_SLIDES SANE_I18N("TMA Slides")
94 #define SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES SANE_I18N("TMA Negatives")
95 static SANE_String_Const
96 sources_list[] = {
97 SANE_VALUE_SCAN_SOURCE_FLATBED,
98 SANE_VALUE_SCAN_SOURCE_ADF,
99 SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX,
100 SANE_VALUE_SCAN_SOURCE_TMA_SLIDES,
101 SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES,
102 NULL
103 };
104
105 #define SANE_VALUE_SCAN_MODE_COLOR_24 SANE_VALUE_SCAN_MODE_COLOR
106 #define SANE_VALUE_SCAN_MODE_COLOR_48 SANE_I18N("Color (48 bits)")
107 #define HAS_WORKING_COLOR_48 1
108
109 #define SANE_NAME_LAMP_TIMEOUT "extend-lamp-timeout"
110 #define SANE_TITLE_LAMP_TIMEOUT SANE_I18N("Extend lamp timeout")
111 #define SANE_DESC_LAMP_TIMEOUT SANE_I18N("Extends lamp timeout (from 15 minutes to 1 hour)")
112 #define SANE_NAME_WAIT_FOR_BUTTON "wait-for-button"
113 #define SANE_TITLE_WAIT_FOR_BUTTON SANE_I18N("Wait for button")
114 #define SANE_DESC_WAIT_FOR_BUTTON SANE_I18N("Waits for button before scanning")
115 #define SANE_NAME_BUTTON_PRESSED "button-pressed"
116 #define SANE_TITLE_BUTTON_PRESSED SANE_I18N("Last button pressed")
117 #define SANE_DESC_BUTTON_PRESSED SANE_I18N("Get ID of last button pressed (read only)")
118 #define SANE_NAME_LCD_COUNTER "counter-value"
119 #define SANE_TITLE_LCD_COUNTER SANE_I18N("LCD counter")
120 #define SANE_DESC_LCD_COUNTER SANE_I18N("Get value of LCD counter (read only)")
121 #define SANE_NAME_COLOR_LED "color-led"
122 #define SANE_TITLE_COLOR_LED SANE_I18N("Color LED indicator")
123 #define SANE_DESC_COLOR_LED SANE_I18N("Get value of LED indicator (read only)")
124 #define SANE_NAME_DOC_IN_ADF "doc-in-adf"
125 #define SANE_TITLE_DOC_IN_ADF SANE_I18N("Document available in ADF")
126 #define SANE_DESC_DOC_IN_ADF SANE_I18N("Get state of document-available indicator in ADF (read only)")
127 #define SANE_NAME_OVERWRITE_EOP_PIXEL "hide-eop-pixel"
128 #define SANE_TITLE_OVERWRITE_EOP_PIXEL SANE_I18N("Hide end-of-page pixel")
129 #define SANE_DESC_OVERWRITE_EOP_PIXEL SANE_I18N("Hide end-of-page indicator pixels and overwrite with neighbor pixels")
130 #define SANE_NAME_TRAILING_LINES_MODE "trailing-lines-mode"
131 #define SANE_TITLE_TRAILING_LINES_MODE SANE_I18N("Filling mode of trailing lines after scan data (ADF)")
132 #define SANE_DESC_TRAILING_LINES_MODE SANE_I18N("raw = raw scan data, last = repeat last scan line, raster = b/w raster, "\
133 "white = white color, black = black color, color = RGB or gray color value")
134 #define SANE_NAME_TRAILING_LINES_COLOR "trailing-lines-color"
135 #define SANE_TITLE_TRAILING_LINES_COLOR SANE_I18N("RGB or gray color value for filling mode 'color'")
136 #define SANE_DESC_TRAILING_LINES_COLOR SANE_I18N("Color value for trailing lines filling mode 'color'. "\
137 "RGB color as r*65536+256*g+b or gray value (default=violet or gray)")
138
139 #define BUTTON_PRESSED_VALUE_COUNT 11
140 #define BUTTON_PRESSED_VALUE_NONE_KEY "none"
141 #define BUTTON_PRESSED_VALUE_POWER_KEY "power"
142 #define BUTTON_PRESSED_VALUE_SCAN_KEY "scan"
143 #define BUTTON_PRESSED_VALUE_COLLECT_KEY "collect"
144 #define BUTTON_PRESSED_VALUE_FILE_KEY "file"
145 #define BUTTON_PRESSED_VALUE_EMAIL_KEY "email"
146 #define BUTTON_PRESSED_VALUE_COPY_KEY "copy"
147 #define BUTTON_PRESSED_VALUE_UP_KEY "up"
148 #define BUTTON_PRESSED_VALUE_DOWN_KEY "down"
149 #define BUTTON_PRESSED_VALUE_MODE_KEY "mode"
150 #define BUTTON_PRESSED_VALUE_CANCEL_KEY "cancel"
151 #define BUTTON_PRESSED_VALUE_MAX_KEY_LEN 32
152 static SANE_String_Const
153 buttonstate_list[] = {
154 BUTTON_PRESSED_VALUE_NONE_KEY,
155 BUTTON_PRESSED_VALUE_POWER_KEY,
156 BUTTON_PRESSED_VALUE_SCAN_KEY,
157 BUTTON_PRESSED_VALUE_COLLECT_KEY,
158 BUTTON_PRESSED_VALUE_FILE_KEY,
159 BUTTON_PRESSED_VALUE_EMAIL_KEY,
160 BUTTON_PRESSED_VALUE_COPY_KEY,
161 BUTTON_PRESSED_VALUE_UP_KEY,
162 BUTTON_PRESSED_VALUE_DOWN_KEY,
163 BUTTON_PRESSED_VALUE_MODE_KEY,
164 BUTTON_PRESSED_VALUE_CANCEL_KEY,
165 NULL
166 };
167
168 #define COLOR_LED_VALUE_COUNT 2
169 #define COLOR_LED_VALUE_COLOR_KEY "color"
170 #define COLOR_LED_VALUE_BLACKWHITE_KEY "black_white"
171 #define COLOR_LED_VALUE_MAX_KEY_LEN 32
172 static SANE_String_Const
173 colorledstate_list[] = {
174 COLOR_LED_VALUE_COLOR_KEY,
175 COLOR_LED_VALUE_BLACKWHITE_KEY,
176 NULL
177 };
178
179 #define LCD_COUNTER_VALUE_MIN 1
180 #define LCD_COUNTER_VALUE_MAX 99
181 #define LCD_COUNTER_VALUE_QUANT 1
182 static SANE_Range
183 lcd_counter_range = {
184 LCD_COUNTER_VALUE_MIN,
185 LCD_COUNTER_VALUE_MAX,
186 LCD_COUNTER_VALUE_QUANT
187 };
188
189 #define TRAILING_LINES_MODE_RAW 0
190 #define TRAILING_LINES_MODE_LAST 1
191 #define TRAILING_LINES_MODE_RASTER 2
192 #define TRAILING_LINES_MODE_WHITE 3
193 #define TRAILING_LINES_MODE_BLACK 4
194 #define TRAILING_LINES_MODE_COLOR 5
195 #define TRAILING_LINES_MODE_VALUE_COUNT 6
196
197 #define TRAILING_LINES_MODE_RAW_KEY "raw"
198 #define TRAILING_LINES_MODE_LAST_KEY "last"
199 #define TRAILING_LINES_MODE_RASTER_KEY "raster"
200 #define TRAILING_LINES_MODE_WHITE_KEY "white"
201 #define TRAILING_LINES_MODE_BLACK_KEY "black"
202 #define TRAILING_LINES_MODE_COLOR_KEY "color"
203 #define TRAILING_LINES_MODE_MAX_KEY_LEN 24
204 static SANE_String_Const
205 trailingmode_list[] = {
206 TRAILING_LINES_MODE_RAW_KEY,
207 TRAILING_LINES_MODE_LAST_KEY,
208 TRAILING_LINES_MODE_RASTER_KEY,
209 TRAILING_LINES_MODE_WHITE_KEY,
210 TRAILING_LINES_MODE_BLACK_KEY,
211 TRAILING_LINES_MODE_COLOR_KEY,
212 NULL
213 };
214
215 #define MAX_SCAN_SOURCE_VALUE_LEN 24
216 #define MAX_SCAN_MODE_VALUE_LEN 24
217
218 static SANE_Range
219 range_x, range_y, range_qual;
220
221 static SANE_String_Const
222 mode_list[] = {
223 SANE_VALUE_SCAN_MODE_COLOR_24,
224 #ifdef HAS_WORKING_COLOR_48
225 SANE_VALUE_SCAN_MODE_COLOR_48,
226 #endif /* HAS_WORKING_COLOR_48 */
227 SANE_VALUE_SCAN_MODE_GRAY,
228 SANE_VALUE_SCAN_MODE_LINEART,
229 NULL
230 };
231
232 enum hp5590_opt_idx {
233 HP5590_OPT_NUM = 0,
234 HP5590_OPT_TL_X,
235 HP5590_OPT_TL_Y,
236 HP5590_OPT_BR_X,
237 HP5590_OPT_BR_Y,
238 HP5590_OPT_MODE,
239 HP5590_OPT_SOURCE,
240 HP5590_OPT_RESOLUTION,
241 HP5590_OPT_LAMP_TIMEOUT,
242 HP5590_OPT_WAIT_FOR_BUTTON,
243 HP5590_OPT_BUTTON_PRESSED,
244 HP5590_OPT_COLOR_LED,
245 HP5590_OPT_LCD_COUNTER,
246 HP5590_OPT_DOC_IN_ADF,
247 HP5590_OPT_PREVIEW,
248 HP5590_OPT_OVERWRITE_EOP_PIXEL,
249 HP5590_OPT_TRAILING_LINES_MODE,
250 HP5590_OPT_TRAILING_LINES_COLOR,
251 HP5590_OPT_LAST
252 };
253
254 struct hp5590_scanner {
255 struct scanner_info *info;
256 enum proto_flags proto_flags;
257 SANE_Device sane;
258 SANE_Int dn;
259 float br_x, br_y, tl_x, tl_y;
260 unsigned int dpi;
261 enum color_depths depth;
262 enum scan_sources source;
263 SANE_Bool extend_lamp_timeout;
264 SANE_Bool wait_for_button;
265 SANE_Bool preview;
266 unsigned int quality;
267 SANE_Option_Descriptor *opts;
268 struct hp5590_scanner *next;
269 unsigned long long image_size;
270 unsigned long long transferred_image_size;
271 void *bulk_read_state;
272 SANE_Bool scanning;
273 SANE_Bool overwrite_eop_pixel;
274 SANE_Byte *eop_last_line_data;
275 unsigned int eop_last_line_data_rpos;
276 SANE_Int eop_trailing_lines_mode;
277 SANE_Int eop_trailing_lines_color;
278 SANE_Byte *adf_next_page_lines_data;
279 unsigned int adf_next_page_lines_data_size;
280 unsigned int adf_next_page_lines_data_rpos;
281 unsigned int adf_next_page_lines_data_wpos;
282 SANE_Byte *one_line_read_buffer;
283 unsigned int one_line_read_buffer_rpos;
284 SANE_Byte *color_shift_line_buffer1;
285 unsigned int color_shift_buffered_lines1;
286 SANE_Byte *color_shift_line_buffer2;
287 unsigned int color_shift_buffered_lines2;
288 };
289
290 static
291 struct hp5590_scanner *scanners_list;
292
293 /******************************************************************************/
294 static SANE_Status
calc_image_params(struct hp5590_scanner * scanner,unsigned int * pixel_bits,unsigned int * pixels_per_line,unsigned int * bytes_per_line,unsigned int * lines,unsigned long long * image_size)295 calc_image_params (struct hp5590_scanner *scanner,
296 unsigned int *pixel_bits,
297 unsigned int *pixels_per_line,
298 unsigned int *bytes_per_line,
299 unsigned int *lines,
300 unsigned long long *image_size)
301 {
302 unsigned int _pixel_bits;
303 SANE_Status ret;
304 unsigned int _pixels_per_line;
305 unsigned int _bytes_per_line;
306 unsigned int _lines;
307 unsigned int _image_size;
308 float var;
309
310 DBG (DBG_proc, "%s\n", __func__);
311
312 if (!scanner)
313 return SANE_STATUS_INVAL;
314
315 ret = hp5590_calc_pixel_bits (scanner->dpi, scanner->depth, &_pixel_bits);
316 if (ret != SANE_STATUS_GOOD)
317 return ret;
318
319 var = (float) (1.0 * (scanner->br_x - scanner->tl_x) * scanner->dpi);
320 _pixels_per_line = var;
321 if (var > _pixels_per_line)
322 _pixels_per_line++;
323
324 var = (float) (1.0 * (scanner->br_y - scanner->tl_y) * scanner->dpi);
325 _lines = var;
326 if (var > _lines)
327 _lines++;
328
329 var = (float) (1.0 * _pixels_per_line / 8 * _pixel_bits);
330 _bytes_per_line = var;
331 if (var > _bytes_per_line)
332 _bytes_per_line++;
333
334 _image_size = (unsigned long long) _lines * _bytes_per_line;
335
336 DBG (DBG_verbose, "%s: pixel_bits: %u, pixels_per_line: %u, "
337 "bytes_per_line: %u, lines: %u, image_size: %u\n",
338 __func__,
339 _pixel_bits, _pixels_per_line, _bytes_per_line, _lines, _image_size);
340
341 if (pixel_bits)
342 *pixel_bits = _pixel_bits;
343
344 if (pixels_per_line)
345 *pixels_per_line = _pixels_per_line;
346
347 if (bytes_per_line)
348 *bytes_per_line = _bytes_per_line;
349
350 if (lines)
351 *lines = _lines;
352
353 if (image_size)
354 *image_size = _image_size;
355
356 return SANE_STATUS_GOOD;
357 }
358
359 /******************************************************************************/
360 static SANE_Status
attach_usb_device(SANE_String_Const devname,enum hp_scanner_types hp_scanner_type)361 attach_usb_device (SANE_String_Const devname,
362 enum hp_scanner_types hp_scanner_type)
363 {
364 struct scanner_info *info;
365 struct hp5590_scanner *scanner, *ptr;
366 unsigned int max_count, count;
367 SANE_Int dn;
368 SANE_Status ret;
369 const struct hp5590_model *hp5590_model;
370
371 DBG (DBG_proc, "%s: Opening USB device\n", __func__);
372 if (sanei_usb_open (devname, &dn) != SANE_STATUS_GOOD)
373 return SANE_STATUS_IO_ERROR;
374 DBG (DBG_proc, "%s: USB device opened\n", __func__);
375
376 ret = hp5590_model_def (hp_scanner_type, &hp5590_model);
377 if (ret != SANE_STATUS_GOOD)
378 return ret;
379
380 if (hp5590_init_scanner (dn, hp5590_model->proto_flags,
381 &info, hp_scanner_type) != 0)
382 return SANE_STATUS_IO_ERROR;
383
384 DBG (1, "%s: found HP%s scanner at '%s'\n",
385 __func__, info->model, devname);
386
387 DBG (DBG_verbose, "%s: Reading max scan count\n", __func__);
388 if (hp5590_read_max_scan_count (dn, hp5590_model->proto_flags,
389 &max_count) != 0)
390 return SANE_STATUS_IO_ERROR;
391 DBG (DBG_verbose, "%s: Max Scanning count %u\n", __func__, max_count);
392
393 DBG (DBG_verbose, "%s: Reading scan count\n", __func__);
394 if (hp5590_read_scan_count (dn, hp5590_model->proto_flags,
395 &count) != 0)
396 return SANE_STATUS_IO_ERROR;
397 DBG (DBG_verbose, "%s: Scanning count %u\n", __func__, count);
398
399 ret = hp5590_read_part_number (dn, hp5590_model->proto_flags);
400 if (ret != SANE_STATUS_GOOD)
401 return ret;
402
403 ret = hp5590_stop_scan (dn, hp5590_model->proto_flags);
404 if (ret != SANE_STATUS_GOOD)
405 return ret;
406
407 scanner = malloc (sizeof(struct hp5590_scanner));
408 if (!scanner)
409 return SANE_STATUS_NO_MEM;
410 memset (scanner, 0, sizeof(struct hp5590_scanner));
411
412 scanner->sane.model = info->model;
413 scanner->sane.vendor = "HP";
414 scanner->sane.type = info->kind;
415 scanner->sane.name = devname;
416 scanner->dn = dn;
417 scanner->proto_flags = hp5590_model->proto_flags;
418 scanner->info = info;
419 scanner->bulk_read_state = NULL;
420 scanner->opts = NULL;
421 scanner->eop_last_line_data = NULL;
422 scanner->eop_last_line_data_rpos = 0;
423 scanner->adf_next_page_lines_data = NULL;
424 scanner->adf_next_page_lines_data_size = 0;
425 scanner->adf_next_page_lines_data_rpos = 0;
426 scanner->adf_next_page_lines_data_wpos = 0;
427 scanner->one_line_read_buffer = NULL;
428 scanner->one_line_read_buffer_rpos = 0;
429 scanner->color_shift_line_buffer1 = NULL;
430 scanner->color_shift_buffered_lines1 = 0;
431 scanner->color_shift_line_buffer2 = NULL;
432 scanner->color_shift_buffered_lines2 = 0;
433
434 if (!scanners_list)
435 scanners_list = scanner;
436 else
437 {
438 for (ptr = scanners_list; ptr->next; ptr = ptr->next);
439 ptr->next = scanner;
440 }
441
442 return SANE_STATUS_GOOD;
443 }
444
445 /******************************************************************************/
446 static SANE_Status
attach_hp4570(SANE_String_Const devname)447 attach_hp4570 (SANE_String_Const devname)
448 {
449 return attach_usb_device (devname, SCANNER_HP4570);
450 }
451
452 /******************************************************************************/
453 static SANE_Status
attach_hp5550(SANE_String_Const devname)454 attach_hp5550 (SANE_String_Const devname)
455 {
456 return attach_usb_device (devname, SCANNER_HP5550);
457 }
458
459 /******************************************************************************/
460 static SANE_Status
attach_hp5590(SANE_String_Const devname)461 attach_hp5590 (SANE_String_Const devname)
462 {
463 return attach_usb_device (devname, SCANNER_HP5590);
464 }
465
466 /******************************************************************************/
467 static SANE_Status
attach_hp7650(SANE_String_Const devname)468 attach_hp7650 (SANE_String_Const devname)
469 {
470 return attach_usb_device (devname, SCANNER_HP7650);
471 }
472
473 /******************************************************************************/
474 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback __sane_unused__ authorize)475 sane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize)
476 {
477 SANE_Status ret;
478 SANE_Word vendor_id, product_id;
479
480 DBG_INIT();
481
482 DBG (1, "SANE backed for HP ScanJet 4500C/4570C/5500C/5550C/5590/7650 %u.%u.%u\n",
483 SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
484 DBG (1, "(c) Ilia Sotnikov <hostcc@gmail.com>\n");
485
486 if (version_code)
487 *version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
488
489 sanei_usb_init();
490
491 sanei_usb_set_timeout (USB_TIMEOUT);
492
493 scanners_list = NULL;
494
495 ret = hp5590_vendor_product_id (SCANNER_HP4570, &vendor_id, &product_id);
496 if (ret != SANE_STATUS_GOOD)
497 return ret;
498
499 ret = sanei_usb_find_devices (vendor_id, product_id, attach_hp4570);
500 if (ret != SANE_STATUS_GOOD)
501 return ret;
502
503 ret = hp5590_vendor_product_id (SCANNER_HP5550, &vendor_id, &product_id);
504 if (ret != SANE_STATUS_GOOD)
505 return ret;
506
507 ret = sanei_usb_find_devices (vendor_id, product_id, attach_hp5550);
508 if (ret != SANE_STATUS_GOOD)
509 return ret;
510
511 ret = hp5590_vendor_product_id (SCANNER_HP5590, &vendor_id, &product_id);
512 if (ret != SANE_STATUS_GOOD)
513 return ret;
514
515 ret = sanei_usb_find_devices (vendor_id, product_id, attach_hp5590);
516 if (ret != SANE_STATUS_GOOD)
517 return ret;
518
519 ret = hp5590_vendor_product_id (SCANNER_HP7650, &vendor_id, &product_id);
520 if (ret != SANE_STATUS_GOOD)
521 return ret;
522
523 ret = sanei_usb_find_devices (vendor_id, product_id, attach_hp7650);
524 if (ret != SANE_STATUS_GOOD)
525 return ret;
526
527 return SANE_STATUS_GOOD;
528 }
529
530 /******************************************************************************/
sane_exit(void)531 void sane_exit (void)
532 {
533 struct hp5590_scanner *ptr, *pnext;
534
535 DBG (DBG_proc, "%s\n", __func__);
536
537 for (ptr = scanners_list; ptr; ptr = pnext)
538 {
539 if (ptr->opts != NULL)
540 free (ptr->opts);
541 if (ptr->eop_last_line_data != NULL) {
542 free (ptr->eop_last_line_data);
543 ptr->eop_last_line_data = NULL;
544 ptr->eop_last_line_data_rpos = 0;
545 }
546 if (ptr->adf_next_page_lines_data != NULL) {
547 free (ptr->adf_next_page_lines_data);
548 ptr->adf_next_page_lines_data = NULL;
549 ptr->adf_next_page_lines_data_size = 0;
550 ptr->adf_next_page_lines_data_wpos = 0;
551 ptr->adf_next_page_lines_data_rpos = 0;
552 }
553 if (ptr->one_line_read_buffer != NULL) {
554 free (ptr->one_line_read_buffer);
555 ptr->one_line_read_buffer = NULL;
556 ptr->one_line_read_buffer_rpos = 0;
557 }
558 if (ptr->color_shift_line_buffer1 != NULL) {
559 free (ptr->color_shift_line_buffer1);
560 ptr->color_shift_line_buffer1 = NULL;
561 ptr->color_shift_buffered_lines1 = 0;
562 }
563 if (ptr->color_shift_line_buffer2 != NULL) {
564 free (ptr->color_shift_line_buffer2);
565 ptr->color_shift_line_buffer2 = NULL;
566 ptr->color_shift_buffered_lines2 = 0;
567 }
568 pnext = ptr->next;
569 free (ptr);
570 }
571 }
572
573 /******************************************************************************/
574 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)575 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
576 {
577 struct hp5590_scanner *ptr;
578 unsigned int found, i;
579
580 DBG (DBG_proc, "%s, local only: %u\n", __func__, local_only);
581
582 if (!device_list)
583 return SANE_STATUS_INVAL;
584
585 for (found = 0, ptr = scanners_list; ptr; found++, ptr = ptr->next);
586 DBG (1, "Found %u devices\n", found);
587
588 found++;
589 *device_list = malloc (found * sizeof (SANE_Device));
590 if (!*device_list)
591 return SANE_STATUS_NO_MEM;
592 memset (*device_list, 0, found * sizeof(SANE_Device));
593
594 for (i = 0, ptr = scanners_list; ptr; i++, ptr = ptr->next)
595 {
596 (*device_list)[i] = &(ptr->sane);
597 }
598
599 return SANE_STATUS_GOOD;
600 }
601
602 /******************************************************************************/
603 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)604 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
605 {
606 struct hp5590_scanner *ptr;
607 SANE_Option_Descriptor *opts;
608
609 DBG (DBG_proc, "%s: device name: %s\n", __func__, devicename);
610
611 if (!handle)
612 return SANE_STATUS_INVAL;
613
614 /* Allow to open the first available device by specifying zero-length name */
615 if (!devicename || !devicename[0]) {
616 ptr = scanners_list;
617 } else {
618 for (ptr = scanners_list;
619 ptr && strcmp (ptr->sane.name, devicename) != 0;
620 ptr = ptr->next);
621 }
622
623 if (!ptr)
624 return SANE_STATUS_INVAL;
625
626 /* DS: Without this after the first scan (and sane_close)
627 * it was impossible to use again the read_buttons usb routine.
628 * Function sane_close puts dn = -1. Now sane_open needs to open
629 * the usb communication again.
630 */
631 if (ptr->dn < 0) {
632 DBG (DBG_proc, "%s: Reopening USB device\n", __func__);
633 if (sanei_usb_open (ptr->sane.name, &ptr->dn) != SANE_STATUS_GOOD)
634 return SANE_STATUS_IO_ERROR;
635 DBG (DBG_proc, "%s: USB device reopened\n", __func__);
636 }
637
638 ptr->tl_x = 0;
639 ptr->tl_y = 0;
640 ptr->br_x = ptr->info->max_size_x;
641 ptr->br_y = ptr->info->max_size_y;
642 ptr->dpi = res_list[1];
643 ptr->depth = DEPTH_BW;
644 ptr->source = SOURCE_FLATBED;
645 ptr->extend_lamp_timeout = SANE_FALSE;
646 ptr->wait_for_button = SANE_FALSE;
647 ptr->preview = SANE_FALSE;
648 ptr->quality = 4;
649 ptr->image_size = 0;
650 ptr->scanning = SANE_FALSE;
651 ptr->overwrite_eop_pixel = SANE_TRUE;
652 ptr->eop_trailing_lines_mode = TRAILING_LINES_MODE_LAST;
653 ptr->eop_trailing_lines_color = 0x7f007f;
654
655 *handle = ptr;
656
657 opts = malloc (sizeof (SANE_Option_Descriptor) * HP5590_OPT_LAST);
658 if (!opts)
659 return SANE_STATUS_NO_MEM;
660
661 opts[HP5590_OPT_NUM].name = SANE_NAME_NUM_OPTIONS;
662 opts[HP5590_OPT_NUM].title = SANE_TITLE_NUM_OPTIONS;
663 opts[HP5590_OPT_NUM].desc = SANE_DESC_NUM_OPTIONS;
664 opts[HP5590_OPT_NUM].type = SANE_TYPE_INT;
665 opts[HP5590_OPT_NUM].unit = SANE_UNIT_NONE;
666 opts[HP5590_OPT_NUM].size = sizeof(SANE_Word);
667 opts[HP5590_OPT_NUM].cap = SANE_CAP_INACTIVE | SANE_CAP_SOFT_DETECT;
668 opts[HP5590_OPT_NUM].constraint_type = SANE_CONSTRAINT_NONE;
669 opts[HP5590_OPT_NUM].constraint.string_list = NULL;
670
671 range_x.min = SANE_FIX(0);
672 range_x.max = SANE_FIX(ptr->info->max_size_x * 25.4);
673 range_x.quant = SANE_FIX(0.1);
674 range_y.min = SANE_FIX(0);
675 range_y.max = SANE_FIX(ptr->info->max_size_y * 25.4);
676 range_y.quant = SANE_FIX(0.1);
677
678 range_qual.min = SANE_FIX(4);
679 range_qual.max = SANE_FIX(16);
680 range_qual.quant = SANE_FIX(1);
681
682 opts[HP5590_OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
683 opts[HP5590_OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
684 opts[HP5590_OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
685 opts[HP5590_OPT_TL_X].type = SANE_TYPE_FIXED;
686 opts[HP5590_OPT_TL_X].unit = SANE_UNIT_MM;
687 opts[HP5590_OPT_TL_X].size = sizeof(SANE_Fixed);
688 opts[HP5590_OPT_TL_X].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
689 opts[HP5590_OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
690 opts[HP5590_OPT_TL_X].constraint.range = &range_x;
691
692 opts[HP5590_OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
693 opts[HP5590_OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
694 opts[HP5590_OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
695 opts[HP5590_OPT_TL_Y].type = SANE_TYPE_FIXED;
696 opts[HP5590_OPT_TL_Y].unit = SANE_UNIT_MM;
697 opts[HP5590_OPT_TL_Y].size = sizeof(SANE_Fixed);
698 opts[HP5590_OPT_TL_Y].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
699 opts[HP5590_OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
700 opts[HP5590_OPT_TL_Y].constraint.range = &range_y;
701
702 opts[HP5590_OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
703 opts[HP5590_OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
704 opts[HP5590_OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
705 opts[HP5590_OPT_BR_X].type = SANE_TYPE_FIXED;
706 opts[HP5590_OPT_BR_X].unit = SANE_UNIT_MM;
707 opts[HP5590_OPT_BR_X].size = sizeof(SANE_Fixed);
708 opts[HP5590_OPT_BR_X].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
709 opts[HP5590_OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
710 opts[HP5590_OPT_BR_X].constraint.range = &range_x;
711
712 opts[HP5590_OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
713 opts[HP5590_OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
714 opts[HP5590_OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
715 opts[HP5590_OPT_BR_Y].type = SANE_TYPE_FIXED;
716 opts[HP5590_OPT_BR_Y].unit = SANE_UNIT_MM;
717 opts[HP5590_OPT_BR_Y].size = sizeof(SANE_Fixed);
718 opts[HP5590_OPT_BR_Y].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
719 opts[HP5590_OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
720 opts[HP5590_OPT_BR_Y].constraint.range = &range_y;
721
722 opts[HP5590_OPT_MODE].name = SANE_NAME_SCAN_MODE;
723 opts[HP5590_OPT_MODE].title = SANE_TITLE_SCAN_MODE;
724 opts[HP5590_OPT_MODE].desc = SANE_DESC_SCAN_MODE;
725 opts[HP5590_OPT_MODE].type = SANE_TYPE_STRING;
726 opts[HP5590_OPT_MODE].unit = SANE_UNIT_NONE;
727 opts[HP5590_OPT_MODE].size = MAX_SCAN_MODE_VALUE_LEN;
728 opts[HP5590_OPT_MODE].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
729 opts[HP5590_OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
730 opts[HP5590_OPT_MODE].constraint.string_list = mode_list;
731
732 /* Show all features, check on feature in command line evaluation. */
733 opts[HP5590_OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
734 opts[HP5590_OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
735 opts[HP5590_OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
736 opts[HP5590_OPT_SOURCE].type = SANE_TYPE_STRING;
737 opts[HP5590_OPT_SOURCE].unit = SANE_UNIT_NONE;
738 opts[HP5590_OPT_SOURCE].size = MAX_SCAN_SOURCE_VALUE_LEN;
739 opts[HP5590_OPT_SOURCE].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
740 opts[HP5590_OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
741 opts[HP5590_OPT_SOURCE].constraint.string_list = sources_list;
742
743 opts[HP5590_OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
744 opts[HP5590_OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
745 opts[HP5590_OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
746 opts[HP5590_OPT_RESOLUTION].type = SANE_TYPE_INT;
747 opts[HP5590_OPT_RESOLUTION].unit = SANE_UNIT_DPI;
748 opts[HP5590_OPT_RESOLUTION].size = sizeof(SANE_Int);
749 opts[HP5590_OPT_RESOLUTION].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
750 opts[HP5590_OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
751 opts[HP5590_OPT_RESOLUTION].constraint.word_list = res_list;
752
753 opts[HP5590_OPT_LAMP_TIMEOUT].name = SANE_NAME_LAMP_TIMEOUT;
754 opts[HP5590_OPT_LAMP_TIMEOUT].title = SANE_TITLE_LAMP_TIMEOUT;
755 opts[HP5590_OPT_LAMP_TIMEOUT].desc = SANE_DESC_LAMP_TIMEOUT;
756 opts[HP5590_OPT_LAMP_TIMEOUT].type = SANE_TYPE_BOOL;
757 opts[HP5590_OPT_LAMP_TIMEOUT].unit = SANE_UNIT_NONE;
758 opts[HP5590_OPT_LAMP_TIMEOUT].size = sizeof(SANE_Bool);
759 opts[HP5590_OPT_LAMP_TIMEOUT].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
760 opts[HP5590_OPT_LAMP_TIMEOUT].constraint_type = SANE_CONSTRAINT_NONE;
761 opts[HP5590_OPT_LAMP_TIMEOUT].constraint.string_list = NULL;
762
763 opts[HP5590_OPT_WAIT_FOR_BUTTON].name = SANE_NAME_WAIT_FOR_BUTTON;
764 opts[HP5590_OPT_WAIT_FOR_BUTTON].title = SANE_TITLE_WAIT_FOR_BUTTON;
765 opts[HP5590_OPT_WAIT_FOR_BUTTON].desc = SANE_DESC_WAIT_FOR_BUTTON;
766 opts[HP5590_OPT_WAIT_FOR_BUTTON].type = SANE_TYPE_BOOL;
767 opts[HP5590_OPT_WAIT_FOR_BUTTON].unit = SANE_UNIT_NONE;
768 opts[HP5590_OPT_WAIT_FOR_BUTTON].size = sizeof(SANE_Bool);
769 opts[HP5590_OPT_WAIT_FOR_BUTTON].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
770 opts[HP5590_OPT_WAIT_FOR_BUTTON].constraint_type = SANE_CONSTRAINT_NONE;
771 opts[HP5590_OPT_WAIT_FOR_BUTTON].constraint.string_list = NULL;
772
773 opts[HP5590_OPT_BUTTON_PRESSED].name = SANE_NAME_BUTTON_PRESSED;
774 opts[HP5590_OPT_BUTTON_PRESSED].title = SANE_TITLE_BUTTON_PRESSED;
775 opts[HP5590_OPT_BUTTON_PRESSED].desc = SANE_DESC_BUTTON_PRESSED;
776 opts[HP5590_OPT_BUTTON_PRESSED].type = SANE_TYPE_STRING;
777 opts[HP5590_OPT_BUTTON_PRESSED].unit = SANE_UNIT_NONE;
778 opts[HP5590_OPT_BUTTON_PRESSED].size = BUTTON_PRESSED_VALUE_MAX_KEY_LEN;
779 opts[HP5590_OPT_BUTTON_PRESSED].cap = SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT;
780 opts[HP5590_OPT_BUTTON_PRESSED].constraint_type = SANE_CONSTRAINT_STRING_LIST;
781 opts[HP5590_OPT_BUTTON_PRESSED].constraint.string_list = buttonstate_list;
782
783 opts[HP5590_OPT_COLOR_LED].name = SANE_NAME_COLOR_LED;
784 opts[HP5590_OPT_COLOR_LED].title = SANE_TITLE_COLOR_LED;
785 opts[HP5590_OPT_COLOR_LED].desc = SANE_DESC_COLOR_LED;
786 opts[HP5590_OPT_COLOR_LED].type = SANE_TYPE_STRING;
787 opts[HP5590_OPT_COLOR_LED].unit = SANE_UNIT_NONE;
788 opts[HP5590_OPT_COLOR_LED].size = COLOR_LED_VALUE_MAX_KEY_LEN;
789 opts[HP5590_OPT_COLOR_LED].cap = SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT;
790 opts[HP5590_OPT_COLOR_LED].constraint_type = SANE_CONSTRAINT_STRING_LIST;
791 opts[HP5590_OPT_COLOR_LED].constraint.string_list = colorledstate_list;
792
793 opts[HP5590_OPT_LCD_COUNTER].name = SANE_NAME_LCD_COUNTER;
794 opts[HP5590_OPT_LCD_COUNTER].title = SANE_TITLE_LCD_COUNTER;
795 opts[HP5590_OPT_LCD_COUNTER].desc = SANE_DESC_LCD_COUNTER;
796 opts[HP5590_OPT_LCD_COUNTER].type = SANE_TYPE_INT;
797 opts[HP5590_OPT_LCD_COUNTER].unit = SANE_UNIT_NONE;
798 opts[HP5590_OPT_LCD_COUNTER].size = sizeof(SANE_Int);
799 opts[HP5590_OPT_LCD_COUNTER].cap = SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT;
800 opts[HP5590_OPT_LCD_COUNTER].constraint_type = SANE_CONSTRAINT_RANGE;
801 opts[HP5590_OPT_LCD_COUNTER].constraint.range = &lcd_counter_range;
802
803 opts[HP5590_OPT_DOC_IN_ADF].name = SANE_NAME_DOC_IN_ADF;
804 opts[HP5590_OPT_DOC_IN_ADF].title = SANE_TITLE_DOC_IN_ADF;
805 opts[HP5590_OPT_DOC_IN_ADF].desc = SANE_DESC_DOC_IN_ADF;
806 opts[HP5590_OPT_DOC_IN_ADF].type = SANE_TYPE_BOOL;
807 opts[HP5590_OPT_DOC_IN_ADF].unit = SANE_UNIT_NONE;
808 opts[HP5590_OPT_DOC_IN_ADF].size = sizeof(SANE_Bool);
809 opts[HP5590_OPT_DOC_IN_ADF].cap = SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT;
810 opts[HP5590_OPT_DOC_IN_ADF].constraint_type = SANE_CONSTRAINT_NONE;
811 opts[HP5590_OPT_DOC_IN_ADF].constraint.range = NULL;
812
813 opts[HP5590_OPT_PREVIEW].name = SANE_NAME_PREVIEW;
814 opts[HP5590_OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
815 opts[HP5590_OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
816 opts[HP5590_OPT_PREVIEW].type = SANE_TYPE_BOOL;
817 opts[HP5590_OPT_PREVIEW].unit = SANE_UNIT_NONE;
818 opts[HP5590_OPT_PREVIEW].size = sizeof(SANE_Bool);
819 opts[HP5590_OPT_PREVIEW].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
820 opts[HP5590_OPT_PREVIEW].constraint_type = SANE_CONSTRAINT_NONE;
821 opts[HP5590_OPT_PREVIEW].constraint.string_list = NULL;
822
823 opts[HP5590_OPT_OVERWRITE_EOP_PIXEL].name = SANE_NAME_OVERWRITE_EOP_PIXEL;
824 opts[HP5590_OPT_OVERWRITE_EOP_PIXEL].title = SANE_TITLE_OVERWRITE_EOP_PIXEL;
825 opts[HP5590_OPT_OVERWRITE_EOP_PIXEL].desc = SANE_DESC_OVERWRITE_EOP_PIXEL;
826 opts[HP5590_OPT_OVERWRITE_EOP_PIXEL].type = SANE_TYPE_BOOL;
827 opts[HP5590_OPT_OVERWRITE_EOP_PIXEL].unit = SANE_UNIT_NONE;
828 opts[HP5590_OPT_OVERWRITE_EOP_PIXEL].size = sizeof(SANE_Bool);
829 opts[HP5590_OPT_OVERWRITE_EOP_PIXEL].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
830 opts[HP5590_OPT_OVERWRITE_EOP_PIXEL].constraint_type = SANE_CONSTRAINT_NONE;
831 opts[HP5590_OPT_OVERWRITE_EOP_PIXEL].constraint.string_list = NULL;
832
833 opts[HP5590_OPT_TRAILING_LINES_MODE].name = SANE_NAME_TRAILING_LINES_MODE;
834 opts[HP5590_OPT_TRAILING_LINES_MODE].title = SANE_TITLE_TRAILING_LINES_MODE;
835 opts[HP5590_OPT_TRAILING_LINES_MODE].desc = SANE_DESC_TRAILING_LINES_MODE;
836 opts[HP5590_OPT_TRAILING_LINES_MODE].type = SANE_TYPE_STRING;
837 opts[HP5590_OPT_TRAILING_LINES_MODE].unit = SANE_UNIT_NONE;
838 opts[HP5590_OPT_TRAILING_LINES_MODE].size = TRAILING_LINES_MODE_MAX_KEY_LEN;
839 opts[HP5590_OPT_TRAILING_LINES_MODE].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
840 opts[HP5590_OPT_TRAILING_LINES_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
841 opts[HP5590_OPT_TRAILING_LINES_MODE].constraint.string_list = trailingmode_list;
842
843 opts[HP5590_OPT_TRAILING_LINES_COLOR].name = SANE_NAME_TRAILING_LINES_COLOR;
844 opts[HP5590_OPT_TRAILING_LINES_COLOR].title = SANE_TITLE_TRAILING_LINES_COLOR;
845 opts[HP5590_OPT_TRAILING_LINES_COLOR].desc = SANE_DESC_TRAILING_LINES_COLOR;
846 opts[HP5590_OPT_TRAILING_LINES_COLOR].type = SANE_TYPE_INT;
847 opts[HP5590_OPT_TRAILING_LINES_COLOR].unit = SANE_UNIT_NONE;
848 opts[HP5590_OPT_TRAILING_LINES_COLOR].size = sizeof(SANE_Int);
849 opts[HP5590_OPT_TRAILING_LINES_COLOR].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
850 opts[HP5590_OPT_TRAILING_LINES_COLOR].constraint_type = SANE_CONSTRAINT_NONE;
851 opts[HP5590_OPT_TRAILING_LINES_COLOR].constraint.string_list = NULL;
852
853 ptr->opts = opts;
854
855 return SANE_STATUS_GOOD;
856 }
857
858 /******************************************************************************/
859 void
sane_close(SANE_Handle handle)860 sane_close (SANE_Handle handle)
861 {
862 struct hp5590_scanner *scanner = handle;
863
864 DBG (DBG_proc, "%s\n", __func__);
865
866 sanei_usb_close (scanner->dn);
867 scanner->dn = -1;
868 }
869
870 /******************************************************************************/
871 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)872 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
873 {
874 struct hp5590_scanner *scanner = handle;
875
876 DBG (DBG_proc, "%s, option: %u\n", __func__, option);
877
878 if (option >= HP5590_OPT_LAST)
879 return NULL;
880
881 return &scanner->opts[option];
882 }
883
884 /*************************************DS:Support function read buttons status */
885 SANE_Status
read_button_pressed(SANE_Handle handle,enum button_status * button_pressed)886 read_button_pressed(SANE_Handle handle, enum button_status * button_pressed)
887 {
888 struct hp5590_scanner * scanner = handle;
889 *button_pressed = BUTTON_NONE;
890 enum button_status status = BUTTON_NONE;
891 DBG (DBG_verbose, "%s: Checking button status (device_number = %u) (device_name = %s)\n", __func__, scanner->dn, scanner->sane.name);
892 SANE_Status ret = hp5590_read_buttons (scanner->dn, scanner->proto_flags, &status);
893 if (ret != SANE_STATUS_GOOD)
894 {
895 DBG (DBG_proc, "%s: Error reading button status (%u)\n", __func__, ret);
896 return ret;
897 }
898 DBG (DBG_verbose, "%s: Button pressed = %d\n", __func__, status);
899 *button_pressed = status;
900 return SANE_STATUS_GOOD;
901 }
902
903 /******************************************************************************/
904 SANE_Status
read_lcd_and_led_values(SANE_Handle handle,SANE_Int * lcd_counter,enum color_led_status * color_led)905 read_lcd_and_led_values(SANE_Handle handle,
906 SANE_Int * lcd_counter,
907 enum color_led_status * color_led)
908 {
909 struct hp5590_scanner * scanner = handle;
910 *lcd_counter = 1;
911 *color_led = LED_COLOR;
912 DBG (DBG_verbose, "%s: Reading LCD and LED values (device_number = %u) (device_name = %s)\n",
913 __func__, scanner->dn, scanner->sane.name);
914 SANE_Status ret = hp5590_read_lcd_and_led (scanner->dn, scanner->proto_flags, lcd_counter, color_led);
915 if (ret != SANE_STATUS_GOOD)
916 {
917 DBG (DBG_proc, "%s: Error reading LCD and LED values (%u)\n", __func__, ret);
918 return ret;
919 }
920 DBG (DBG_verbose, "%s: LCD = %d, LED = %s\n", __func__, *lcd_counter,
921 *color_led == LED_BLACKWHITE ? COLOR_LED_VALUE_BLACKWHITE_KEY : COLOR_LED_VALUE_COLOR_KEY);
922 return SANE_STATUS_GOOD;
923 }
924
925 /******************************************************************************/
926 SANE_Status
read_doc_in_adf_value(SANE_Handle handle,SANE_Bool * doc_in_adf)927 read_doc_in_adf_value(SANE_Handle handle,
928 SANE_Bool * doc_in_adf)
929 {
930 struct hp5590_scanner * scanner = handle;
931 DBG (DBG_verbose, "%s: Reading state of document-available in ADF (device_number = %u) (device_name = %s)\n",
932 __func__, scanner->dn, scanner->sane.name);
933 SANE_Status ret = hp5590_is_data_available (scanner->dn, scanner->proto_flags);
934 if (ret == SANE_STATUS_GOOD)
935 *doc_in_adf = SANE_TRUE;
936 else if (ret == SANE_STATUS_NO_DOCS)
937 *doc_in_adf = SANE_FALSE;
938 else
939 {
940 DBG (DBG_proc, "%s: Error reading state of document-available in ADF (%u)\n", __func__, ret);
941 return ret;
942 }
943 DBG (DBG_verbose, "%s: doc_in_adf = %s\n", __func__, *doc_in_adf == SANE_FALSE ? "false" : "true");
944 return SANE_STATUS_GOOD;
945 }
946
947 /******************************************************************************/
948 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * value,SANE_Int * info)949 sane_control_option (SANE_Handle handle, SANE_Int option,
950 SANE_Action action, void *value,
951 SANE_Int * info)
952 {
953 struct hp5590_scanner *scanner = handle;
954
955 if (!value)
956 return SANE_STATUS_INVAL;
957
958 if (!handle)
959 return SANE_STATUS_INVAL;
960
961 if (option >= HP5590_OPT_LAST)
962 return SANE_STATUS_INVAL;
963
964 if (action == SANE_ACTION_GET_VALUE)
965 {
966 if (option == HP5590_OPT_NUM)
967 {
968 DBG(3, "%s: get total number of options - %u\n", __func__, HP5590_OPT_LAST);
969 *((SANE_Int *) value) = HP5590_OPT_LAST;
970 return SANE_STATUS_GOOD;
971 }
972
973 if (!scanner->opts)
974 return SANE_STATUS_INVAL;
975
976 DBG (DBG_proc, "%s: get option '%s' value\n", __func__, scanner->opts[option].name);
977
978 if (option == HP5590_OPT_BR_X)
979 {
980 *(SANE_Fixed *) value = SANE_FIX (scanner->br_x * 25.4);
981 }
982
983 if (option == HP5590_OPT_BR_Y)
984 {
985 *(SANE_Fixed *) value = SANE_FIX (scanner->br_y * 25.4);
986 }
987
988 if (option == HP5590_OPT_TL_X)
989 {
990 *(SANE_Fixed *) value = SANE_FIX ((scanner->tl_x) * 25.4);
991 }
992
993 if (option == HP5590_OPT_TL_Y)
994 {
995 *(SANE_Fixed *) value = SANE_FIX (scanner->tl_y * 25.4);
996 }
997
998 if (option == HP5590_OPT_MODE)
999 {
1000 switch (scanner->depth) {
1001 case DEPTH_BW:
1002 memset (value , 0, scanner->opts[option].size);
1003 memcpy (value, SANE_VALUE_SCAN_MODE_LINEART, strlen (SANE_VALUE_SCAN_MODE_LINEART));
1004 break;
1005 case DEPTH_GRAY:
1006 memset (value , 0, scanner->opts[option].size);
1007 memcpy (value, SANE_VALUE_SCAN_MODE_GRAY, strlen (SANE_VALUE_SCAN_MODE_GRAY));
1008 break;
1009 case DEPTH_COLOR_24:
1010 memset (value , 0, scanner->opts[option].size);
1011 memcpy (value, SANE_VALUE_SCAN_MODE_COLOR_24, strlen (SANE_VALUE_SCAN_MODE_COLOR_24));
1012 break;
1013 case DEPTH_COLOR_48:
1014 memset (value , 0, scanner->opts[option].size);
1015 memcpy (value, SANE_VALUE_SCAN_MODE_COLOR_48, strlen (SANE_VALUE_SCAN_MODE_COLOR_48));
1016 break;
1017 default:
1018 return SANE_STATUS_INVAL;
1019 }
1020 }
1021
1022 if (option == HP5590_OPT_SOURCE)
1023 {
1024 switch (scanner->source) {
1025 case SOURCE_FLATBED:
1026 memset (value , 0, scanner->opts[option].size);
1027 memcpy (value, SANE_VALUE_SCAN_SOURCE_FLATBED, strlen (SANE_VALUE_SCAN_SOURCE_FLATBED));
1028 break;
1029 case SOURCE_ADF:
1030 memset (value , 0, scanner->opts[option].size);
1031 memcpy (value, SANE_VALUE_SCAN_SOURCE_ADF, strlen (SANE_VALUE_SCAN_SOURCE_ADF));
1032 break;
1033 case SOURCE_ADF_DUPLEX:
1034 memset (value , 0, scanner->opts[option].size);
1035 memcpy (value, SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX, strlen (SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX));
1036 break;
1037 case SOURCE_TMA_SLIDES:
1038 memset (value , 0, scanner->opts[option].size);
1039 memcpy (value, SANE_VALUE_SCAN_SOURCE_TMA_SLIDES, strlen (SANE_VALUE_SCAN_SOURCE_TMA_SLIDES));
1040 break;
1041 case SOURCE_TMA_NEGATIVES:
1042 memset (value , 0, scanner->opts[option].size);
1043 memcpy (value, SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES, strlen (SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES));
1044 break;
1045 case SOURCE_NONE:
1046 default:
1047 return SANE_STATUS_INVAL;
1048 }
1049 }
1050
1051 if (option == HP5590_OPT_RESOLUTION)
1052 {
1053 *(SANE_Int *) value = scanner->dpi;
1054 }
1055
1056 if (option == HP5590_OPT_LAMP_TIMEOUT)
1057 {
1058 *(SANE_Bool *) value = scanner->extend_lamp_timeout;
1059 }
1060
1061 if (option == HP5590_OPT_WAIT_FOR_BUTTON)
1062 {
1063 *(SANE_Bool *) value = scanner->wait_for_button;
1064 }
1065
1066 if (option == HP5590_OPT_BUTTON_PRESSED)
1067 {
1068 enum button_status button_pressed = BUTTON_NONE;
1069 SANE_Status ret = read_button_pressed(scanner, &button_pressed);
1070 if (ret != SANE_STATUS_GOOD)
1071 return ret;
1072 switch (button_pressed) {
1073 case BUTTON_POWER:
1074 strncpy (value, BUTTON_PRESSED_VALUE_POWER_KEY, scanner->opts[option].size);
1075 break;
1076 case BUTTON_SCAN:
1077 strncpy (value, BUTTON_PRESSED_VALUE_SCAN_KEY, scanner->opts[option].size);
1078 break;
1079 case BUTTON_COLLECT:
1080 strncpy (value, BUTTON_PRESSED_VALUE_COLLECT_KEY, scanner->opts[option].size);
1081 break;
1082 case BUTTON_FILE:
1083 strncpy (value, BUTTON_PRESSED_VALUE_FILE_KEY, scanner->opts[option].size);
1084 break;
1085 case BUTTON_EMAIL:
1086 strncpy (value, BUTTON_PRESSED_VALUE_EMAIL_KEY, scanner->opts[option].size);
1087 break;
1088 case BUTTON_COPY:
1089 strncpy (value, BUTTON_PRESSED_VALUE_COPY_KEY, scanner->opts[option].size);
1090 break;
1091 case BUTTON_UP:
1092 strncpy (value, BUTTON_PRESSED_VALUE_UP_KEY, scanner->opts[option].size);
1093 break;
1094 case BUTTON_DOWN:
1095 strncpy (value, BUTTON_PRESSED_VALUE_DOWN_KEY, scanner->opts[option].size);
1096 break;
1097 case BUTTON_MODE:
1098 strncpy (value, BUTTON_PRESSED_VALUE_MODE_KEY, scanner->opts[option].size);
1099 break;
1100 case BUTTON_CANCEL:
1101 strncpy (value, BUTTON_PRESSED_VALUE_CANCEL_KEY, scanner->opts[option].size);
1102 break;
1103 case BUTTON_NONE:
1104 default:
1105 strncpy (value, BUTTON_PRESSED_VALUE_NONE_KEY, scanner->opts[option].size);
1106 }
1107 }
1108
1109 if (option == HP5590_OPT_COLOR_LED)
1110 {
1111 SANE_Int lcd_counter = 0;
1112 enum color_led_status color_led = LED_COLOR;
1113 SANE_Status ret = read_lcd_and_led_values(scanner, &lcd_counter, &color_led);
1114 if (ret != SANE_STATUS_GOOD)
1115 return ret;
1116 switch (color_led) {
1117 case LED_BLACKWHITE:
1118 strncpy (value, COLOR_LED_VALUE_BLACKWHITE_KEY, scanner->opts[option].size);
1119 break;
1120 case LED_COLOR:
1121 default:
1122 strncpy (value, COLOR_LED_VALUE_COLOR_KEY, scanner->opts[option].size);
1123 }
1124 }
1125
1126 if (option == HP5590_OPT_LCD_COUNTER)
1127 {
1128 SANE_Int lcd_counter = 0;
1129 enum color_led_status color_led = LED_COLOR;
1130 SANE_Status ret = read_lcd_and_led_values(scanner, &lcd_counter, &color_led);
1131 if (ret != SANE_STATUS_GOOD)
1132 return ret;
1133 *(SANE_Int *) value = lcd_counter;
1134 }
1135
1136 if (option == HP5590_OPT_DOC_IN_ADF)
1137 {
1138 SANE_Bool doc_in_adf = SANE_FALSE;
1139 SANE_Status ret = read_doc_in_adf_value(scanner, &doc_in_adf);
1140 if (ret != SANE_STATUS_GOOD)
1141 return ret;
1142 *(SANE_Bool *) value = doc_in_adf;
1143 }
1144
1145 if (option == HP5590_OPT_PREVIEW)
1146 {
1147 *(SANE_Bool *) value = scanner->preview;
1148 }
1149
1150 if (option == HP5590_OPT_OVERWRITE_EOP_PIXEL)
1151 {
1152 *(SANE_Bool *) value = scanner->overwrite_eop_pixel;
1153 }
1154
1155 if (option == HP5590_OPT_TRAILING_LINES_MODE)
1156 {
1157 switch (scanner->eop_trailing_lines_mode) {
1158 case TRAILING_LINES_MODE_RAW:
1159 memset (value , 0, scanner->opts[option].size);
1160 memcpy (value, TRAILING_LINES_MODE_RAW_KEY, strlen (TRAILING_LINES_MODE_RAW_KEY));
1161 break;
1162 case TRAILING_LINES_MODE_LAST:
1163 memset (value , 0, scanner->opts[option].size);
1164 memcpy (value, TRAILING_LINES_MODE_LAST_KEY, strlen (TRAILING_LINES_MODE_LAST_KEY));
1165 break;
1166 case TRAILING_LINES_MODE_RASTER:
1167 memset (value , 0, scanner->opts[option].size);
1168 memcpy (value, TRAILING_LINES_MODE_RASTER_KEY, strlen (TRAILING_LINES_MODE_RASTER_KEY));
1169 break;
1170 case TRAILING_LINES_MODE_BLACK:
1171 memset (value , 0, scanner->opts[option].size);
1172 memcpy (value, TRAILING_LINES_MODE_BLACK_KEY, strlen (TRAILING_LINES_MODE_BLACK_KEY));
1173 break;
1174 case TRAILING_LINES_MODE_WHITE:
1175 memset (value , 0, scanner->opts[option].size);
1176 memcpy (value, TRAILING_LINES_MODE_WHITE_KEY, strlen (TRAILING_LINES_MODE_WHITE_KEY));
1177 break;
1178 case TRAILING_LINES_MODE_COLOR:
1179 memset (value , 0, scanner->opts[option].size);
1180 memcpy (value, TRAILING_LINES_MODE_COLOR_KEY, strlen (TRAILING_LINES_MODE_COLOR_KEY));
1181 break;
1182 default:
1183 return SANE_STATUS_INVAL;
1184 }
1185 }
1186
1187 if (option == HP5590_OPT_TRAILING_LINES_COLOR)
1188 {
1189 *(SANE_Int *) value = scanner->eop_trailing_lines_color;
1190 }
1191 }
1192
1193 if (action == SANE_ACTION_SET_VALUE)
1194 {
1195 if (option == HP5590_OPT_NUM)
1196 return SANE_STATUS_INVAL;
1197
1198 if (option == HP5590_OPT_BR_X)
1199 {
1200 float val = SANE_UNFIX(*(SANE_Fixed *) value) / 25.4;
1201 if (val <= scanner->tl_x)
1202 return SANE_STATUS_GOOD;
1203 scanner->br_x = val;
1204 if (info)
1205 *info = SANE_INFO_RELOAD_PARAMS;
1206 }
1207
1208 if (option == HP5590_OPT_BR_Y)
1209 {
1210 float val = SANE_UNFIX(*(SANE_Fixed *) value) / 25.4;
1211 if (val <= scanner->tl_y)
1212 return SANE_STATUS_GOOD;
1213 scanner->br_y = val;
1214 if (info)
1215 *info = SANE_INFO_RELOAD_PARAMS;
1216 }
1217
1218 if (option == HP5590_OPT_TL_X)
1219 {
1220 float val = SANE_UNFIX(*(SANE_Fixed *) value) / 25.4;
1221 if (val >= scanner->br_x)
1222 return SANE_STATUS_GOOD;
1223 scanner->tl_x = val;
1224 if (info)
1225 *info = SANE_INFO_RELOAD_PARAMS;
1226 }
1227
1228 if (option == HP5590_OPT_TL_Y)
1229 {
1230 float val = SANE_UNFIX(*(SANE_Fixed *) value) / 25.4;
1231 if (val >= scanner->br_y)
1232 return SANE_STATUS_GOOD;
1233 scanner->tl_y = val;
1234 if (info)
1235 *info = SANE_INFO_RELOAD_PARAMS;
1236 }
1237
1238 if (option == HP5590_OPT_MODE)
1239 {
1240 if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_MODE_LINEART) == 0)
1241 {
1242 scanner->depth = DEPTH_BW;
1243 }
1244 else if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_MODE_GRAY) == 0)
1245 {
1246 scanner->depth = DEPTH_GRAY;
1247 }
1248 else if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_MODE_COLOR_24) == 0)
1249 {
1250 scanner->depth = DEPTH_COLOR_24;
1251 }
1252 else if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_MODE_COLOR_48) == 0)
1253 {
1254 scanner->depth = DEPTH_COLOR_48;
1255 }
1256 else
1257 {
1258 return SANE_STATUS_INVAL;
1259 }
1260
1261 if (info)
1262 *info = SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1263 }
1264
1265 if (option == HP5590_OPT_SOURCE)
1266 {
1267 range_y.max = SANE_FIX(scanner->info->max_size_y * 25.4);
1268
1269 if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_SOURCE_FLATBED) == 0)
1270 {
1271 scanner->source = SOURCE_FLATBED;
1272 range_x.max = SANE_FIX(scanner->info->max_size_x * 25.4);
1273 range_y.max = SANE_FIX(scanner->info->max_size_y * 25.4);
1274 scanner->br_x = scanner->info->max_size_x;
1275 scanner->br_y = scanner->info->max_size_y;
1276 }
1277 else if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_SOURCE_ADF) == 0)
1278 {
1279 /* In ADF modes the device can scan up to ADF_MAX_Y_INCHES, which is usually
1280 * bigger than what scanner reports back during initialization
1281 */
1282 if (! (scanner->info->features & FEATURE_ADF))
1283 {
1284 DBG(DBG_err, "ADF feature not available: %s\n", (char *) value);
1285 return SANE_STATUS_UNSUPPORTED;
1286 }
1287 scanner->source = SOURCE_ADF;
1288 range_x.max = SANE_FIX(scanner->info->max_size_x * 25.4);
1289 range_y.max = SANE_FIX(ADF_MAX_Y_INCHES * 25.4);
1290 scanner->br_x = scanner->info->max_size_x;
1291 scanner->br_y = ADF_MAX_Y_INCHES;
1292 }
1293 else if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX) == 0)
1294 {
1295 if (! (scanner->info->features & FEATURE_ADF))
1296 {
1297 DBG(DBG_err, "ADF feature not available: %s\n", (char *) value);
1298 return SANE_STATUS_UNSUPPORTED;
1299 }
1300 scanner->source = SOURCE_ADF_DUPLEX;
1301 range_x.max = SANE_FIX(scanner->info->max_size_x * 25.4);
1302 range_y.max = SANE_FIX(ADF_MAX_Y_INCHES * 25.4);
1303 scanner->br_x = scanner->info->max_size_x;
1304 scanner->br_y = ADF_MAX_Y_INCHES;
1305 }
1306 else if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_SOURCE_TMA_SLIDES) == 0)
1307 {
1308 if (! (scanner->info->features & FEATURE_TMA))
1309 {
1310 DBG(DBG_err, "TMA feature not available: %s\n", (char *) value);
1311 return SANE_STATUS_UNSUPPORTED;
1312 }
1313 scanner->source = SOURCE_TMA_SLIDES;
1314 range_x.max = SANE_FIX(TMA_MAX_X_INCHES * 25.4);
1315 range_y.max = SANE_FIX(TMA_MAX_Y_INCHES * 25.4);
1316 scanner->br_x = TMA_MAX_X_INCHES;
1317 scanner->br_y = TMA_MAX_Y_INCHES;
1318 }
1319 else if (strcmp ((char *) value, (char *) SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES) == 0)
1320 {
1321 if (! (scanner->info->features & FEATURE_TMA))
1322 {
1323 DBG(DBG_err, "TMA feature not available: %s\n", (char *) value);
1324 return SANE_STATUS_UNSUPPORTED;
1325 }
1326 scanner->source = SOURCE_TMA_NEGATIVES;
1327 range_x.max = SANE_FIX(TMA_MAX_X_INCHES * 25.4);
1328 range_y.max = SANE_FIX(TMA_MAX_Y_INCHES * 25.4);
1329 scanner->br_x = TMA_MAX_X_INCHES;
1330 scanner->br_y = TMA_MAX_Y_INCHES;
1331 }
1332 else
1333 {
1334 return SANE_STATUS_INVAL;
1335 }
1336 if (info)
1337 *info = SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1338 }
1339
1340 if (option == HP5590_OPT_RESOLUTION)
1341 {
1342 scanner->dpi = *(SANE_Int *) value;
1343 if (info)
1344 *info = SANE_INFO_RELOAD_PARAMS;
1345 }
1346
1347 if (option == HP5590_OPT_LAMP_TIMEOUT)
1348 {
1349 scanner->extend_lamp_timeout = *(SANE_Bool *) value;
1350 }
1351
1352 if (option == HP5590_OPT_WAIT_FOR_BUTTON)
1353 {
1354 scanner->wait_for_button = *(SANE_Bool *) value;
1355 }
1356
1357 if (option == HP5590_OPT_BUTTON_PRESSED)
1358 {
1359 DBG(DBG_verbose, "State of buttons is read only. Setting of state will be ignored.\n");
1360 }
1361
1362 if (option == HP5590_OPT_COLOR_LED)
1363 {
1364 DBG(DBG_verbose, "State of color LED indicator is read only. Setting of state will be ignored.\n");
1365 }
1366
1367 if (option == HP5590_OPT_LCD_COUNTER)
1368 {
1369 DBG(DBG_verbose, "Value of LCD counter is read only. Setting of value will be ignored.\n");
1370 }
1371
1372 if (option == HP5590_OPT_DOC_IN_ADF)
1373 {
1374 DBG(DBG_verbose, "Value of document-available indicator is read only. Setting of value will be ignored.\n");
1375 }
1376
1377 if (option == HP5590_OPT_PREVIEW)
1378 {
1379 scanner->preview = *(SANE_Bool *) value;
1380 }
1381
1382 if (option == HP5590_OPT_OVERWRITE_EOP_PIXEL)
1383 {
1384 scanner->overwrite_eop_pixel = *(SANE_Bool *) value;
1385 }
1386
1387 if (option == HP5590_OPT_TRAILING_LINES_MODE)
1388 {
1389 if (strcmp ((char *) value, (char *) TRAILING_LINES_MODE_RAW_KEY) == 0)
1390 scanner->eop_trailing_lines_mode = TRAILING_LINES_MODE_RAW;
1391 if (strcmp ((char *) value, (char *) TRAILING_LINES_MODE_LAST_KEY) == 0)
1392 scanner->eop_trailing_lines_mode = TRAILING_LINES_MODE_LAST;
1393 if (strcmp ((char *) value, (char *) TRAILING_LINES_MODE_RASTER_KEY) == 0)
1394 scanner->eop_trailing_lines_mode = TRAILING_LINES_MODE_RASTER;
1395 if (strcmp ((char *) value, (char *) TRAILING_LINES_MODE_BLACK_KEY) == 0)
1396 scanner->eop_trailing_lines_mode = TRAILING_LINES_MODE_BLACK;
1397 if (strcmp ((char *) value, (char *) TRAILING_LINES_MODE_WHITE_KEY) == 0)
1398 scanner->eop_trailing_lines_mode = TRAILING_LINES_MODE_WHITE;
1399 if (strcmp ((char *) value, (char *) TRAILING_LINES_MODE_COLOR_KEY) == 0)
1400 scanner->eop_trailing_lines_mode = TRAILING_LINES_MODE_COLOR;
1401 }
1402
1403 if (option == HP5590_OPT_TRAILING_LINES_COLOR)
1404 {
1405 scanner->eop_trailing_lines_color = *(SANE_Int *) value;
1406 }
1407 }
1408
1409 return SANE_STATUS_GOOD;
1410 }
1411
1412 /******************************************************************************/
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)1413 SANE_Status sane_get_parameters (SANE_Handle handle,
1414 SANE_Parameters * params)
1415 {
1416 struct hp5590_scanner *scanner = handle;
1417 SANE_Status ret;
1418 unsigned int pixel_bits;
1419
1420 DBG (DBG_proc, "%s\n", __func__);
1421
1422 if (!params)
1423 return SANE_STATUS_INVAL;
1424
1425 if (!handle)
1426 return SANE_STATUS_INVAL;
1427
1428 ret = calc_image_params (scanner,
1429 (unsigned int *) &pixel_bits,
1430 (unsigned int *) ¶ms->pixels_per_line,
1431 (unsigned int *) ¶ms->bytes_per_line,
1432 (unsigned int *) ¶ms->lines, NULL);
1433 if (ret != SANE_STATUS_GOOD)
1434 return ret;
1435
1436 switch (scanner->depth) {
1437 case DEPTH_BW:
1438 params->depth = pixel_bits;
1439 params->format = SANE_FRAME_GRAY;
1440 params->last_frame = SANE_TRUE;
1441 break;
1442 case DEPTH_GRAY:
1443 params->depth = pixel_bits;
1444 params->format = SANE_FRAME_GRAY;
1445 params->last_frame = SANE_TRUE;
1446 break;
1447 case DEPTH_COLOR_24:
1448 params->depth = pixel_bits / 3;
1449 params->last_frame = SANE_TRUE;
1450 params->format = SANE_FRAME_RGB;
1451 break;
1452 case DEPTH_COLOR_48:
1453 params->depth = pixel_bits / 3;
1454 params->last_frame = SANE_TRUE;
1455 params->format = SANE_FRAME_RGB;
1456 break;
1457 default:
1458 DBG(DBG_err, "%s: Unknown depth\n", __func__);
1459 return SANE_STATUS_INVAL;
1460 }
1461
1462
1463 DBG (DBG_proc, "format: %u, last_frame: %u, bytes_per_line: %u, "
1464 "pixels_per_line: %u, lines: %u, depth: %u\n",
1465 params->format, params->last_frame,
1466 params->bytes_per_line, params->pixels_per_line,
1467 params->lines, params->depth);
1468
1469 return SANE_STATUS_GOOD;
1470 }
1471
1472 /******************************************************************************/
1473 SANE_Status
sane_start(SANE_Handle handle)1474 sane_start (SANE_Handle handle)
1475 {
1476 struct hp5590_scanner *scanner = handle;
1477 SANE_Status ret;
1478 unsigned int bytes_per_line;
1479
1480 DBG (DBG_proc, "%s\n", __func__);
1481
1482 if (!scanner)
1483 return SANE_STATUS_INVAL;
1484
1485 /* Cleanup for all pages. */
1486 if (scanner->eop_last_line_data)
1487 {
1488 /* Release last line data */
1489 free (scanner->eop_last_line_data);
1490 scanner->eop_last_line_data = NULL;
1491 scanner->eop_last_line_data_rpos = 0;
1492 }
1493 if (scanner->one_line_read_buffer)
1494 {
1495 /* Release temporary line buffer. */
1496 free (scanner->one_line_read_buffer);
1497 scanner->one_line_read_buffer = NULL;
1498 scanner->one_line_read_buffer_rpos = 0;
1499 }
1500 if (scanner->color_shift_line_buffer1)
1501 {
1502 /* Release line buffer1 for shifting colors. */
1503 free (scanner->color_shift_line_buffer1);
1504 scanner->color_shift_line_buffer1 = NULL;
1505 scanner->color_shift_buffered_lines1 = 0;
1506 }
1507 if (scanner->color_shift_line_buffer2)
1508 {
1509 /* Release line buffer2 for shifting colors. */
1510 free (scanner->color_shift_line_buffer2);
1511 scanner->color_shift_line_buffer2 = NULL;
1512 scanner->color_shift_buffered_lines2 = 0;
1513 }
1514
1515 if ( scanner->scanning == SANE_TRUE
1516 && ( scanner->source == SOURCE_ADF
1517 || scanner->source == SOURCE_ADF_DUPLEX))
1518 {
1519 DBG (DBG_verbose, "%s: Scanner is scanning, check if more data is available\n",
1520 __func__);
1521 ret = hp5590_is_data_available (scanner->dn, scanner->proto_flags);
1522 if (ret == SANE_STATUS_GOOD)
1523 {
1524 DBG (DBG_verbose, "%s: More data is available\n", __func__);
1525 scanner->transferred_image_size = scanner->image_size;
1526 return SANE_STATUS_GOOD;
1527 }
1528
1529 if (ret != SANE_STATUS_NO_DOCS)
1530 return ret;
1531 }
1532
1533 sane_cancel (handle);
1534
1535 if (scanner->wait_for_button)
1536 {
1537 enum button_status status;
1538 for (;;)
1539 {
1540 ret = hp5590_read_buttons (scanner->dn,
1541 scanner->proto_flags,
1542 &status);
1543 if (ret != SANE_STATUS_GOOD)
1544 return ret;
1545
1546 if (status == BUTTON_CANCEL)
1547 return SANE_STATUS_CANCELLED;
1548
1549 if (status != BUTTON_NONE && status != BUTTON_POWER)
1550 break;
1551 usleep (100 * 1000);
1552 }
1553 }
1554
1555 DBG (DBG_verbose, "Init scanner\n");
1556 ret = hp5590_init_scanner (scanner->dn, scanner->proto_flags,
1557 NULL, SCANNER_NONE);
1558 if (ret != SANE_STATUS_GOOD)
1559 return ret;
1560
1561 ret = hp5590_power_status (scanner->dn, scanner->proto_flags);
1562 if (ret != SANE_STATUS_GOOD)
1563 return ret;
1564
1565 DBG (DBG_verbose, "Wakeup\n");
1566 ret = hp5590_select_source_and_wakeup (scanner->dn, scanner->proto_flags,
1567 scanner->source,
1568 scanner->extend_lamp_timeout);
1569 if (ret != SANE_STATUS_GOOD)
1570 return ret;
1571
1572 ret = hp5590_set_scan_params (scanner->dn,
1573 scanner->proto_flags,
1574 scanner->info,
1575 scanner->tl_x * scanner->dpi,
1576 scanner->tl_y * scanner->dpi,
1577 (scanner->br_x - scanner->tl_x) * scanner->dpi,
1578 (scanner->br_y - scanner->tl_y) * scanner->dpi,
1579 scanner->dpi,
1580 scanner->depth, scanner->preview ? MODE_PREVIEW : MODE_NORMAL,
1581 scanner->source);
1582 if (ret != SANE_STATUS_GOOD)
1583 {
1584 hp5590_reset_scan_head (scanner->dn, scanner->proto_flags);
1585 return ret;
1586 }
1587
1588 ret = calc_image_params (scanner, NULL, NULL,
1589 &bytes_per_line, NULL,
1590 &scanner->image_size);
1591 if (ret != SANE_STATUS_GOOD)
1592 {
1593 hp5590_reset_scan_head (scanner->dn, scanner->proto_flags);
1594 return ret;
1595 }
1596
1597 scanner->transferred_image_size = scanner->image_size;
1598
1599 if ( scanner->depth == DEPTH_COLOR_24
1600 || scanner->depth == DEPTH_COLOR_48)
1601 {
1602 DBG (1, "Color 24/48 bits: checking if image size is correctly "
1603 "aligned on number of colors\n");
1604 if (bytes_per_line % 3)
1605 {
1606 DBG (DBG_err, "Color 24/48 bits: image size doesn't lined up on number of colors (3) "
1607 "(image size: %llu, bytes per line %u)\n",
1608 scanner->image_size, bytes_per_line);
1609 hp5590_reset_scan_head (scanner->dn, scanner->proto_flags);
1610 return SANE_STATUS_INVAL;
1611 }
1612 DBG (1, "Color 24/48 bits: image size is correctly aligned on number of colors "
1613 "(image size: %llu, bytes per line %u)\n",
1614 scanner->image_size, bytes_per_line);
1615
1616 DBG (1, "Color 24/48 bits: checking if image size is correctly "
1617 "aligned on bytes per line\n");
1618 if (scanner->image_size % bytes_per_line)
1619 {
1620 DBG (DBG_err, "Color 24/48 bits: image size doesn't lined up on bytes per line "
1621 "(image size: %llu, bytes per line %u)\n",
1622 scanner->image_size, bytes_per_line);
1623 hp5590_reset_scan_head (scanner->dn, scanner->proto_flags);
1624 return SANE_STATUS_INVAL;
1625 }
1626 DBG (1, "Color 24/48 bits: image size correctly aligned on bytes per line "
1627 "(images size: %llu, bytes per line: %u)\n",
1628 scanner->image_size, bytes_per_line);
1629 }
1630
1631 DBG (DBG_verbose, "Final image size: %llu\n", scanner->image_size);
1632
1633 DBG (DBG_verbose, "Reverse calibration maps\n");
1634 ret = hp5590_send_reverse_calibration_map (scanner->dn, scanner->proto_flags);
1635 if (ret != SANE_STATUS_GOOD)
1636 {
1637 hp5590_reset_scan_head (scanner->dn, scanner->proto_flags);
1638 return ret;
1639 }
1640
1641 DBG (DBG_verbose, "Forward calibration maps\n");
1642 ret = hp5590_send_forward_calibration_maps (scanner->dn, scanner->proto_flags);
1643 if (ret != SANE_STATUS_GOOD)
1644 {
1645 hp5590_reset_scan_head (scanner->dn, scanner->proto_flags);
1646 return ret;
1647 }
1648
1649 if (scanner->adf_next_page_lines_data)
1650 {
1651 free (scanner->adf_next_page_lines_data);
1652 scanner->adf_next_page_lines_data = NULL;
1653 scanner->adf_next_page_lines_data_size = 0;
1654 scanner->adf_next_page_lines_data_rpos = 0;
1655 scanner->adf_next_page_lines_data_wpos = 0;
1656 }
1657
1658 scanner->scanning = SANE_TRUE;
1659
1660 DBG (DBG_verbose, "Starting scan\n");
1661 ret = hp5590_start_scan (scanner->dn, scanner->proto_flags);
1662 /* Check for paper jam */
1663 if ( ret == SANE_STATUS_DEVICE_BUSY
1664 && ( scanner->source == SOURCE_ADF
1665 || scanner->source == SOURCE_ADF_DUPLEX))
1666 return SANE_STATUS_JAMMED;
1667
1668 if (ret != SANE_STATUS_GOOD)
1669 {
1670 hp5590_reset_scan_head (scanner->dn, scanner->proto_flags);
1671 return ret;
1672 }
1673
1674 return SANE_STATUS_GOOD;
1675 }
1676
1677 /******************************************************************************/
1678 static void
invert_negative_colors(unsigned char * buf,unsigned int bytes_per_line,struct hp5590_scanner * scanner)1679 invert_negative_colors (unsigned char *buf, unsigned int bytes_per_line, struct hp5590_scanner *scanner)
1680 {
1681 /* Invert lineart or negatives. */
1682 int is_linear = (scanner->depth == DEPTH_BW);
1683 int is_negative = (scanner->source == SOURCE_TMA_NEGATIVES);
1684 if (is_linear ^ is_negative)
1685 {
1686 for (unsigned int k = 0; k < bytes_per_line; k++)
1687 buf[k] ^= 0xff;
1688 }
1689 }
1690
1691 /******************************************************************************/
1692 static SANE_Status
convert_gray_and_lineart(struct hp5590_scanner * scanner,SANE_Byte * data,SANE_Int size)1693 convert_gray_and_lineart (struct hp5590_scanner *scanner, SANE_Byte *data, SANE_Int size)
1694 {
1695 unsigned int pixels_per_line;
1696 unsigned int pixel_bits;
1697 unsigned int bytes_per_line;
1698 unsigned int lines;
1699 unsigned char *buf;
1700 SANE_Status ret;
1701
1702 hp5590_assert (scanner != NULL);
1703 hp5590_assert (data != NULL);
1704
1705 if ( ! (scanner->depth == DEPTH_BW || scanner->depth == DEPTH_GRAY))
1706 return SANE_STATUS_GOOD;
1707
1708 DBG (DBG_proc, "%s\n", __func__);
1709
1710 ret = calc_image_params (scanner,
1711 &pixel_bits,
1712 &pixels_per_line, &bytes_per_line,
1713 NULL, NULL);
1714 if (ret != SANE_STATUS_GOOD)
1715 return ret;
1716
1717 lines = size / bytes_per_line;
1718
1719 buf = data;
1720 for (unsigned int i = 0; i < lines; buf += bytes_per_line, ++i)
1721 {
1722 if (! scanner->eop_last_line_data)
1723 {
1724 if (pixels_per_line > 0)
1725 {
1726 /* Test for last-line indicator pixel. If found, store last line
1727 * and optionally overwrite indicator pixel with neighbor value.
1728 */
1729 unsigned int j = bytes_per_line - 1;
1730 int eop_found = 0;
1731 if (scanner->depth == DEPTH_GRAY)
1732 {
1733 eop_found = (buf[j] != 0);
1734 if (scanner->overwrite_eop_pixel && (j > 0))
1735 {
1736 buf[j] = buf[j-1];
1737 }
1738 }
1739 else if (scanner->depth == DEPTH_BW)
1740 {
1741 eop_found = (buf[j] != 0);
1742 if (scanner->overwrite_eop_pixel && (j > 0))
1743 {
1744 buf[j] = (buf[j-1] & 0x01) ? 0xff : 0;
1745 }
1746 }
1747
1748 invert_negative_colors (buf, bytes_per_line, scanner);
1749
1750 if (eop_found && (! scanner->eop_last_line_data))
1751 {
1752 DBG (DBG_verbose, "Found end-of-page at line %u in reading block.\n", i);
1753 scanner->eop_last_line_data = malloc(bytes_per_line);
1754 if (! scanner->eop_last_line_data)
1755 return SANE_STATUS_NO_MEM;
1756
1757 memcpy (scanner->eop_last_line_data, buf, bytes_per_line);
1758 scanner->eop_last_line_data_rpos = 0;
1759
1760 /* Fill trailing line buffer with requested color. */
1761 if (scanner->eop_trailing_lines_mode == TRAILING_LINES_MODE_RASTER)
1762 {
1763 /* Black-white raster. */
1764 if (scanner->depth == DEPTH_BW)
1765 {
1766 memset (scanner->eop_last_line_data, 0xaa, bytes_per_line);
1767 }
1768 else
1769 {
1770 /* Gray. */
1771 for (unsigned int k = 0; k < bytes_per_line; ++k)
1772 {
1773 scanner->eop_last_line_data[k] = (k & 1 ? 0xff : 0);
1774 }
1775 }
1776 }
1777 else if (scanner->eop_trailing_lines_mode == TRAILING_LINES_MODE_WHITE)
1778 {
1779 /* White. */
1780 if (scanner->depth == DEPTH_BW)
1781 {
1782 memset (scanner->eop_last_line_data, 0x00, bytes_per_line);
1783 }
1784 else
1785 {
1786 memset (scanner->eop_last_line_data, 0xff, bytes_per_line);
1787 }
1788 }
1789 else if (scanner->eop_trailing_lines_mode == TRAILING_LINES_MODE_BLACK)
1790 {
1791 /* Black. */
1792 if (scanner->depth == DEPTH_BW)
1793 {
1794 memset (scanner->eop_last_line_data, 0xff, bytes_per_line);
1795 }
1796 else
1797 {
1798 memset (scanner->eop_last_line_data, 0x00, bytes_per_line);
1799 }
1800 }
1801 else if (scanner->eop_trailing_lines_mode == TRAILING_LINES_MODE_COLOR)
1802 {
1803 if (scanner->depth == DEPTH_BW)
1804 {
1805 /* Black or white. */
1806 memset (scanner->eop_last_line_data, scanner->eop_trailing_lines_color & 0x01 ? 0x00 : 0xff, bytes_per_line);
1807 }
1808 else
1809 {
1810 /* Gray value */
1811 memset (scanner->eop_last_line_data, scanner->eop_trailing_lines_color & 0xff, bytes_per_line);
1812 }
1813 }
1814 }
1815 }
1816 }
1817 else
1818 {
1819 DBG (DBG_verbose, "Trailing lines mode: line=%u, mode=%d, color=%u\n",
1820 i, scanner->eop_trailing_lines_mode, scanner->eop_trailing_lines_color);
1821
1822 if ((scanner->source == SOURCE_ADF) || (scanner->source == SOURCE_ADF_DUPLEX))
1823 {
1824 /* We are in in ADF mode after last-line and store next page data
1825 * to buffer.
1826 */
1827 if (! scanner->adf_next_page_lines_data)
1828 {
1829 unsigned int n_rest_lines = lines - i;
1830 unsigned int buf_size = n_rest_lines * bytes_per_line;
1831 scanner->adf_next_page_lines_data = malloc(buf_size);
1832 if (! scanner->adf_next_page_lines_data)
1833 return SANE_STATUS_NO_MEM;
1834 scanner->adf_next_page_lines_data_size = buf_size;
1835 scanner->adf_next_page_lines_data_rpos = 0;
1836 scanner->adf_next_page_lines_data_wpos = 0;
1837 DBG (DBG_verbose, "ADF between pages: Save n=%u next page lines in buffer.\n", n_rest_lines);
1838 }
1839 DBG (DBG_verbose, "ADF between pages: Store line %u of %u.\n", i, lines);
1840 invert_negative_colors (buf, bytes_per_line, scanner);
1841 memcpy (scanner->adf_next_page_lines_data + scanner->adf_next_page_lines_data_wpos, buf, bytes_per_line);
1842 scanner->adf_next_page_lines_data_wpos += bytes_per_line;
1843 }
1844
1845 if (scanner->eop_trailing_lines_mode != TRAILING_LINES_MODE_RAW)
1846 {
1847 /* Copy last line data or corresponding color over trailing lines
1848 * data.
1849 */
1850 memcpy (buf, scanner->eop_last_line_data, bytes_per_line);
1851 }
1852 }
1853 }
1854
1855 return SANE_STATUS_GOOD;
1856 }
1857
1858 /******************************************************************************/
1859 static unsigned char
get_checked(unsigned char * ptr,unsigned int i,unsigned int length)1860 get_checked (unsigned char *ptr, unsigned int i, unsigned int length)
1861 {
1862 if (i < length)
1863 {
1864 return ptr[i];
1865 }
1866 DBG (DBG_details, "get from array out of range: idx=%u, size=%u\n", i, length);
1867 return 0;
1868 }
1869
1870 /******************************************************************************/
1871 static SANE_Status
convert_to_rgb(struct hp5590_scanner * scanner,SANE_Byte * data,SANE_Int size)1872 convert_to_rgb (struct hp5590_scanner *scanner, SANE_Byte *data, SANE_Int size)
1873 {
1874 unsigned int pixels_per_line;
1875 unsigned int pixel_bits;
1876 unsigned int bytes_per_color;
1877 unsigned int bytes_per_line;
1878 unsigned int bytes_per_line_limit;
1879 unsigned int lines;
1880 unsigned int i, j;
1881 unsigned char *buf;
1882 unsigned char *bufptr;
1883 unsigned char *ptr;
1884 SANE_Status ret;
1885
1886 hp5590_assert (scanner != NULL);
1887 hp5590_assert (data != NULL);
1888
1889 if ( ! (scanner->depth == DEPTH_COLOR_24 || scanner->depth == DEPTH_COLOR_48))
1890 return SANE_STATUS_GOOD;
1891
1892 DBG (DBG_proc, "%s\n", __func__);
1893
1894 #ifndef HAS_WORKING_COLOR_48
1895 if (scanner->depth == DEPTH_COLOR_48)
1896 return SANE_STATUS_UNSUPPORTED;
1897 #endif
1898
1899 ret = calc_image_params (scanner,
1900 &pixel_bits,
1901 &pixels_per_line, &bytes_per_line,
1902 NULL, NULL);
1903 if (ret != SANE_STATUS_GOOD)
1904 return ret;
1905
1906 lines = size / bytes_per_line;
1907 bytes_per_color = (pixel_bits + 7) / 8;
1908
1909 bytes_per_line_limit = bytes_per_line;
1910 if ((scanner->depth == DEPTH_COLOR_48) && (bytes_per_line_limit > 3))
1911 {
1912 /* Last-line indicator pixel has only 3 bytes instead of 6. */
1913 bytes_per_line_limit -= 3;
1914 }
1915
1916 DBG (DBG_verbose, "Length : %u\n", size);
1917
1918 DBG (DBG_verbose, "Converting row RGB to normal RGB\n");
1919
1920 DBG (DBG_verbose, "Bytes per line %u\n", bytes_per_line);
1921 DBG (DBG_verbose, "Bytes per line limited %u\n", bytes_per_line_limit);
1922 DBG (DBG_verbose, "Bytes per color %u\n", bytes_per_color);
1923 DBG (DBG_verbose, "Pixels per line %u\n", pixels_per_line);
1924 DBG (DBG_verbose, "Lines %u\n", lines);
1925
1926 /* Use working buffer for color mapping. */
1927 bufptr = malloc (size);
1928 if (! bufptr)
1929 return SANE_STATUS_NO_MEM;
1930 memset (bufptr, 0, size);
1931 buf = bufptr;
1932
1933 ptr = data;
1934 for (j = 0; j < lines; ptr += bytes_per_line_limit, buf += bytes_per_line, j++)
1935 {
1936 for (i = 0; i < pixels_per_line; i++)
1937 {
1938 /* Color mapping from raw scanner data to RGB buffer. */
1939 if (scanner->depth == DEPTH_COLOR_24)
1940 {
1941 /* R */
1942 buf[i*3] = get_checked(ptr, i, bytes_per_line_limit);
1943 /* G */
1944 buf[i*3+1] = get_checked(ptr, i+pixels_per_line, bytes_per_line_limit);;
1945 /* B */
1946 buf[i*3+2] = get_checked(ptr, i+pixels_per_line*2, bytes_per_line_limit);
1947 }
1948 else if (scanner->depth == DEPTH_COLOR_48)
1949 {
1950 /* Note: The last-line indicator pixel uses only 24 bits, not 48.
1951 *Blue uses offset of 2 bytes. Green swaps lo and hi.
1952 */
1953 /* R lo, hi*/
1954 buf[i*6] = get_checked(ptr, 2*i+(pixels_per_line-1)*0+1, bytes_per_line_limit);
1955 buf[i*6+1] = get_checked(ptr, 2*i+(pixels_per_line-1)*0+0, bytes_per_line_limit);
1956 /* G lo, hi*/
1957 buf[i*6+2] = get_checked(ptr, 2*i+(pixels_per_line-1)*2+0, bytes_per_line_limit);
1958 buf[i*6+3] = get_checked(ptr, 2*i+(pixels_per_line-1)*2+1, bytes_per_line_limit);
1959 /* B lo, hi*/
1960 buf[i*6+4] = get_checked(ptr, 2*i+(pixels_per_line-1)*4+1+2, bytes_per_line_limit);
1961 buf[i*6+5] = get_checked(ptr, 2*i+(pixels_per_line-1)*4+0+2, bytes_per_line_limit);
1962 }
1963 }
1964
1965 if (! scanner->eop_last_line_data)
1966 {
1967 if (pixels_per_line > 0)
1968 {
1969 /* Test for last-line indicator pixel on blue. If found, store
1970 * last line and optionally overwrite indicator pixel with
1971 * neighbor value.
1972 */
1973 i = pixels_per_line - 1;
1974 int eop_found = 0;
1975 if (scanner->depth == DEPTH_COLOR_24)
1976 {
1977 /* DBG (DBG_details, "BUF24: %u %u %u\n", buf[i*3], buf[i*3+1], buf[i*3+2]); */
1978 eop_found = (buf[i*3+2] != 0);
1979 if (scanner->overwrite_eop_pixel && (i > 0))
1980 {
1981 buf[i*3] = buf[(i-1)*3];
1982 buf[i*3+1] = buf[(i-1)*3+1];
1983 buf[i*3+2] = buf[(i-1)*3+2];
1984 }
1985 }
1986 else if (scanner->depth == DEPTH_COLOR_48)
1987 {
1988 /* DBG (DBG_details, "BUF48: %u %u %u\n", buf[i*6+1], buf[i*6+3], buf[i*6+5]); */
1989 eop_found = (buf[i*6+5] != 0);
1990 if (scanner->overwrite_eop_pixel && (i > 0))
1991 {
1992 buf[i*6] = buf[(i-1)*6];
1993 buf[i*6+1] = buf[(i-1)*6+1];
1994 buf[i*6+2] = buf[(i-1)*6+2];
1995 buf[i*6+3] = buf[(i-1)*6+3];
1996 buf[i*6+4] = buf[(i-1)*6+4];
1997 buf[i*6+5] = buf[(i-1)*6+5];
1998 }
1999 }
2000
2001 invert_negative_colors (buf, bytes_per_line, scanner);
2002
2003 if (eop_found && (! scanner->eop_last_line_data))
2004 {
2005 DBG (DBG_verbose, "Found end-of-page at line %u in reading block.\n", j);
2006 scanner->eop_last_line_data = malloc(bytes_per_line);
2007 if (! scanner->eop_last_line_data)
2008 return SANE_STATUS_NO_MEM;
2009
2010 memcpy (scanner->eop_last_line_data, buf, bytes_per_line);
2011 scanner->eop_last_line_data_rpos = 0;
2012
2013 /* Fill trailing line buffer with requested color. */
2014 if (scanner->eop_trailing_lines_mode == TRAILING_LINES_MODE_RASTER)
2015 {
2016 /* Black-white raster. */
2017 if (scanner->depth == DEPTH_COLOR_24)
2018 {
2019 for (unsigned int k = 0; k < bytes_per_line; ++k)
2020 {
2021 scanner->eop_last_line_data[k] = (k % 6 < 3 ? 0xff : 0);
2022 }
2023 }
2024 else
2025 {
2026 /* Color48. */
2027 for (unsigned int k = 0; k < bytes_per_line; ++k)
2028 {
2029 scanner->eop_last_line_data[k] = (k % 12 < 6 ? 0xff : 0);
2030 }
2031 }
2032 }
2033 else if (scanner->eop_trailing_lines_mode == TRAILING_LINES_MODE_WHITE)
2034 {
2035 memset (scanner->eop_last_line_data, 0xff, bytes_per_line);
2036 }
2037 else if (scanner->eop_trailing_lines_mode == TRAILING_LINES_MODE_BLACK)
2038 {
2039 memset (scanner->eop_last_line_data, 0x00, bytes_per_line);
2040 }
2041 else if (scanner->eop_trailing_lines_mode == TRAILING_LINES_MODE_COLOR)
2042 {
2043 /* RGB color value. */
2044 int rgb[3];
2045 rgb[0] = (scanner->eop_trailing_lines_color >> 16) & 0xff;
2046 rgb[1] = (scanner->eop_trailing_lines_color >> 8) & 0xff;
2047 rgb[2] = scanner->eop_trailing_lines_color & 0xff;
2048 if (scanner->depth == DEPTH_COLOR_24)
2049 {
2050 for (unsigned int k = 0; k < bytes_per_line; ++k)
2051 {
2052 scanner->eop_last_line_data[k] = rgb[k % 3];
2053 }
2054 }
2055 else
2056 {
2057 /* Color48. */
2058 for (unsigned int k = 0; k < bytes_per_line; ++k)
2059 {
2060 scanner->eop_last_line_data[k] = rgb[(k % 6) >> 1];
2061 }
2062 }
2063 }
2064 }
2065 }
2066 }
2067 else
2068 {
2069 DBG (DBG_verbose, "Trailing lines mode: line=%u, mode=%d, color=%u\n",
2070 j, scanner->eop_trailing_lines_mode, scanner->eop_trailing_lines_color);
2071
2072 if ((scanner->source == SOURCE_ADF) || (scanner->source == SOURCE_ADF_DUPLEX))
2073 {
2074 /* We are in in ADF mode after last-line and store next page data
2075 * to buffer.
2076 */
2077 if (! scanner->adf_next_page_lines_data)
2078 {
2079 unsigned int n_rest_lines = lines - j;
2080 unsigned int buf_size = n_rest_lines * bytes_per_line;
2081 scanner->adf_next_page_lines_data = malloc(buf_size);
2082 if (! scanner->adf_next_page_lines_data)
2083 return SANE_STATUS_NO_MEM;
2084 scanner->adf_next_page_lines_data_size = buf_size;
2085 scanner->adf_next_page_lines_data_rpos = 0;
2086 scanner->adf_next_page_lines_data_wpos = 0;
2087 DBG (DBG_verbose, "ADF between pages: Save n=%u next page lines in buffer.\n", n_rest_lines);
2088 }
2089 DBG (DBG_verbose, "ADF between pages: Store line %u of %u.\n", j, lines);
2090 invert_negative_colors (buf, bytes_per_line, scanner);
2091 memcpy (scanner->adf_next_page_lines_data + scanner->adf_next_page_lines_data_wpos, buf, bytes_per_line);
2092 scanner->adf_next_page_lines_data_wpos += bytes_per_line;
2093 }
2094
2095 if (scanner->eop_trailing_lines_mode != TRAILING_LINES_MODE_RAW)
2096 {
2097 /* Copy last line data or corresponding color over trailing lines
2098 * data.
2099 */
2100 memcpy (buf, scanner->eop_last_line_data, bytes_per_line);
2101 }
2102 }
2103 }
2104 memcpy (data, bufptr, size);
2105 free (bufptr);
2106
2107 return SANE_STATUS_GOOD;
2108 }
2109
2110 /******************************************************************************/
2111 static void
read_data_from_temporary_buffer(struct hp5590_scanner * scanner,SANE_Byte * data,unsigned int max_length,unsigned int bytes_per_line,SANE_Int * length)2112 read_data_from_temporary_buffer(struct hp5590_scanner *scanner,
2113 SANE_Byte * data, unsigned int max_length,
2114 unsigned int bytes_per_line, SANE_Int *length)
2115 {
2116 *length = 0;
2117 if (scanner && scanner->one_line_read_buffer)
2118 {
2119 /* Copy scan data from temporary read buffer and return size copied data. */
2120 /* Release buffer, when no data left. */
2121 unsigned int rest_len;
2122 rest_len = bytes_per_line - scanner->one_line_read_buffer_rpos;
2123 rest_len = (rest_len < max_length) ? rest_len : max_length;
2124 if (rest_len > 0)
2125 {
2126 memcpy (data, scanner->one_line_read_buffer + scanner->one_line_read_buffer_rpos, rest_len);
2127 scanner->one_line_read_buffer_rpos += rest_len;
2128 scanner->transferred_image_size -= rest_len;
2129 *length = rest_len;
2130 }
2131
2132 DBG (DBG_verbose, "Copy scan data from temporary buffer: length = %u, rest in buffer = %u.\n",
2133 *length, bytes_per_line - scanner->one_line_read_buffer_rpos);
2134
2135 if (scanner->one_line_read_buffer_rpos >= bytes_per_line)
2136 {
2137 DBG (DBG_verbose, "Release temporary buffer.\n");
2138 free (scanner->one_line_read_buffer);
2139 scanner->one_line_read_buffer = NULL;
2140 scanner->one_line_read_buffer_rpos = 0;
2141 }
2142 }
2143 }
2144
2145 /******************************************************************************/
2146 static SANE_Status
sane_read_internal(struct hp5590_scanner * scanner,SANE_Byte * data,SANE_Int max_length,SANE_Int * length,unsigned int bytes_per_line)2147 sane_read_internal (struct hp5590_scanner * scanner, SANE_Byte * data,
2148 SANE_Int max_length, SANE_Int * length, unsigned int bytes_per_line)
2149 {
2150 SANE_Status ret;
2151
2152 DBG (DBG_proc, "%s, length %u, left %llu\n",
2153 __func__,
2154 max_length,
2155 scanner->transferred_image_size);
2156
2157 SANE_Int length_limited = 0;
2158 *length = max_length;
2159 if ((unsigned long long) *length > scanner->transferred_image_size)
2160 *length = (SANE_Int) scanner->transferred_image_size;
2161
2162 /* Align reading size to bytes per line. */
2163 *length -= *length % bytes_per_line;
2164
2165 if (scanner->depth == DEPTH_COLOR_48)
2166 {
2167 /* Note: The last-line indicator pixel uses only 24 bits (3 bytes), not
2168 * 48 bits (6 bytes).
2169 */
2170 if (bytes_per_line > 3)
2171 {
2172 length_limited = *length - *length % (bytes_per_line - 3);
2173 }
2174 }
2175
2176 DBG (DBG_verbose, "Aligning requested size to bytes per line "
2177 "(requested: %d, aligned: %u, limit_for_48bit: %u)\n",
2178 max_length, *length, length_limited);
2179
2180 if (max_length <= 0)
2181 {
2182 DBG (DBG_verbose, "Buffer too small for one scan line. Need at least %u bytes per line.\n",
2183 bytes_per_line);
2184 scanner->scanning = SANE_FALSE;
2185 return SANE_STATUS_UNSUPPORTED;
2186 }
2187
2188 if (scanner->one_line_read_buffer)
2189 {
2190 /* Copy scan data from temporary read buffer. */
2191 read_data_from_temporary_buffer (scanner, data, max_length, bytes_per_line, length);
2192 if (*length > 0)
2193 {
2194 DBG (DBG_verbose, "Return %d bytes, left %llu bytes.\n", *length, scanner->transferred_image_size);
2195 return SANE_STATUS_GOOD;
2196 }
2197 }
2198
2199 /* Buffer to return scanned data. We need at least space for one line to
2200 * simplify color processing and last-line detection. If call buffer is too
2201 * small, use temporary read buffer for reading one line instead.
2202 */
2203 SANE_Byte * scan_data;
2204 SANE_Int scan_data_length;
2205 scan_data = data;
2206 scan_data_length = *length;
2207
2208 /* Note, read length is shorter in 48bit mode. */
2209 SANE_Int length_for_read = length_limited ? length_limited : scan_data_length;
2210 if (length_for_read == 0)
2211 {
2212 /* Call buffer is too small for one line. Use temporary read buffer
2213 * instead.
2214 */
2215 if (! scanner->one_line_read_buffer)
2216 {
2217 scanner->one_line_read_buffer = malloc (bytes_per_line);
2218 if (! scanner->one_line_read_buffer)
2219 return SANE_STATUS_NO_MEM;
2220 memset (scanner->one_line_read_buffer, 0, bytes_per_line);
2221 }
2222
2223 DBG (DBG_verbose, "Call buffer too small for one scan line. Use temporary read buffer for one line with %u bytes.\n",
2224 bytes_per_line);
2225
2226 /* Scan and process next line in temporary buffer. */
2227 scan_data = scanner->one_line_read_buffer;
2228 scan_data_length = bytes_per_line;
2229 length_for_read = bytes_per_line;
2230 if (scanner->depth == DEPTH_COLOR_48)
2231 {
2232 /* The last-line indicator pixel uses only 24 bits (3 bytes), not 48
2233 * bits (6 bytes).
2234 */
2235 if (length_for_read > 3)
2236 {
2237 length_for_read -= 3;
2238 }
2239 }
2240 }
2241
2242 int read_from_scanner = 1;
2243 if ((scanner->source == SOURCE_ADF) || (scanner->source == SOURCE_ADF_DUPLEX))
2244 {
2245 if (scanner->eop_last_line_data)
2246 {
2247 /* Scanner is in ADF mode between last-line of previous page and
2248 * start of next page.
2249 * Fill remaining lines with last-line data.
2250 */
2251 unsigned int wpos = 0;
2252 while (wpos < (unsigned int) scan_data_length)
2253 {
2254 unsigned int n1 = scan_data_length - wpos;
2255 unsigned int n2 = bytes_per_line - scanner->eop_last_line_data_rpos;
2256 n1 = (n1 < n2) ? n1 : n2;
2257 memcpy (scan_data + wpos, scanner->eop_last_line_data + scanner->eop_last_line_data_rpos, n1);
2258 wpos += n1;
2259 scanner->eop_last_line_data_rpos += n1;
2260 if (scanner->eop_last_line_data_rpos >= bytes_per_line)
2261 scanner->eop_last_line_data_rpos = 0;
2262 }
2263 read_from_scanner = (wpos == 0);
2264 DBG (DBG_verbose, "ADF use last-line data, wlength=%u, length=%u\n", wpos, scan_data_length);
2265 }
2266 else if (scanner->adf_next_page_lines_data)
2267 {
2268 /* Scanner is in ADF mode at start of next page and already some next
2269 * page data is available from earlier read operation. Return this
2270 * data.
2271 */
2272 unsigned int wpos = 0;
2273 while ((wpos < (unsigned int) scan_data_length) &&
2274 (scanner->adf_next_page_lines_data_rpos < scanner->adf_next_page_lines_data_size))
2275 {
2276 unsigned int n1 = scan_data_length - wpos;
2277 unsigned int n2 = scanner->adf_next_page_lines_data_size - scanner->adf_next_page_lines_data_rpos;
2278 n1 = (n1 < n2) ? n1 : n2;
2279 memcpy (scan_data + wpos, scanner->adf_next_page_lines_data + scanner->adf_next_page_lines_data_rpos, n1);
2280 wpos += n1;
2281 scanner->adf_next_page_lines_data_rpos += n1;
2282 if (scanner->adf_next_page_lines_data_rpos >= scanner->adf_next_page_lines_data_size)
2283 {
2284 free (scanner->adf_next_page_lines_data);
2285 scanner->adf_next_page_lines_data = NULL;
2286 scanner->adf_next_page_lines_data_size = 0;
2287 scanner->adf_next_page_lines_data_rpos = 0;
2288 scanner->adf_next_page_lines_data_wpos = 0;
2289 }
2290 }
2291 scan_data_length = wpos;
2292 read_from_scanner = (wpos == 0);
2293 DBG (DBG_verbose, "ADF use next-page data, wlength=%u, length=%u\n", wpos, scan_data_length);
2294 }
2295 }
2296
2297 if (read_from_scanner)
2298 {
2299 /* Read data from scanner. */
2300 ret = hp5590_read (scanner->dn, scanner->proto_flags,
2301 scan_data, length_for_read,
2302 scanner->bulk_read_state);
2303 if (ret != SANE_STATUS_GOOD)
2304 {
2305 scanner->scanning = SANE_FALSE;
2306 return ret;
2307 }
2308
2309 /* Look for last-line indicator pixels in convert functions.
2310 * If found:
2311 * - Overwrite indicator pixel with neighboring color (optional).
2312 * - Save last line data for later use.
2313 */
2314 ret = convert_to_rgb (scanner, scan_data, scan_data_length);
2315 if (ret != SANE_STATUS_GOOD)
2316 {
2317 scanner->scanning = SANE_FALSE;
2318 return ret;
2319 }
2320
2321 ret = convert_gray_and_lineart (scanner, scan_data, scan_data_length);
2322 if (ret != SANE_STATUS_GOOD)
2323 return ret;
2324 }
2325
2326 if (data == scan_data)
2327 {
2328 /* Scanned to call buffer. */
2329 scanner->transferred_image_size -= scan_data_length;
2330 *length = scan_data_length;
2331 }
2332 else
2333 {
2334 /* Scanned to temporary read buffer. */
2335 if (scanner->one_line_read_buffer)
2336 {
2337 /* Copy scan data from temporary read buffer. */
2338 read_data_from_temporary_buffer (scanner, data, max_length, scan_data_length, length);
2339 }
2340 else
2341 {
2342 *length = 0;
2343 }
2344 }
2345
2346 DBG (DBG_verbose, "Return %d bytes, left %llu bytes\n", *length, scanner->transferred_image_size);
2347 return SANE_STATUS_GOOD;
2348 }
2349
2350 /******************************************************************************
2351 * Copy at maximum the last n lines from the src buffer to the begin of the dst
2352 * buffer.
2353 * Return number of lines copied.
2354 */
2355 static SANE_Int
copy_n_last_lines(SANE_Byte * src,SANE_Int src_len,SANE_Byte * dst,SANE_Int n,unsigned int bytes_per_line)2356 copy_n_last_lines(SANE_Byte * src, SANE_Int src_len, SANE_Byte * dst, SANE_Int n, unsigned int bytes_per_line)
2357 {
2358 DBG (DBG_proc, "%s\n", __func__);
2359 SANE_Int n_copy = MY_MIN(src_len, n);
2360 SANE_Byte * src1 = src + (src_len - n_copy) * bytes_per_line;
2361 memcpy (dst, src1, n_copy * bytes_per_line);
2362 return n_copy;
2363 }
2364
2365 /******************************************************************************
2366 * Copy the color values from line - delta_lines to line.
2367 * buffer2 : Source and target buffer.
2368 * buffer1 : Only source buffer. Contains lines scanned before lines in buffer1.
2369 * color_idx : Index of color to be copied (0..2).
2370 * delta_lines : color shift.
2371 * color_48 : True = 2 byte , false = 1 byte per color.
2372 */
2373 static void
shift_color_lines(SANE_Byte * buffer2,SANE_Int n_lines2,SANE_Byte * buffer1,SANE_Int n_lines1,SANE_Int color_idx,SANE_Int delta_lines,SANE_Bool color_48,unsigned int bytes_per_line)2374 shift_color_lines(SANE_Byte * buffer2, SANE_Int n_lines2, SANE_Byte * buffer1, SANE_Int n_lines1, SANE_Int color_idx, SANE_Int delta_lines, SANE_Bool color_48, unsigned int bytes_per_line)
2375 {
2376 DBG (DBG_proc, "%s\n", __func__);
2377 for (SANE_Int i = n_lines2 - 1; i >= 0; --i) {
2378 SANE_Byte * dst = buffer2 + i * bytes_per_line;
2379 SANE_Int ii = i - delta_lines;
2380 SANE_Byte * src = NULL;
2381 SANE_Int source_color_idx = color_idx;
2382 if (ii >= 0) {
2383 /* Read from source and target buffer. */
2384 src = buffer2 + ii * bytes_per_line;
2385 } else {
2386 ii += n_lines1;
2387 if (ii >= 0) {
2388 /* Read from source only buffer. */
2389 src = buffer1 + ii * bytes_per_line;
2390 } else {
2391 /* Read other color from source position. */
2392 src = dst;
2393 source_color_idx = 2;
2394 }
2395 }
2396 /* Copy selected color values. */
2397 SANE_Int step = color_48 ? 2 : 1;
2398 SANE_Int stride = 3 * step;
2399 for (unsigned int pos = 0; pos < bytes_per_line; pos += stride) {
2400 SANE_Int p1 = pos + step * source_color_idx;
2401 SANE_Int p2 = pos + step * color_idx;
2402 dst[p2] = src[p1];
2403 if (color_48) {
2404 dst[p2 + 1] = src[p1 + 1];
2405 }
2406 }
2407 }
2408 }
2409
2410 /******************************************************************************
2411 * Append all lines from buffer2 to the end of buffer1 and keep max_lines last
2412 * lines.
2413 * buffer2 : Source line buffer.
2414 * buffer1 : Target line buffer. Length will be adjusted.
2415 * max_lines : Max number of lines in buffer1.
2416 */
2417 static void
append_and_move_lines(SANE_Byte * buffer2,SANE_Int n_lines2,SANE_Byte * buffer1,unsigned int * n_lines1_ptr,SANE_Int max_lines,unsigned int bytes_per_line)2418 append_and_move_lines(SANE_Byte * buffer2, SANE_Int n_lines2, SANE_Byte * buffer1, unsigned int * n_lines1_ptr, SANE_Int max_lines, unsigned int bytes_per_line)
2419 {
2420 DBG (DBG_proc, "%s\n", __func__);
2421 SANE_Int rest1 = max_lines - *n_lines1_ptr;
2422 SANE_Int copy2 = MY_MIN(n_lines2, max_lines);
2423 if (copy2 > rest1) {
2424 SANE_Int shift1 = *n_lines1_ptr + copy2 - max_lines;
2425 SANE_Int blen = MY_MIN(max_lines - shift1, (SANE_Int) *n_lines1_ptr);
2426 SANE_Byte * pdst = buffer1;
2427 SANE_Byte * psrc = pdst + shift1 * bytes_per_line;
2428 for (SANE_Int i = 0; i < blen; ++i) {
2429 memcpy (pdst, psrc, bytes_per_line);
2430 pdst += bytes_per_line;
2431 psrc += bytes_per_line;
2432 }
2433 *n_lines1_ptr -= shift1;
2434 }
2435 SANE_Int n_copied = copy_n_last_lines(buffer2, n_lines2, buffer1 + *n_lines1_ptr * bytes_per_line, copy2, bytes_per_line);
2436 *n_lines1_ptr += n_copied;
2437 }
2438
2439
2440 /******************************************************************************/
2441 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * data,SANE_Int max_length,SANE_Int * length)2442 sane_read (SANE_Handle handle, SANE_Byte * data,
2443 SANE_Int max_length, SANE_Int * length)
2444 {
2445 struct hp5590_scanner *scanner = handle;
2446 SANE_Status ret;
2447
2448 DBG (DBG_proc, "%s, length %u, left %llu\n",
2449 __func__,
2450 max_length,
2451 scanner->transferred_image_size);
2452
2453 if (!length)
2454 {
2455 scanner->scanning = SANE_FALSE;
2456 return SANE_STATUS_INVAL;
2457 }
2458
2459 if (scanner->transferred_image_size == 0)
2460 {
2461 *length = 0;
2462 DBG (DBG_verbose, "Setting scan count\n");
2463
2464 ret = hp5590_inc_scan_count (scanner->dn, scanner->proto_flags);
2465 if (ret != SANE_STATUS_GOOD)
2466 return ret;
2467
2468 /* Don't free bulk read state, some bytes could be left
2469 * for the next images from ADF
2470 */
2471 return SANE_STATUS_EOF;
2472 }
2473
2474 if (!scanner->bulk_read_state)
2475 {
2476 ret = hp5590_low_init_bulk_read_state (&scanner->bulk_read_state);
2477 if (ret != SANE_STATUS_GOOD)
2478 {
2479 scanner->scanning = SANE_FALSE;
2480 return ret;
2481 }
2482 }
2483
2484 unsigned int bytes_per_line;
2485 ret = calc_image_params (scanner,
2486 NULL, NULL,
2487 &bytes_per_line,
2488 NULL, NULL);
2489 if (ret != SANE_STATUS_GOOD)
2490 return ret;
2491
2492 ret = sane_read_internal(scanner, data, max_length, length, bytes_per_line);
2493
2494 if ((ret == SANE_STATUS_GOOD) && (scanner->dpi == 2400) &&
2495 ((scanner->depth == DEPTH_COLOR_48) || (scanner->depth == DEPTH_COLOR_24)))
2496 {
2497 /* Correct color shift bug for 2400 dpi.
2498 * Note: 2400 dpi only works in color mode. Grey mode and lineart seem to
2499 * fail.
2500 * Align colors by shifting B channel by 48 lines and G channel by 24
2501 * lines.
2502 */
2503 const SANE_Int offset_max = 48;
2504 const SANE_Int offset_part = 24;
2505 SANE_Bool color_48 = (scanner->depth == DEPTH_COLOR_48);
2506
2507 if (! scanner->color_shift_line_buffer1)
2508 {
2509 scanner->color_shift_buffered_lines1 = 0;
2510 scanner->color_shift_line_buffer1 = malloc (bytes_per_line * offset_max);
2511 if (! scanner->color_shift_line_buffer1)
2512 return SANE_STATUS_NO_MEM;
2513 memset (scanner->color_shift_line_buffer1, 0, bytes_per_line * offset_max);
2514 }
2515 if (! scanner->color_shift_line_buffer2)
2516 {
2517 scanner->color_shift_buffered_lines2 = 0;
2518 scanner->color_shift_line_buffer2 = malloc (bytes_per_line * offset_max);
2519 if (! scanner->color_shift_line_buffer2)
2520 return SANE_STATUS_NO_MEM;
2521 memset (scanner->color_shift_line_buffer2, 0, bytes_per_line * offset_max);
2522 }
2523
2524 SANE_Int n_lines = *length / bytes_per_line;
2525 scanner->color_shift_buffered_lines2 = MY_MIN(n_lines, offset_max);
2526 copy_n_last_lines(data, n_lines, scanner->color_shift_line_buffer2, scanner->color_shift_buffered_lines2, bytes_per_line);
2527
2528 shift_color_lines(data, n_lines, scanner->color_shift_line_buffer1, scanner->color_shift_buffered_lines1, 1, offset_part, color_48, bytes_per_line);
2529 shift_color_lines(data, n_lines, scanner->color_shift_line_buffer1, scanner->color_shift_buffered_lines1, 0, offset_max, color_48, bytes_per_line);
2530
2531 append_and_move_lines(scanner->color_shift_line_buffer2, scanner->color_shift_buffered_lines2, scanner->color_shift_line_buffer1, &(scanner->color_shift_buffered_lines1), offset_max, bytes_per_line);
2532 }
2533
2534 return ret;
2535 }
2536
2537 /******************************************************************************/
2538 void
sane_cancel(SANE_Handle handle)2539 sane_cancel (SANE_Handle handle)
2540 {
2541 struct hp5590_scanner *scanner = handle;
2542 SANE_Status ret;
2543
2544 DBG (DBG_proc, "%s\n", __func__);
2545
2546 scanner->scanning = SANE_FALSE;
2547
2548 if (scanner->dn < 0)
2549 return;
2550
2551 hp5590_low_free_bulk_read_state (&scanner->bulk_read_state);
2552
2553 ret = hp5590_stop_scan (scanner->dn, scanner->proto_flags);
2554 if (ret != SANE_STATUS_GOOD)
2555 return;
2556 }
2557
2558 /******************************************************************************/
2559
2560 SANE_Status
sane_set_io_mode(SANE_Handle __sane_unused__ handle,SANE_Bool __sane_unused__ non_blocking)2561 sane_set_io_mode (SANE_Handle __sane_unused__ handle,
2562 SANE_Bool __sane_unused__ non_blocking)
2563 {
2564 DBG (DBG_proc, "%s\n", __func__);
2565
2566 return SANE_STATUS_UNSUPPORTED;
2567 }
2568
2569 /******************************************************************************/
2570 SANE_Status
sane_get_select_fd(SANE_Handle __sane_unused__ handle,SANE_Int __sane_unused__ * fd)2571 sane_get_select_fd (SANE_Handle __sane_unused__ handle,
2572 SANE_Int __sane_unused__ * fd)
2573 {
2574 DBG (DBG_proc, "%s\n", __func__);
2575
2576 return SANE_STATUS_UNSUPPORTED;
2577 }
2578
2579 /* vim: sw=2 ts=8
2580 */
2581