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   SANE_Bool duplex_rear_valid;
506 
507   color_mode c_mode;
508   source_mode source_mode;
509   source_mode_dim source_mode_dim;
510 
511   /* Avision HW Access Connection (SCSI/USB abstraction) */
512   Avision_Connection av_con;
513 
514   SANE_Pid reader_pid;	/* process id of reader */
515   int read_fds;		/* pipe reading end */
516   int write_fds;	/* pipe writing end */
517 
518 } Avision_Scanner;
519 
520 /* Some Avision driver internal defines */
521 #define AV_WINID 0
522 
523 /* Avision SCSI over USB error codes */
524 #define AVISION_USB_GOOD                    0x00
525 #define AVISION_USB_REQUEST_SENSE           0x02
526 #define AVISION_USB_BUSY                    0x08
527 
528 /* SCSI commands that the Avision scanners understand: */
529 
530 #define AVISION_SCSI_TEST_UNIT_READY        0x00
531 #define AVISION_SCSI_REQUEST_SENSE          0x03
532 #define AVISION_SCSI_MEDIA_CHECK            0x08
533 #define AVISION_SCSI_INQUIRY                0x12
534 #define AVISION_SCSI_MODE_SELECT            0x15
535 #define AVISION_SCSI_RESERVE_UNIT           0x16
536 #define AVISION_SCSI_RELEASE_UNIT           0x17
537 #define AVISION_SCSI_SCAN                   0x1b
538 #define AVISION_SCSI_SET_WINDOW             0x24
539 #define AVISION_SCSI_READ                   0x28
540 #define AVISION_SCSI_SEND                   0x2a
541 #define AVISION_SCSI_OBJECT_POSITION        0x31
542 #define AVISION_SCSI_GET_DATA_STATUS        0x34
543 
544 #define AVISION_SCSI_OP_REJECT_PAPER        0x00
545 #define AVISION_SCSI_OP_LOAD_PAPER          0x01
546 #define AVISION_SCSI_OP_GO_HOME             0x02
547 #define AVISION_SCSI_OP_TRANS_CALIB_GRAY    0x04
548 #define AVISION_SCSI_OP_TRANS_CALIB_COLOR   0x05
549 
550 /* These apply to bitset1.  The values are 0 to 6, shifted 3 bits to the left */
551 #define AVISION_FILTER_NONE	0x00
552 #define AVISION_FILTER_RED	0x08
553 #define AVISION_FILTER_GREEN	0x10
554 #define AVISION_FILTER_BLUE	0x18
555 #define AVISION_FILTER_RGB	0x20
556 #define AVISION_FILTER_CMYK	0x28
557 #define AVISION_FILTER_GRAY	0x30
558 
559 /* The SCSI structures that we have to send to an avision to get it to
560    do various stuff... */
561 
562 typedef struct command_header
563 {
564   uint8_t opc;
565   uint8_t pad0 [3];
566   uint8_t len;
567   uint8_t pad1;
568 } command_header;
569 
570 typedef struct command_set_window
571 {
572   uint8_t opc;
573   uint8_t reserved0 [5];
574   uint8_t transferlen [3];
575   uint8_t control;
576 } command_set_window;
577 
578 typedef struct command_read
579 {
580   uint8_t opc;
581   uint8_t bitset1;
582   uint8_t datatypecode;
583   uint8_t readtype;
584   uint8_t datatypequal [2];
585   uint8_t transferlen [3];
586   uint8_t control;
587 } command_read;
588 
589 typedef struct command_scan
590 {
591   uint8_t opc;
592   uint8_t bitset0;
593   uint8_t reserved0 [2];
594   uint8_t transferlen;
595   uint8_t bitset1;
596 } command_scan;
597 
598 typedef struct command_send
599 {
600   uint8_t opc;
601   uint8_t bitset1;
602   uint8_t datatypecode;
603   uint8_t reserved0;
604   uint8_t datatypequal [2];
605   uint8_t transferlen [3];
606   uint8_t reserved1;
607 } command_send;
608 
609 typedef struct firmware_status
610 {
611   uint8_t download_firmware;
612   uint8_t first_effective_pixel_flatbed [2];
613   uint8_t first_effective_pixel_adf_front [2];
614   uint8_t first_effective_pixel_adf_rear [2];
615   uint8_t reserved;
616 } firmware_status;
617 
618 typedef struct nvram_data
619 {
620   uint8_t pad_scans [4];
621   uint8_t adf_simplex_scans [4];
622   uint8_t adf_duplex_scans [4];
623   uint8_t flatbed_scans [4];
624 
625   uint8_t flatbed_leading_edge [2];
626   uint8_t flatbed_side_edge [2];
627   uint8_t adf_leading_edge [2];
628   uint8_t adf_side_edge [2];
629   uint8_t adf_rear_leading_edge [2];
630   uint8_t adf_rear_side_edge [2];
631 
632   uint8_t born_month [2];
633   uint8_t born_day [2];
634   uint8_t born_year [2];
635 
636   uint8_t first_scan_month [2];
637   uint8_t first_scan_day [2];
638   uint8_t first_scan_year [2];
639 
640   uint8_t vertical_magnification [2];
641   uint8_t horizontal_magnification [2];
642 
643   uint8_t ccd_type;
644   uint8_t scan_speed;
645 
646   char     serial [24];
647 
648   uint8_t power_saving_time [2];
649 
650   uint8_t auto_feed;
651   uint8_t roller_count [4];
652   uint8_t multifeed_count [4];
653   uint8_t jam_count [4];
654 
655   uint8_t reserved;
656   char     identify_info[16];
657   char     formal_name[16];
658 
659   uint8_t reserved2 [10];
660 } nvram_data;
661 
662 typedef struct command_set_window_window
663 {
664   struct {
665     uint8_t reserved0 [6];
666     uint8_t desclen [2];
667   } header;
668 
669   struct {
670     uint8_t winid;
671     uint8_t reserved0;
672     uint8_t xres [2];
673     uint8_t yres [2];
674     uint8_t ulx [4];
675     uint8_t uly [4];
676     uint8_t width [4];
677     uint8_t length [4];
678     uint8_t brightness;
679     uint8_t threshold;
680     uint8_t contrast;
681     uint8_t image_comp;
682     uint8_t bpc;
683     uint8_t halftone [2];
684     uint8_t padding_and_bitset;
685     uint8_t bitordering [2];
686     uint8_t compr_type;
687     uint8_t compr_arg;
688     uint8_t paper_length[2];
689     uint8_t reserved1 [4];
690 
691     /* Avision specific parameters */
692     uint8_t vendor_specific;
693     uint8_t paralen; /* bytes following after this byte */
694   } descriptor;
695 
696   struct {
697     uint8_t bitset1;
698     uint8_t highlight;
699     uint8_t shadow;
700     uint8_t line_width [2];
701     uint8_t line_count [2];
702 
703     /* the tail is quite version and model specific */
704     union {
705       struct {
706 	uint8_t bitset2;
707 	uint8_t reserved;
708       } old;
709 
710       struct {
711 	uint8_t bitset2;
712 	uint8_t ir_exposure_time;
713 
714 	/* optional */
715 	uint8_t r_exposure_time [2];
716 	uint8_t g_exposure_time [2];
717 	uint8_t b_exposure_time [2];
718 
719 	uint8_t bitset3; /* reserved in the v2 */
720 	uint8_t auto_focus;
721 	uint8_t line_width_msb;
722 	uint8_t line_count_msb;
723 	uint8_t background_lines;
724 
725 	uint8_t single_sheet_scan; /* from Kodak SVT tool */
726       } normal;
727 
728       struct {
729 	uint8_t reserved0 [4];
730 	uint8_t paper_size;
731 	uint8_t paperx [4];
732 	uint8_t papery [4];
733 	uint8_t reserved1 [2];
734       } fujitsu;
735     } type;
736   } avision;
737 } command_set_window_window;
738 
739 typedef struct page_header
740 {
741   uint8_t pad0 [4];
742   uint8_t code;
743   uint8_t length;
744 } page_header;
745 
746 typedef struct avision_page
747 {
748   uint8_t gamma;
749   uint8_t thresh;
750   uint8_t masks;
751   uint8_t delay;
752   uint8_t features;
753   uint8_t pad0;
754 } avision_page;
755 
756 typedef struct calibration_format
757 {
758   uint16_t pixel_per_line;
759   uint8_t bytes_per_channel;
760   uint8_t lines;
761   uint8_t flags;
762   uint8_t ability1;
763   uint8_t r_gain;
764   uint8_t g_gain;
765   uint8_t b_gain;
766   uint16_t r_shading_target;
767   uint16_t g_shading_target;
768   uint16_t b_shading_target;
769   uint16_t r_dark_shading_target;
770   uint16_t g_dark_shading_target;
771   uint16_t b_dark_shading_target;
772 
773   /* not returned but useful in some places */
774   uint8_t channels;
775 } calibration_format;
776 
777 typedef struct matrix_3x3
778 {
779   uint16_t v[9];
780 } matrix_3x3;
781 
782 typedef struct acceleration_info
783 {
784   uint16_t total_steps;
785   uint16_t stable_steps;
786   uint32_t table_units;
787   uint32_t base_units;
788   uint16_t start_speed;
789   uint16_t target_speed;
790   uint8_t ability;
791   uint8_t table_count;
792   uint8_t reserved[6];
793 } acceleration_info;
794 
795 /* set/get SCSI highended (big-endian) variables. Declare them as an array
796  * of chars endianness-safe, int-size safe ... */
797 #define set_double(var,val) var[0] = (uint8_t) (((val) >> 8) & 0xff);  \
798                             var[1] = (uint8_t) (((val)     ) & 0xff)
799 
800 #define set_triple(var,val) var[0] = (uint8_t) (((val) >> 16) & 0xff); \
801                             var[1] = (uint8_t) (((val) >> 8 ) & 0xff); \
802                             var[2] = (uint8_t) (((val)      ) & 0xff)
803 
804 #define set_quad(var,val)   var[0] = (uint8_t) (((val) >> 24) & 0xff); \
805                             var[1] = (uint8_t) (((val) >> 16) & 0xff); \
806                             var[2] = (uint8_t) (((val) >> 8 ) & 0xff); \
807                             var[3] = (uint8_t) (((val)      ) & 0xff)
808 
809 #define get_double(var) ((*var << 8) + *(var + 1))
810 
811 #define get_triple(var) ((*var << 16) + \
812                          (*(var + 1) << 8) + *(var + 2))
813 
814 #define get_quad(var)   ((*var << 24) + \
815                          (*(var + 1) << 16) + \
816                          (*(var + 2) << 8) + *(var + 3))
817 
818 /* set/get Avision lowended (little-endian) shading data */
819 #define set_double_le(var,val) var[0] = (uint8_t) (((val)     ) & 0xff);  \
820                                var[1] = (uint8_t) (((val) >> 8) & 0xff)
821 
822 #define get_double_le(var) ((uint16_t) ((*(var + 1) << 8) + *(var)))
823 
824 #define BIT(n, p) ((n & (1 << p)) ? 1 : 0)
825 
826 #define SET_BIT(n, p) (n |= (1 << p))
827 #define CLEAR_BIT(n, p) (n &= ~(1 << p))
828 
829 /* These should be in saneopts.h */
830 #define SANE_NAME_FRAME "frame"
831 #define SANE_TITLE_FRAME SANE_I18N("Number of the frame to scan")
832 #define SANE_DESC_FRAME  SANE_I18N("Selects the number of the frame to scan")
833 
834 #define SANE_NAME_DUPLEX "duplex"
835 #define SANE_TITLE_DUPLEX SANE_I18N("Duplex scan")
836 #define SANE_DESC_DUPLEX SANE_I18N("Duplex scan provides a scan of the front and back side of the document")
837 
838 #ifdef AVISION_ENHANCED_SANE
839 #warning "Compiled Avision backend will violate the SANE standard"
840 /* Some Avision SANE extensions */
841 typedef enum
842 {
843   SANE_STATUS_LAMP_WARMING = SANE_STATUS_ACCESS_DENIED + 1	/* lamp is warming up */
844 }
845 SANE_Avision_Status;
846 
847 /* public API extension */
848 
849 extern SANE_Status ENTRY(media_check) (SANE_Handle handle);
850 
851 #endif
852 
853 typedef enum
854 {
855   AVISION_DATATYPECODE_READ_IMAGE_DATA = 0x00,
856   AVISION_DATATYPECODE_GET_CALIBRATION_FORMAT = 0x60,
857   AVISION_DATATYPECODE_DETECT_ACCESSORIES = 0x64,
858   AVISION_DATATYPECODE_READ_NVRAM_DATA = 0x69,
859   AVISION_DATATYPECODE_FLASH_RAM_INFO = 0x6a,
860   AVISION_DATATYPECODE_ACCELERATION_TABLE = 0x6c,
861   AVISION_DATATYPECODE_DOWNLOAD_GAMMA_TABLE = 0x81,
862   AVISION_DATATYPECODE_3X3_COLOR_MATRIX = 0x83,
863   AVISION_DATATYPECODE_SEND_NVRAM_DATA = 0x85,
864   AVISION_DATATYPECODE_FLASH_DATA = 0x86,
865   AVISION_DATATYPECODE_FILM_HOLDER_SENSE = 0x87,
866   AVISION_DATATYPECODE_FIRMWARE_STATUS = 0x90,
867   AVISION_DATATYPECODE_ATTACH_TRUNCATE_TAIL = 0x95,
868   AVISION_DATATYPECODE_ATTACH_TRUNCATE_HEAD = 0x96,
869   AVISION_DATATYPECODE_GET_BACKGROUND_RASTER = 0x9b,
870   AVISION_DATATYPECODE_LIGHT_STATUS = 0xa0,
871   AVISION_DATATYPECODE_BUTTON_STATUS = 0xa1,
872   AVISION_DATATYPECODE_POWER_SAVING_TIMER = 0xa2,
873   AVISION_DATATYPECODE_READ_DUPLEX_INFO = 0xb1,
874   AVISION_DATATYPECODE_UNKNOWN = 0xd0,
875   AVISION_DATATYPECODE_READ_GENERAL_ABILITY_PARAM = 0xd2,
876 } Avision_Datatypecode;
877 
878 #endif /* avision_h */
879