• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * SANE - Scanner Access Now Easy.
3 
4    avision.h
5 
6    This file is part of the SANE package.
7 
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 
21    As a special exception, the authors of SANE give permission for
22    additional uses of the libraries contained in this release of SANE.
23 
24    The exception is that, if you link a SANE library with other files
25    to produce an executable, this does not by itself cause the
26    resulting executable to be covered by the GNU General Public
27    License.  Your use of that executable is in no way restricted on
28    account of linking the SANE library code into it.
29 
30    This exception does not, however, invalidate any other reasons why
31    the executable file might be covered by the GNU General Public
32    License.
33 
34    If you submit changes to SANE to the maintainers to be included in
35    a subsequent release, you agree by submitting the changes that
36    those changes may be distributed with this exception intact.
37 
38    *****************************************************************************
39 
40    This backend is based upon the Tamarack backend and adapted to the Avision
41    scanners by René Rebe and Meino Cramer.
42 
43    Check the avision.c file for detailed copyright and change-log
44    information.
45 
46 ********************************************************************************/
47 
48 #ifndef avision_h
49 #define avision_h
50 
51 #ifdef HAVE_STDINT_H
52 # include <stdint.h>            /* available in ISO C99 */
53 #else
54 # include <sys/types.h>
55 typedef uint8_t uint8_t;
56 typedef uint16_t uint16_t;
57 typedef uint32_t uint32_t;
58 #endif /* HAVE_STDINT_H */
59 
60 #ifndef PATH_MAX
61 # define PATH_MAX 1024
62 #endif
63 
64 typedef enum Avision_ConnectionType {
65   AV_SCSI,
66   AV_USB
67 } Avision_ConnectionType;
68 
69 /*
70  * Translatable custom options text.
71  *
72  */
73 #define SANE_TITLE_MISC_GROUP             SANE_I18N("Miscellaneous")
74 #define SANE_TITLE_INSTALLED_OPTS_GROUP   SANE_I18N("Installed options")
75 
76 #define SANE_TITLE_OVERSCAN_TOP           SANE_I18N("Overscan top")
77 #define SANE_TITLE_OVERSCAN_BOTTOM        SANE_I18N("Overscan bottom")
78 #define SANE_TITLE_BACKGROUND_LINES       SANE_I18N("Background raster lines")
79 #define SANE_TITLE_QUALITY_SCAN           SANE_I18N("Quality scan")
80 #define SANE_TITLE_MANUAL_EXPOSURE        SANE_I18N("Exposure")
81 #define SANE_TITLE_MULTI_SAMPLE           SANE_I18N("Multi-sample")
82 #define SANE_TITLE_POWER_SAVE_TIME        SANE_I18N("Power save timer control")
83 #define SANE_TITLE_OPTIONS_MSG            SANE_I18N("Message text from the scanner")
84 #define SANE_TITLE_NVRAM                  SANE_I18N("Obtain NVRAM values")
85 #define SANE_TITLE_PAPER_LENGTH           SANE_I18N("Use paper length")
86 #define SANE_TITLE_FLIP_PAGE              SANE_I18N("Flip document after duplex scanning")
87 #define SANE_TITLE_ADF_INSTALLED          SANE_I18N("ADF installed")
88 #define SANE_TITLE_LIGHTBOX_INSTALLED     SANE_I18N("Lightbox installed")
89 
90 #define SANE_DESC_OVERSCAN_TOP            \
91 SANE_I18N("The top overscan controls the additional area to scan before the "\
92           "paper is detected.")
93 #define SANE_DESC_OVERSCAN_BOTTOM         \
94 SANE_I18N("The bottom overscan controls the additional area to scan after "\
95           "the paper end is detected.")
96 #define SANE_DESC_BACKGROUND_LINES        \
97 SANE_I18N("The background raster controls the additional background lines to "\
98           "scan before the paper is feed through the scanner.")
99 #define SANE_DESC_QUALITY_SCAN            \
100 SANE_I18N("Turn on quality scanning (slower but better).")
101 #define SANE_DESC_MANUAL_EXPOSURE         \
102 SANE_I18N("Manual exposure adjustment.")
103 #define SANE_DESC_MULTI_SAMPLE            \
104 SANE_I18N("Enable multi-sample scan mode.")
105 #define SANE_DESC_POWER_SAVE_TIME         \
106 SANE_I18N("Allows control of the scanner's power save timer, dimming or "\
107           "turning off the light.")
108 #define SANE_DESC_OPTIONS_MSG             \
109 SANE_I18N("This text contains device specific options controlled by the "\
110           "user on the scanner hardware.")
111 #define SANE_DESC_NVRAM                   \
112 SANE_I18N("Allows access obtaining the scanner's NVRAM values as pretty "\
113           "printed text.")
114 #define SANE_DESC_PAPER_LENGTH            \
115 SANE_I18N("Newer scanners can utilize this paper length to detect double feeds. "\
116           "However some others (DM152) can get confused during media flush if it is set.")
117 #define SANE_DESC_FLIP_PAGE               \
118 SANE_I18N("Tells page-flipping document scanners to flip the paper back to its "\
119           "original orientation before dropping it in the output tray.  "\
120           "Turning this off might make scanning a little faster if you don't "\
121           "care about manually flipping the pages afterwards.")
122 #define SANE_DESC_ADF_INSTALLED           \
123 SANE_I18N("ADF option is detected as installed.")
124 #define SANE_DESC_LIGHTBOX_INSTALLED      \
125 SANE_I18N("Lightbox option is detected as installed.")
126 
127 
128 /* information needed for device access */
129 typedef struct Avision_Connection {
130   Avision_ConnectionType connection_type;
131   int scsi_fd;			/* SCSI filedescriptor */
132   SANE_Int usb_dn;		/* USB (libusb or scanner.c) device number */
133   enum {
134     AVISION_USB_UNTESTED_STATUS, /* status type untested */
135     AVISION_USB_INT_STATUS,      /* interrupt endp. (USB 1.x device) status */
136     AVISION_USB_BULK_STATUS      /* bulk endp. (USB 2.0 device) status */
137   } usb_status;
138 
139 } Avision_Connection;
140 
141 /* structure for ADF offsets in mm */
142 typedef struct mm_offset {
143   double top;
144   double bottom;
145 } mm_offset;
146 
147 typedef struct Avision_HWEntry {
148   const char* scsi_mfg;
149   const char* scsi_model;
150 
151   int   usb_vendor;
152   int   usb_product;
153 
154   const char* real_mfg;
155   const char* real_model;
156 
157   /* feature overwrites - as embedded CPUs have 16bit enums - this
158      would need a change ... */
159     /* force no calibration */
160   #define AV_NO_CALIB ((uint64_t)1<<0)
161 
162     /* force all in one command calibration */
163   #define AV_ONE_CALIB_CMD ((uint64_t)1<<1)
164 
165     /* no gamma table */
166   #define AV_NO_GAMMA ((uint64_t)1<<2)
167 
168     /* light check is bogus */
169   #define AV_LIGHT_CHECK_BOGUS ((uint64_t)1<<3)
170 
171     /* no button though the device advertise it */
172   #define AV_NO_BUTTON ((uint64_t)1<<4)
173 
174     /* if the scan area needs to be forced to A3 */
175   #define AV_FORCE_A3 ((uint64_t)1<<5)
176 
177     /* if the scan area and resolution needs to be forced for films */
178   #define AV_FORCE_FILM ((uint64_t)1<<6)
179 
180     /* does not support, or very broken background (added for AV610C2) */
181   #define AV_NO_BACKGROUND ((uint64_t)1<<7)
182 
183     /* is film scanner - no detection yet */
184   #define AV_FILMSCANNER ((uint64_t)1<<8)
185 
186     /* fujitsu adaption */
187   #define AV_FUJITSU ((uint64_t)1<<9)
188 
189     /* gray calibration data has to be uploaded on the blue channel ... ? */
190   #define AV_GRAY_CALIB_BLUE ((uint64_t)1<<10)
191 
192     /* Interrupt endpoint button readout (so far AV220) */
193   #define AV_INT_BUTTON ((uint64_t)1<<11)
194 
195     /* send acceleration table ... */
196   #define AV_ACCEL_TABLE ((uint64_t)1<<12)
197 
198     /* non-interlaced scanns up to 300 dpi (AV32xx / AV83xx) */
199   #define AV_NON_INTERLACED_DUPLEX_300 ((uint64_t)1<<13)
200 
201     /* do not read multiples of 64 bytes - stalls the USB chip */
202   #define AV_NO_64BYTE_ALIGN ((uint64_t)1<<14)
203 
204     /* force channel-by-channel calibration */
205   #define AV_MULTI_CALIB_CMD ((uint64_t)1<<15)
206 
207     /* non color scans are faster with a filter applied (AV32xx) */
208   #define AV_FASTER_WITH_FILTER ((uint64_t)1<<16)
209 
210     /* interlaced data with 1 line distance */
211   #define AV_2ND_LINE_INTERLACED ((uint64_t)1<<17)
212 
213     /* does not keep the window though it advertices so */
214   #define AV_DOES_NOT_KEEP_WINDOW ((uint64_t)1<<18)
215 
216     /* does not keep the gamma though it advertices so */
217   #define AV_DOES_NOT_KEEP_GAMMA ((uint64_t)1<<19)
218 
219     /* advertises ADF is BGR order, but isn't (or vice versa) */
220   #define AV_ADF_BGR_ORDER_INVERT ((uint64_t)1<<20)
221 
222     /* allows 12bit mode, though not flagged */
223   #define AV_12_BIT_MODE ((uint64_t)1<<21)
224 
225     /* very broken background raster */
226   #define AV_BACKGROUND_QUIRK ((uint64_t)1<<22)
227 
228     /* though marked as GRAY only the scanner can do GRAY modes */
229   #define AV_GRAY_MODES ((uint64_t)1<<23)
230 
231     /* no separate, single REAR scan (AV122, DM152, ...) */
232   #define AV_NO_REAR ((uint64_t)1<<24)
233 
234     /* only scan with some known good hardware resolutions, as the
235        scanner fails to properly interpoloate in between (e.g.  AV121,
236        DM152 on duplex scans - but also the AV600), software scale and
237        interpolate to all the others */
238   #define AV_SOFT_SCALE ((uint64_t)1<<25)
239 
240     /* does keep window though it does not advertise it - the AV122/DM152
241        mess up image data if window is resend between ADF pages */
242   #define AV_DOES_KEEP_WINDOW ((uint64_t)1<<26)
243 
244     /* does keep gamma though it does not advertise it */
245   #define AV_DOES_KEEP_GAMMA ((uint64_t)1<<27)
246 
247     /* does the scanner contain a Cancel button? */
248   #define AV_CANCEL_BUTTON ((uint64_t)1<<28)
249 
250     /* some devices do not need a START_SCAN, even hang with it */
251   #define AV_NO_START_SCAN ((uint64_t)1<<30)
252 
253   #define AV_INT_STATUS ((uint64_t)1<<31)
254 
255     /* force no calibration */
256   #define AV_NO_TUNE_SCAN_LENGTH ((uint64_t)1<<32)
257 
258     /* for gray scans, set grey filter */
259   #define AV_USE_GRAY_FILTER ((uint64_t)1<<33)
260 
261     /* For (HP) scanners with flipping duplexers */
262   #define AV_ADF_FLIPPING_DUPLEX ((uint64_t)1<<34)
263 
264     /* For scanners which need to have their firmware read to properly function. */
265   #define AV_FIRMWARE ((uint64_t)1<<35)
266 
267   /* at least Kodak i1120 claims no calibration needed but windows driver does it anyways */
268   #define AV_FORCE_CALIB ((uint64_t)1<<36)
269 
270   /* at least Kodak i1120 does not have an explicit "quality-scan" mode */
271   #define AV_NO_QSCAN_MODE ((uint64_t)1<<37)
272 
273   /* at least Kodak i1120 optical DPI is used for overscan calculation */
274   #define AV_OVERSCAN_OPTDPI ((uint64_t)1<<38)
275 
276   /* some scanners support fast feed-out of the sheet when cancelling a running scan */
277   #define AV_FASTFEED_ON_CANCEL ((uint64_t)1<<39)
278 
279   /* at least Kodak i1120 does not have an explicit "quality-calibration" mode */
280   #define AV_NO_QCALIB_MODE ((uint64_t)1<<40)
281 
282   /* Kodak i1120 needs gamma = 1.0 to give decent results */
283   #define AV_GAMMA_10 ((uint64_t)1<<41)
284 
285   /* Kodak i1120 has a different gamma table format (like a uint16/double array) */
286   #define AV_GAMMA_UINT16 ((uint64_t)1<<42)
287 
288   /* Kodak i1120 has single-sheet and multi-sheet scan modes. This option sets
289      bitset3[7] which enables multi-sheet scan by default so there is no pause
290      of 1s between two sheets in ADF scan mode. This also fixes some offsets
291      when scanning multiple sheets. */
292   #define AV_MULTI_SHEET_SCAN ((uint64_t)1<<43)
293 
294     /* maybe more ...*/
295   uint64_t feature_type;
296 
297   /* ADF offsets in mm */
298   struct {
299     float first; /* offset difference first sheet */
300     mm_offset front; /* front-only */
301     struct {
302       mm_offset front;
303       mm_offset rear;
304     } duplex;
305   } offset;
306 
307 } Avision_HWEntry;
308 
309 typedef enum {
310   AV_ASIC_Cx = 0,
311   AV_ASIC_C1 = 1,
312   AV_ASIC_W1 = 2,
313   AV_ASIC_C2 = 3,
314   AV_ASIC_C5 = 5,
315   AV_ASIC_C6 = 6,
316   AV_ASIC_C7 = 7,
317   AV_ASIC_OA980 = 128,
318   AV_ASIC_OA982 = 129
319 } asic_type;
320 
321 typedef enum {
322   AV_THRESHOLDED,
323   AV_DITHERED,
324   AV_GRAYSCALE,       /* all gray needs to be before color for is_color() */
325   AV_GRAYSCALE12,
326   AV_GRAYSCALE16,
327   AV_TRUECOLOR,
328   AV_TRUECOLOR12,
329   AV_TRUECOLOR16,
330   AV_COLOR_MODE_LAST
331 } color_mode;
332 
333 typedef enum {
334   AV_NORMAL,
335   AV_TRANSPARENT,
336   AV_ADF,
337   AV_ADF_REAR,
338   AV_ADF_DUPLEX,
339   AV_SOURCE_MODE_LAST
340 } source_mode;
341 
342 typedef enum {
343   AV_NORMAL_DIM,
344   AV_TRANSPARENT_DIM,
345   AV_ADF_DIM,
346   AV_SOURCE_MODE_DIM_LAST
347 } source_mode_dim;
348 
349 enum Avision_Option
350 {
351   OPT_NUM_OPTS = 0,      /* must come first */
352 
353   OPT_MODE_GROUP,
354   OPT_MODE,
355   OPT_RESOLUTION,
356 #define OPT_RESOLUTION_DEFAULT 150
357   OPT_SPEED,
358   OPT_PREVIEW,
359 
360   OPT_SOURCE,            /* scan source normal, transparency, ADF */
361 
362   OPT_GEOMETRY_GROUP,
363   OPT_TL_X,	         /* top-left x */
364   OPT_TL_Y,	         /* top-left y */
365   OPT_BR_X,	         /* bottom-right x */
366   OPT_BR_Y,		 /* bottom-right y */
367 
368   OPT_OVERSCAN_TOP,      /* overscan for auto-crop/deskew, if supported */
369   OPT_OVERSCAN_BOTTOM,
370   OPT_BACKGROUND,        /* background raster lines to read out */
371 
372   OPT_ENHANCEMENT_GROUP,
373   OPT_BRIGHTNESS,
374   OPT_CONTRAST,
375   OPT_QSCAN,
376   OPT_QCALIB,
377 
378   OPT_GAMMA_VECTOR,      /* first must be gray */
379   OPT_GAMMA_VECTOR_R,    /* then r g b vector */
380   OPT_GAMMA_VECTOR_G,
381   OPT_GAMMA_VECTOR_B,
382 
383   OPT_EXPOSURE,          /* film exposure adjustment */
384   OPT_IR,                /* infra-red */
385   OPT_MULTISAMPLE,       /* multi-sample */
386 
387   OPT_MISC_GROUP,
388   OPT_FRAME,             /* Film holder control */
389 
390   OPT_POWER_SAVE_TIME,   /* set power save time to the scanner */
391 
392   OPT_MESSAGE,           /* optional message from the scanner display */
393   OPT_NVRAM,             /* retrieve NVRAM values as pretty printed text */
394 
395   OPT_PAPERLEN,          /* Use paper_length field to detect double feeds */
396   OPT_ADF_FLIP,          /* For flipping duplex, reflip the document */
397 
398   OPT_OPTIONS_GROUP,
399   OPT_OPTION_ADF,       // ADF installed/detected?
400   OPT_OPTION_LIGHTBOX,   // LightBox installed/detected?
401 
402   NUM_OPTIONS            /* must come last */
403 };
404 
405 /* structure for ADF offsets in pixels of HW res */
406 typedef struct hwpx_offset {
407   int top;
408   int bottom;
409 } hwpx_offset;
410 
411 
412 typedef struct Avision_Dimensions
413 {
414   /* in dpi */
415   int xres;
416   int yres;
417 
418   /* in pixels */
419   long tlx;
420   long tly;
421   long brx;
422   long bry;
423 
424   /* in pixels */
425   int line_difference;
426 
427   struct {
428     hwpx_offset front;
429     hwpx_offset rear;
430   } offset;
431 
432   /* interlaced duplex scan */
433   SANE_Bool interlaced_duplex;
434 
435   /* in dpi, likewise - different if software scaling required */
436   int hw_xres;
437   int hw_yres;
438 
439   int hw_pixels_per_line;
440   int hw_bytes_per_line;
441   int hw_lines;
442 
443 } Avision_Dimensions;
444 
445 /* this contains our low-level info - not relevant for the SANE interface  */
446 typedef struct Avision_Device
447 {
448   struct Avision_Device* next;
449   SANE_Device sane;
450   Avision_Connection connection;
451 
452   /* structs used to store config options */
453   SANE_Range dpi_range;
454   SANE_Range x_range;
455   SANE_Range y_range;
456   SANE_Range speed_range;
457 
458   asic_type inquiry_asic_type;
459   SANE_Bool inquiry_new_protocol;
460 
461   SANE_Bool inquiry_nvram_read;
462   SANE_Bool inquiry_power_save_time;
463 
464   SANE_Bool inquiry_adf_capability;
465   SANE_Bool inquiry_duplex;
466   SANE_Bool inquiry_duplex_interlaced;
467   SANE_Bool inquiry_paper_length;
468   SANE_Bool inquiry_batch_scan;
469   SANE_Bool inquiry_detect_accessories;
470   SANE_Bool inquiry_needs_calibration;
471   SANE_Bool inquiry_needs_gamma;
472   SANE_Bool inquiry_keeps_gamma;
473   SANE_Bool inquiry_keeps_window;
474   SANE_Bool inquiry_calibration;
475   SANE_Bool inquiry_3x3_matrix;
476   SANE_Bool inquiry_needs_software_colorpack;
477   SANE_Bool inquiry_needs_line_pack;
478   SANE_Bool inquiry_adf_need_mirror;
479   SANE_Bool inquiry_adf_bgr_order;
480   SANE_Bool inquiry_light_detect;
481   SANE_Bool inquiry_light_control;
482   SANE_Bool inquiry_exposure_control;
483 
484   // Determines from accessories query.
485   SANE_Bool inquiry_light_box_present;
486   SANE_Bool inquiry_adf_present;
487 
488   int       inquiry_max_shading_target;
489   SANE_Bool inquiry_button_control;
490   unsigned int inquiry_buttons;
491   SANE_Bool inquiry_tune_scan_length;
492   SANE_Bool inquiry_background_raster;
493   int       inquiry_background_raster_pixel;
494 
495   enum {AV_FLATBED,
496 	AV_FILM,
497 	AV_SHEETFEED
498   } scanner_type;
499 
500   /* the list of available color modes */
501   SANE_String_Const color_list[AV_COLOR_MODE_LAST + 1];
502   color_mode color_list_num[AV_COLOR_MODE_LAST];
503   color_mode color_list_default;
504 
505   /* the list of available source modes */
506   SANE_String_Const source_list[AV_SOURCE_MODE_LAST + 1];
507   source_mode source_list_num[AV_SOURCE_MODE_LAST];
508 
509   int inquiry_optical_res;        /* in dpi */
510   int inquiry_max_res;            /* in dpi */
511 
512   double inquiry_x_ranges  [AV_SOURCE_MODE_DIM_LAST]; /* in mm */
513   double inquiry_y_ranges  [AV_SOURCE_MODE_DIM_LAST]; /* in mm */
514 
515   int inquiry_color_boundary;
516   int inquiry_gray_boundary;
517   int inquiry_dithered_boundary;
518   int inquiry_thresholded_boundary;
519   int inquiry_line_difference; /* software color pack */
520 
521   int inquiry_channels_per_pixel;
522   int inquiry_bits_per_channel;
523   int inquiry_no_gray_modes;
524 
525   SANE_Bool adf_offset_compensation;
526 
527   int scsi_buffer_size; /* nice to have SCSI buffer size */
528   int read_stripe_size; /* stripes to be read at-a-time */
529 
530   /* film scanner attributes - maybe these should be in the scanner struct? */
531   SANE_Range frame_range;
532   SANE_Word current_frame;
533   SANE_Word holder_type;
534 
535   /* some version corrections */
536   uint16_t data_dq; /* was ox0A0D - but hangs some new scanners */
537 
538   Avision_HWEntry* hw;
539 } Avision_Device;
540 
541 /* all the state relevant for the SANE interface */
542 typedef struct Avision_Scanner
543 {
544   struct Avision_Scanner* next;
545   Avision_Device* hw;
546 
547   SANE_Option_Descriptor opt [NUM_OPTIONS];
548   Option_Value val [NUM_OPTIONS];
549   SANE_Int gamma_table [4][256];
550 
551   /* we now save the calib data because we might need it for 16bit software
552      calibration :-( */
553   uint8_t* dark_avg_data;
554   uint8_t* white_avg_data;
555 
556   /* background raster data, if duplex first front, then rear */
557   uint8_t* background_raster;
558 
559   /* Parsed option values and variables that are valid only during
560      the actual scan: */
561   SANE_Bool prepared;		/* first page marker */
562   SANE_Bool scanning;           /* scan in progress */
563   unsigned int page;            /* page counter, 0: uninitialized, 1: scanning 1st page, ... */
564   int cancelled;
565 
566   SANE_Parameters params;       /* scan window */
567   Avision_Dimensions avdimen;   /* scan window - detailed internals */
568 
569   /* Internal data for duplex scans */
570   char duplex_rear_fname [PATH_MAX];
571   SANE_Bool duplex_rear_valid;
572 
573   color_mode c_mode;
574   source_mode source_mode;
575   source_mode_dim source_mode_dim;
576 
577   /* Avision HW Access Connection (SCSI/USB abstraction) */
578   Avision_Connection av_con;
579 
580   SANE_Pid reader_pid;	/* process id of reader */
581   int read_fds;		/* pipe reading end */
582   int write_fds;	/* pipe writing end */
583 
584 } Avision_Scanner;
585 
586 /* Some Avision driver internal defines */
587 #define AV_WINID 0
588 
589 /* Avision SCSI over USB error codes */
590 #define AVISION_USB_GOOD                    0x00
591 #define AVISION_USB_REQUEST_SENSE           0x02
592 #define AVISION_USB_BUSY                    0x08
593 
594 /* SCSI commands that the Avision scanners understand: */
595 
596 #define AVISION_SCSI_TEST_UNIT_READY        0x00
597 #define AVISION_SCSI_REQUEST_SENSE          0x03
598 #define AVISION_SCSI_MEDIA_CHECK            0x08
599 #define AVISION_SCSI_INQUIRY                0x12
600 #define AVISION_SCSI_MODE_SELECT            0x15
601 #define AVISION_SCSI_RESERVE_UNIT           0x16
602 #define AVISION_SCSI_RELEASE_UNIT           0x17
603 #define AVISION_SCSI_SCAN                   0x1b
604 #define AVISION_SCSI_SET_WINDOW             0x24
605 #define AVISION_SCSI_READ                   0x28
606 #define AVISION_SCSI_SEND                   0x2a
607 #define AVISION_SCSI_OBJECT_POSITION        0x31
608 #define AVISION_SCSI_GET_DATA_STATUS        0x34
609 
610 #define AVISION_SCSI_OP_REJECT_PAPER        0x00
611 #define AVISION_SCSI_OP_LOAD_PAPER          0x01
612 #define AVISION_SCSI_OP_GO_HOME             0x02
613 #define AVISION_SCSI_OP_TRANS_CALIB_GRAY    0x04
614 #define AVISION_SCSI_OP_TRANS_CALIB_COLOR   0x05
615 
616 /* These apply to bitset1.  The values are 0 to 6, shifted 3 bits to the left */
617 #define AVISION_FILTER_NONE	0x00
618 #define AVISION_FILTER_RED	0x08
619 #define AVISION_FILTER_GREEN	0x10
620 #define AVISION_FILTER_BLUE	0x18
621 #define AVISION_FILTER_RGB	0x20
622 #define AVISION_FILTER_CMYK	0x28
623 #define AVISION_FILTER_GRAY	0x30
624 
625 /* The SCSI structures that we have to send to an avision to get it to
626    do various stuff... */
627 
628 typedef struct command_header
629 {
630   uint8_t opc;
631   uint8_t pad0 [3];
632   uint8_t len;
633   uint8_t pad1;
634 } command_header;
635 
636 typedef struct command_set_window
637 {
638   uint8_t opc;
639   uint8_t reserved0 [5];
640   uint8_t transferlen [3];
641   uint8_t control;
642 } command_set_window;
643 
644 typedef struct command_read
645 {
646   uint8_t opc;
647   uint8_t bitset1;
648   uint8_t datatypecode;
649   uint8_t readtype;
650   uint8_t datatypequal [2];
651   uint8_t transferlen [3];
652   uint8_t control;
653 } command_read;
654 
655 typedef struct command_scan
656 {
657   uint8_t opc;
658   uint8_t bitset0;
659   uint8_t reserved0 [2];
660   uint8_t transferlen;
661   uint8_t bitset1;
662 } command_scan;
663 
664 typedef struct command_send
665 {
666   uint8_t opc;
667   uint8_t bitset1;
668   uint8_t datatypecode;
669   uint8_t reserved0;
670   uint8_t datatypequal [2];
671   uint8_t transferlen [3];
672   uint8_t reserved1;
673 } command_send;
674 
675 typedef struct firmware_status
676 {
677   uint8_t download_firmware;
678   uint8_t first_effective_pixel_flatbed [2];
679   uint8_t first_effective_pixel_adf_front [2];
680   uint8_t first_effective_pixel_adf_rear [2];
681   uint8_t reserved;
682 } firmware_status;
683 
684 typedef struct nvram_data
685 {
686   uint8_t pad_scans [4];
687   uint8_t adf_simplex_scans [4];
688   uint8_t adf_duplex_scans [4];
689   uint8_t flatbed_scans [4];
690 
691   uint8_t flatbed_leading_edge [2];
692   uint8_t flatbed_side_edge [2];
693   uint8_t adf_leading_edge [2];
694   uint8_t adf_side_edge [2];
695   uint8_t adf_rear_leading_edge [2];
696   uint8_t adf_rear_side_edge [2];
697 
698   uint8_t born_month [2];
699   uint8_t born_day [2];
700   uint8_t born_year [2];
701 
702   uint8_t first_scan_month [2];
703   uint8_t first_scan_day [2];
704   uint8_t first_scan_year [2];
705 
706   uint8_t vertical_magnification [2];
707   uint8_t horizontal_magnification [2];
708 
709   uint8_t ccd_type;
710   uint8_t scan_speed;
711 
712   char     serial [24];
713 
714   uint8_t power_saving_time [2];
715 
716   uint8_t auto_feed;
717   uint8_t roller_count [4];
718   uint8_t multifeed_count [4];
719   uint8_t jam_count [4];
720 
721   uint8_t reserved;
722   char     identify_info[16];
723   char     formal_name[16];
724 
725   uint8_t reserved2 [10];
726 } nvram_data;
727 
728 typedef struct command_set_window_window
729 {
730   struct {
731     uint8_t reserved0 [6];
732     uint8_t desclen [2];
733   } header;
734 
735   struct {
736     uint8_t winid;
737     uint8_t reserved0;
738     uint8_t xres [2];
739     uint8_t yres [2];
740     uint8_t ulx [4];
741     uint8_t uly [4];
742     uint8_t width [4];
743     uint8_t length [4];
744     uint8_t brightness;
745     uint8_t threshold;
746     uint8_t contrast;
747     uint8_t image_comp;
748     uint8_t bpc;
749     uint8_t halftone [2];
750     uint8_t padding_and_bitset;
751     uint8_t bitordering [2];
752     uint8_t compr_type;
753     uint8_t compr_arg;
754     uint8_t paper_length[2];
755     uint8_t reserved1 [4];
756 
757     /* Avision specific parameters */
758     uint8_t vendor_specific;
759     uint8_t paralen; /* bytes following after this byte */
760   } descriptor;
761 
762   struct {
763     uint8_t bitset1;
764     uint8_t highlight;
765     uint8_t shadow;
766     uint8_t line_width [2];
767     uint8_t line_count [2];
768 
769     /* the tail is quite version and model specific */
770     union {
771       struct {
772 	uint8_t bitset2;
773 	uint8_t reserved;
774       } old;
775 
776       struct {
777 	uint8_t bitset2;
778 	uint8_t ir_exposure_time;
779 
780 	/* optional */
781 	uint8_t r_exposure_time [2];
782 	uint8_t g_exposure_time [2];
783 	uint8_t b_exposure_time [2];
784 
785 	uint8_t bitset3; /* reserved in the v2 */
786 	uint8_t auto_focus;
787 	uint8_t line_width_msb;
788 	uint8_t line_count_msb;
789 	uint8_t background_lines;
790 
791 	uint8_t single_sheet_scan; /* from Kodak SVT tool */
792       } normal;
793 
794       struct {
795 	uint8_t reserved0 [4];
796 	uint8_t paper_size;
797 	uint8_t paperx [4];
798 	uint8_t papery [4];
799 	uint8_t reserved1 [2];
800       } fujitsu;
801     } type;
802   } avision;
803 } command_set_window_window;
804 
805 typedef struct page_header
806 {
807   uint8_t pad0 [4];
808   uint8_t code;
809   uint8_t length;
810 } page_header;
811 
812 typedef struct avision_page
813 {
814   uint8_t gamma;
815   uint8_t thresh;
816   uint8_t masks;
817   uint8_t delay;
818   uint8_t features;
819   uint8_t pad0;
820 } avision_page;
821 
822 typedef struct calibration_format
823 {
824   uint16_t pixel_per_line;
825   uint8_t bytes_per_channel;
826   uint8_t lines;
827   uint8_t flags;
828   uint8_t ability1;
829   uint8_t r_gain;
830   uint8_t g_gain;
831   uint8_t b_gain;
832   uint16_t r_shading_target;
833   uint16_t g_shading_target;
834   uint16_t b_shading_target;
835   uint16_t r_dark_shading_target;
836   uint16_t g_dark_shading_target;
837   uint16_t b_dark_shading_target;
838 
839   /* not returned but useful in some places */
840   uint8_t channels;
841 } calibration_format;
842 
843 typedef struct matrix_3x3
844 {
845   uint16_t v[9];
846 } matrix_3x3;
847 
848 typedef struct acceleration_info
849 {
850   uint16_t total_steps;
851   uint16_t stable_steps;
852   uint32_t table_units;
853   uint32_t base_units;
854   uint16_t start_speed;
855   uint16_t target_speed;
856   uint8_t ability;
857   uint8_t table_count;
858   uint8_t reserved[6];
859 } acceleration_info;
860 
861 /* set/get SCSI highended (big-endian) variables. Declare them as an array
862  * of chars endianness-safe, int-size safe ... */
863 #define set_double(var,val) var[0] = (uint8_t) (((val) >> 8) & 0xff);  \
864                             var[1] = (uint8_t) (((val)     ) & 0xff)
865 
866 #define set_triple(var,val) var[0] = (uint8_t) (((val) >> 16) & 0xff); \
867                             var[1] = (uint8_t) (((val) >> 8 ) & 0xff); \
868                             var[2] = (uint8_t) (((val)      ) & 0xff)
869 
870 #define set_quad(var,val)   var[0] = (uint8_t) (((val) >> 24) & 0xff); \
871                             var[1] = (uint8_t) (((val) >> 16) & 0xff); \
872                             var[2] = (uint8_t) (((val) >> 8 ) & 0xff); \
873                             var[3] = (uint8_t) (((val)      ) & 0xff)
874 
875 #define get_double(var) ((*var << 8) + *(var + 1))
876 
877 #define get_triple(var) ((*var << 16) + \
878                          (*(var + 1) << 8) + *(var + 2))
879 
880 #define get_quad(var)   ((*var << 24) + \
881                          (*(var + 1) << 16) + \
882                          (*(var + 2) << 8) + *(var + 3))
883 
884 /* set/get Avision lowended (little-endian) shading data */
885 #define set_double_le(var,val) var[0] = (uint8_t) (((val)     ) & 0xff);  \
886                                var[1] = (uint8_t) (((val) >> 8) & 0xff)
887 
888 #define get_double_le(var) ((uint16_t) ((*(var + 1) << 8) + *(var)))
889 
890 #define BIT(n, p) ((n & (1 << p)) ? 1 : 0)
891 
892 #define SET_BIT(n, p) (n |= (1 << p))
893 #define CLEAR_BIT(n, p) (n &= ~(1 << p))
894 
895 /* These should be in saneopts.h */
896 #define SANE_NAME_FRAME "frame"
897 #define SANE_TITLE_FRAME SANE_I18N("Number of the frame to scan")
898 #define SANE_DESC_FRAME  SANE_I18N("Selects the number of the frame to scan")
899 
900 #define SANE_NAME_DUPLEX "duplex"
901 #define SANE_TITLE_DUPLEX SANE_I18N("Duplex scan")
902 #define SANE_DESC_DUPLEX SANE_I18N("Duplex scan provides a scan of the front and back side of the document")
903 
904 #ifdef AVISION_ENHANCED_SANE
905 #warning "Compiled Avision backend will violate the SANE standard"
906 /* Some Avision SANE extensions */
907 typedef enum
908 {
909   SANE_STATUS_LAMP_WARMING = SANE_STATUS_ACCESS_DENIED + 1	/* lamp is warming up */
910 }
911 SANE_Avision_Status;
912 
913 /* public API extension */
914 
915 extern SANE_Status ENTRY(media_check) (SANE_Handle handle);
916 
917 #endif
918 
919 typedef enum
920 {
921   AVISION_DATATYPECODE_READ_IMAGE_DATA = 0x00,
922   AVISION_DATATYPECODE_GET_CALIBRATION_FORMAT = 0x60,
923   AVISION_DATATYPECODE_DETECT_ACCESSORIES = 0x64,
924   AVISION_DATATYPECODE_READ_NVRAM_DATA = 0x69,
925   AVISION_DATATYPECODE_FLASH_RAM_INFO = 0x6a,
926   AVISION_DATATYPECODE_ACCELERATION_TABLE = 0x6c,
927   AVISION_DATATYPECODE_DOWNLOAD_GAMMA_TABLE = 0x81,
928   AVISION_DATATYPECODE_3X3_COLOR_MATRIX = 0x83,
929   AVISION_DATATYPECODE_SEND_NVRAM_DATA = 0x85,
930   AVISION_DATATYPECODE_FLASH_DATA = 0x86,
931   AVISION_DATATYPECODE_FILM_HOLDER_SENSE = 0x87,
932   AVISION_DATATYPECODE_FIRMWARE_STATUS = 0x90,
933   AVISION_DATATYPECODE_ATTACH_TRUNCATE_TAIL = 0x95,
934   AVISION_DATATYPECODE_ATTACH_TRUNCATE_HEAD = 0x96,
935   AVISION_DATATYPECODE_GET_BACKGROUND_RASTER = 0x9b,
936   AVISION_DATATYPECODE_LIGHT_STATUS = 0xa0,
937   AVISION_DATATYPECODE_BUTTON_STATUS = 0xa1,
938   AVISION_DATATYPECODE_POWER_SAVING_TIMER = 0xa2,
939   AVISION_DATATYPECODE_READ_DUPLEX_INFO = 0xb1,
940   AVISION_DATATYPECODE_UNKNOWN = 0xd0,
941   AVISION_DATATYPECODE_READ_GENERAL_ABILITY_PARAM = 0xd2,
942 } Avision_Datatypecode;
943 
944 #endif /* avision_h */
945