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