• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *) &params->pixels_per_line,
1431                            (unsigned int *) &params->bytes_per_line,
1432                            (unsigned int *) &params->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