1 /*******************************************************************************
2 * SANE - Scanner Access Now Easy.
3
4 microtek2.h
5
6 This file (C) 1998, 1999 Bernd Schroeder
7 2000, 2001 Karsten Festag
8
9 This file is part of the SANE package.
10
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <https://www.gnu.org/licenses/>.
23
24 As a special exception, the authors of SANE give permission for
25 additional uses of the libraries contained in this release of SANE.
26
27 The exception is that, if you link a SANE library with other files
28 to produce an executable, this does not by itself cause the
29 resulting executable to be covered by the GNU General Public
30 License. Your use of that executable is in no way restricted on
31 account of linking the SANE library code into it.
32
33 This exception does not, however, invalidate any other reasons why
34 the executable file might be covered by the GNU General Public
35 License.
36
37 If you submit changes to SANE to the maintainers to be included in
38 a subsequent release, you agree by submitting the changes that
39 those changes may be distributed with this exception intact.
40
41 If you write modifications of your own for SANE, it is your choice
42 whether to permit this exception to apply to your modifications.
43 If you do not wish that, delete this exception notice.
44
45
46 *******************************************************************************/
47
48
49 #ifndef microtek2_h
50 #define microtek2_h
51
52 #include <sys/types.h>
53
54
55 /******************************************************************************/
56 /* Miscellaneous defines */
57 /******************************************************************************/
58
59 #ifndef PATH_MAX
60 # define PATH_MAX 1024
61 #endif
62
63 #ifdef HAVE_AUTHORIZATION
64 #ifndef PATH_SEP
65 #if defined(_WIN32) || defined(HAVE_OS2_H)
66 # define PATH_SEP "\\"
67 #else
68 # define PATH_SEP "/"
69 #endif
70 #endif
71
72 #define MAX_LINE_LEN 512 /* max length of entry in password file */
73 #define PASSWD_FILE STRINGIFY(PATH_SANE_CONFIG_DIR) PATH_SEP "auth"
74 #define SEPARATOR ':' /* separator in that file */
75 #define SALT "ab" /* used by crypt() */
76
77 #endif /* HAVE_AUTHORIZATION */
78
79
80 #define ENDIAN_TYPE(d) { unsigned i, test = 0; \
81 for (i=0; i < sizeof(int); i++ ) \
82 test += i << (8 * i); \
83 d = ((char *) &test)[0] == 0 ? 0 : 1; }
84
85 #define MIN(a,b) ((a) < (b)) ? (a) : (b)
86 #define MAX(a,b) ((a) > (b)) ? (a) : (b)
87
88 #define MICROTEK2_MAJOR 0
89 #define MICROTEK2_MINOR 96
90 #define MICROTEK2_BUILD "200410042220"
91 #define MICROTEK2_CONFIG_FILE "microtek2.conf"
92
93
94 /******************************************************************************/
95 /* defines that are common to all devices */
96 /******************************************************************************/
97
98 #define MD_RESOLUTION_DEFAULT 72 << SANE_FIXED_SCALE_SHIFT
99 #define MD_BRIGHTNESS_DEFAULT 100 << SANE_FIXED_SCALE_SHIFT
100 #define MD_CONTRAST_DEFAULT 100 << SANE_FIXED_SCALE_SHIFT
101 #define MD_THRESHOLD_DEFAULT 128
102 #define MD_GAMMA_DEFAULT SANE_FIX(2.2)
103 #define MD_SHADOW_DEFAULT 0
104 #define MD_MIDTONE_DEFAULT 128
105 #define MD_HIGHLIGHT_DEFAULT 255
106 #define MD_EXPOSURE_DEFAULT 0
107 #define M_BRIGHTNESS_DEFAULT 128
108 #define M_CONTRAST_DEFAULT 128
109 #define M_SHADOW_DEFAULT 0
110 #define M_MIDTONE_DEFAULT 128
111 #define M_HIGHLIGHT_DEFAULT 255
112 #define M_EXPOSURE_DEFAULT 0
113 #define M_THRESHOLD_DEFAULT 128
114
115
116 /******************************************************************************/
117 /* SCSI commands used by the scanner */
118 /******************************************************************************/
119
120 /* INQUIRY */
121 #define INQ_CMD(d) d[0] = 0x12; d[1] = 0x00; d[2] = 0x00; \
122 d[3] = 0x00; d[4] = 0x00; d[5] = 0x00
123 #define INQ_CMD_L 6
124 #define INQ_ALLOC_L 5 /* first get 5 bytes */
125 #define INQ_ALLOC_P 4
126 #define INQ_SET_ALLOC(d,s) (d)[4] = (s)
127
128 #define INQ_GET_INQLEN(d,s) d = (s)[4]
129 #define INQ_GET_QUAL(d,s) d = ((s)[0] >> 5) & 0x07
130 #define INQ_GET_DEVT(d,s) d = (s)[0] & 0x1f
131 #define INQ_GET_VERSION(d,s) d = (s)[2] & 0x02
132 #define INQ_VENDOR_L 8
133 #define INQ_GET_VENDOR(d,s) strncpy(d, &(s)[8], INQ_VENDOR_L); \
134 d[INQ_VENDOR_L] = '\0'
135 #define INQ_MODEL_L 16
136 #define INQ_GET_MODEL(d,s) strncpy(d, &(s)[16], INQ_MODEL_L); \
137 d[INQ_MODEL_L] = '\0'
138 #define INQ_REV_L 4
139 #define INQ_GET_REV(d,s) strncpy(d, &(s)[32], INQ_REV_L); \
140 d[INQ_REV_L] = '\0'
141 #define INQ_GET_MODELCODE(d,s) d = (s)[36]
142
143
144
145 /* TEST_UNIT_READY */
146 #define TUR_CMD(d) d[0]=0x00; d[1]=0x00; d[2]=0x00; \
147 d[3]=0x00; d[4]=0x00; d[5]=0x00
148 #define TUR_CMD_L 6
149
150
151 /* READ GAMMA TABLE */
152 #define RG_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x03; \
153 (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \
154 (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \
155 (d)[9] = 0x00
156 #define RG_CMD_L 10
157 #define RG_PCORMAC(d,p) (d)[5] |= (((p) << 7) & 0x80)
158 #define RG_COLOR(d,p) (d)[5] |= (((p) << 5) & 0x60)
159 #define RG_WORD(d,p) (d)[5] |= ((p) & 0x01)
160 #define RG_TRANSFERLENGTH(d,p) (d)[7] = (((p) >> 8) & 0xff); \
161 (d)[8] = ((p) & 0xff)
162
163 /* SEND GAMMA TABLE */
164 #define SG_SET_CMD(d) (d)[0] = 0x2a; (d)[1] = 0x00; (d)[2] = 0x03; \
165 (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \
166 (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \
167 (d)[9] = 0x00
168 #define SG_CMD_L 10
169 #define SG_SET_PCORMAC(d,p) (d)[5] |= (((p) << 7) & 0x80)
170 #define SG_SET_COLOR(d,p) (d)[5] |= (((p) << 5) & 0x60)
171 #define SG_SET_WORD(d,p) (d)[5] |= ((p) & 0x01)
172 #define SG_SET_TRANSFERLENGTH(d,p) (d)[7] = (((p) >> 8) & 0xff); \
173 (d)[8] = ((p) & 0xff)
174 #define SG_DATA_P SG_CMD_L
175
176
177 /* READ CONTROL BITS */
178 #define RCB_SET_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x90; \
179 (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \
180 (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \
181 (d)[9] = 0x00
182 #define RCB_CMD_L 10
183 #define RCB_SET_LENGTH(d,s) (d)[6] = (((s) >> 16) & 0xff); \
184 (d)[7] = (((s) >> 8) & 0xff); \
185 (d)[8] = ((s) & 0xff);
186
187
188 /* READ_SCANNER_ATTRIBUTES */
189 #define RSA_CMD(d) d[0]=0x28; d[1]=0x00; d[2]=0x82; d[3]=0x00; \
190 d[4]=0x00; d[5]=0x00; d[6]=0x00; d[7]=0x00; \
191 d[8]=0x28; d[9]=0x00
192 #define RSA_CMD_L 10
193 #define RSA_SETMEDIA(d,p) d[5] |= ((p) & 0x77)
194 #define RSA_TRANSFERLENGTH 40
195
196 #define RSA_COLOR(d,s) d = (((s)[0] >> 7) & 0x01)
197 #define RSA_ONEPASS(d,s) d = (((s)[0] >> 6) & 0x01)
198 #define RSA_SCANNERTYPE(d,s) d = (((s)[0] >> 4) & 0x03)
199 #define RSA_FEPROM(d,s) d = (((s)[0] >> 3) & 0x01)
200 #define RSA_DATAFORMAT(d,s) d = ((s)[0] & 0x07)
201 #define RSA_COLORSEQUENCE_L 3
202 #define RSA_COLORSEQUENCE(d,s) { \
203 d[0] = (((s)[1] >> 6) & 0x03); \
204 d[1] = (((s)[1] >> 4) & 0x03); \
205 d[2] = (((s)[1] >> 2) & 0x03); \
206 }
207 #define RSA_NIS(d,s) d = ((s)[1] & 0x02)
208 #define RSA_DATSEQ(d,s) d = ((s)[1] & 0x01)
209 #define RSA_CCDGAP(d,s) d = (s)[2]
210 #define RSA_MAX_XRESOLUTION(d,s) d = ((s)[3] << 8) + (s)[4]
211 #define RSA_MAX_YRESOLUTION(d,s) d = ((s)[5] << 8) + (s)[6]
212 #define RSA_GEOWIDTH(d,s) d = ((s)[7] << 8) + (s)[8]
213 #define RSA_GEOHEIGHT(d,s) d = ((s)[9] << 8) + (s)[10]
214 #define RSA_OPTRESOLUTION(d,s) d = ((s)[11] << 8) + (s)[12]
215 #define RSA_DEPTH(d,s) d = (((s)[13] >> 4) & 0x0f)
216 #define RSA_SCANMODE(d,s) d = (s)[13] & 0x0f
217 #define RSA_CCDPIXELS(d,s) d = ((s)[14] << 8) + (s)[15]
218 #define RSA_LUTCAP(d,s) d = (s)[16]
219 #define RSA_DNLDPTRN(d,s) d = (((s)[17] >> 7) & 0x01)
220 #define RSA_GRAINSLCT(d,s) d = (s)[17] & 0x7f
221 #define RSA_SUPPOPT(d,s) d = (s)[18] & 0xf3
222 #define RSA_CALIBWHITE(d,s) d = ((s)[19] << 24) + ((s)[20] << 16) \
223 + ((s)[21] << 8) + (s)[22]
224 #define RSA_CALIBSPACE(d,s) d = ((s)[23] << 24) + ((s)[24] << 16) \
225 + ((s)[25] << 8) + (s)[26]
226 #define RSA_NLENS(d,s) d = (s)[27]
227 #define RSA_NWINDOWS(d,s) d = (s)[28]
228 #define RSA_SHTRNSFEREQU(d,s) d = (((s)[29] >> 2) & 0x3f)
229 #define RSA_SCNBTTN(d,s) d = (((s)[29] >> 1) & 0x01)
230 #define RSA_BUFTYPE(d,s) d = (s)[29] & 0x01
231 #define RSA_REDBALANCE(d,s) d = ((s)[30] << 8) | (s)[31]
232 #define RSA_GREENBALANCE(d,s) d = ((s)[32] << 8) | (s)[33]
233 #define RSA_BLUEBALANCE(d,s) d = ((s)[34] << 8) | (s)[35]
234 #define RSA_APSMAXFRAMES(d,s) d = (s)[36]
235
236
237 /* READ IMAGE INFORMATION */
238 #define RII_SET_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x80; \
239 (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \
240 (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x10; \
241 (d)[9] = 0x00
242 #define RII_CMD_L 10
243 #define RII_RESULT_L 16
244
245 #define RII_GET_WIDTHPIXEL(d,s) d = ((s)[0] << 24) + ((s)[1] << 16) \
246 + ((s)[2] << 8) + (s)[3]
247 #define RII_GET_WIDTHBYTES(d,s) d = ((s)[4] << 24) + ((s)[5] << 16) \
248 + ((s)[6] << 8) + (s)[7]
249 #define RII_GET_HEIGHTLINES(d,s) d = ((s)[8] << 24) + ((s)[9] << 16) \
250 + ((s)[10] << 8) + (s)[11]
251 #define RII_GET_REMAINBYTES(d,s) d = ((s)[12] << 24) + ((s)[13] << 16) \
252 + ((s)[14] << 8) + (s)[15]
253
254 /* The V300 returns some values in only two bytes */
255 #define RII_GET_V300_WIDTHPIXEL(d,s) d = ((s)[0] << 8) + (s)[1]
256 #define RII_GET_V300_WIDTHBYTES(d,s) d = ((s)[2] << 8) + (s)[3]
257 #define RII_GET_V300_HEIGHTLINES(d,s) d = ((s)[4] << 8) + (s)[5]
258 #define RII_GET_V300_REMAINBYTES(d,s) d = ((s)[6] << 24) + ((s)[7] << 16) \
259 + ((s)[8] << 8) + (s)[9]
260
261 /* READ SHADING INFORMATION */
262 #define RSI_SET_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x01; \
263 (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \
264 (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x10; \
265 (d)[9] = 0x00
266 #define RSI_CMD_L 10
267 #define RSI_SET_PCORMAC(d,s) (d)[5] |= (((s) << 7) & 0x80)
268 #define RSI_SET_COLOR(d,s) (d)[5] |= (((s) << 5) & 0x60)
269 #define RSI_SET_DARK(d,s) (d)[5] |= (((s) << 1) & 0x02) /*(KF)*/
270 /* RSI_SET_DARK was missing*/
271 #define RSI_SET_WORD(d,s) (d)[5] |= ((s) & 0x01)
272 #define RSI_SET_TRANSFERLENGTH(d,s) (d)[6] = (((s) >> 16) & 0xff); \
273 (d)[7] = (((s) >> 8) & 0xff); \
274 (d)[8] = ((s) & 0xff);
275
276 /* SEND SHADING INFORMATION */
277 #define SSI_SET_CMD(d) (d)[0] = 0x2a; (d)[1] = 0x00; (d)[2] = 0x01; \
278 (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \
279 (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \
280 (d)[9] = 0x00
281 #define SSI_CMD_L 10
282 #define SSI_SET_PCORMAC(d,s) (d)[5] |= (((s) << 7) & 0x80)
283 #define SSI_SET_COLOR(d,s) (d)[5] |= (((s) << 5) & 0x60)
284 #define SSI_SET_DARK(d,s) (d)[5] |= (((s) << 1) & 0x02)
285 #define SSI_SET_WORD(d,s) (d)[5] |= ((s) & 0x01)
286 #define SSI_SET_TRANSFERLENGTH(d,s) (d)[6] = (((s) >> 16) & 0xff); \
287 (d)[7] = (((s) >> 8) & 0xff); \
288 (d)[8] = ((s) & 0xff);
289
290
291 /* READ IMAGE */
292
293 /* READ IMAGE */
294 #define RI_SET_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x00; \
295 (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \
296 (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \
297 (d)[9] = 0x00
298 #define RI_CMD_L 10
299
300
301 #define RI_SET_PCORMAC(d,s) (d)[4] |= (((s) << 7) & 0x80)
302 #define RI_SET_COLOR(d,s) (d)[4] |= (((s) << 5) & 0x60)
303 #define RI_SET_TRANSFERLENGTH(d,s) (d)[6] = (((s) >> 16) & 0xff); \
304 (d)[7] = (((s) >> 8) & 0xff); \
305 (d)[8] = ((s) & 0xff);
306
307
308 /* READ SYSTEM_STATUS */
309 #define RSS_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x81; \
310 (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \
311 (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x09; \
312 (d)[9] = 0x00
313 #define RSS_CMD_L 10
314 #define RSS_RESULT_L 9
315
316 #define RSS_FIRSTSCAN(s) (s)[0] & 0x80
317 #define RSS_AFOCUS(s) (s)[0] & 0x40
318 #define RSS_SSKIP(s) (s)[0] & 0x20
319 #define RSS_STICK(s) (s)[0] & 0x10
320 #define RSS_NTRACK(s) (s)[0] & 0x08
321 #define RSS_NCALIB(s) (s)[0] & 0x04
322 #define RSS_TLAMP(s) (s)[0] & 0x02
323 #define RSS_FLAMP(s) (s)[0] & 0x01
324 #define RSS_FSH(s) (s)[1] & 0x20
325 #define RSS_TEFLAG(s) (s)[1] & 0x10
326 #define RSS_WHITESTRIE(s) (s)[1] & 0x08
327 #define RSS_RDYMAN(s) (s)[1] & 0x04
328 #define RSS_TRDY(s) (s)[1] & 0x02
329 #define RSS_FRDY(s) (s)[1] & 0x01
330 #define RSS_ADP(s) (s)[2] & 0x80
331 #define RSS_DETECT(s) (s)[2] & 0x40
332 #define RSS_ADPTIME(s) (s)[2] & 0x3f
333 #define RSS_LENSSTATUS(s) (s)[3]
334 #define RSS_ALOFF(s) (s)[4] & 0x80
335 #define RSS_TIMEREMAIN(s) (s)[4] & 0x7f
336 #define RSS_MTMACNT(s) (s)[5] & 0x40
337 #define RSS_MOVE(s) (s)[5] & 0x20
338 #define RSS_LAMP(s) (s)[5] & 0x10
339 #define RSS_EJECT(s) (s)[5] & 0x08
340 #define RSS_TMACNT(s) (s)[5] & 0x04
341 #define RSS_PAPER(s) (s)[5] & 0x02
342 #define RSS_ADFCNT(s) (s)[5] & 0x01
343 #define RSS_CANCELBTN(s) (s)[6] & 0x80
344 #define RSS_COPYBTN(s) (s)[6] & 0x40
345 #define RSS_EMAILBTN(s) (s)[6] & 0x20
346 #define RSS_GOBTN(s) (s)[6] & 0x10
347 #define RSS_TURBOBTN(s) (s)[6] & 0x08
348 #define RSS_CURRENTMODE(s) (s)[6] & 0x07
349 #define RSS_BUTTONCOUNT(s) (s)[7]
350 #define RSS_MFOCUS(s) (s)[9]
351
352 /* SEND SYSTEM STATUS */
353 #define SSS_CMD(d) (d)[0] = 0x2a; (d)[1] = 0x00; (d)[2] = 0x81; \
354 (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \
355 (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x09; \
356 (d)[9] = 0x00
357 #define SSS_CMD_L 10
358 #define SSS_DATA_L 9
359
360 #define SSS_AFOCUS(d,p) d[0] |= (p) & 0x40
361 #define SSS_STICK(d,p) d[0] |= (p) & 0x10
362 #define SSS_NTRACK(d,p) d[0] |= (p) & 0x08
363 #define SSS_NCALIB(d,p) d[0] |= (p) & 0x04
364 #define SSS_TLAMP(d,p) d[0] |= (p) & 0x02
365 #define SSS_FLAMP(d,p) d[0] |= (p) & 0x01
366 #define SSS_RESERVED17(d,p) d[1] |= (p) & 0x80
367 #define SSS_FSH(d,p) d[1] |= (p) & 0x40
368 #define SSS_RDYMAN(d,p) d[1] |= (p) & 0x04
369 #define SSS_TRDY(d,p) d[1] |= (p) & 0x02
370 #define SSS_FRDY(d,p) d[1] |= (p) & 0x01
371 #define SSS_ADP(d,p) d[2] |= (p) & 0x80
372 #define SSS_DETECT(d,p) d[2] |= (p) & 0x40
373 #define SSS_ADPTIME(d,p) d[2] |= (p) & 0x3f
374 #define SSS_LENSSTATUS(d,p) d[3] |= (p)
375 #define SSS_ALOFF(d,p) d[4] |= (p) & 0x80
376 #define SSS_TIMEREMAIN(d,p) d[4] |= (p) & 0x7f
377 #define SSS_TMACNT(d,p) d[5] |= (p) & 0x04
378 #define SSS_PAPER(d,p) d[5] |= (p) & 0x02
379 #define SSS_ADFCNT(d,p) d[5] |= (p) & 0x01
380 #define SSS_CURRENTMODE(d,p) d[6] |= (p) & 0x07
381 #define SSS_BUTTONCOUNT(d,p) d[6] |= (p)
382 #define SSS_MFOCUS(s) d[9] |= (p)
383
384
385 /* SET WINDOW */
386 #define SW_CMD(d) d[0]=0x24; d[1]=0x00; d[2]=0x00; d[3]=0x00; \
387 d[4]=0x00; d[5]=0x00; d[6]=0x00; d[7]=0x00;\
388 d[8]=0x00; d[9]=0x00
389
390 #define SW_CMD_L 10
391 #define SW_HEADER_L 8
392 #define SW_BODY_L 61
393 #define SW_CMD_P 0 /* command at position 0 */
394 #define SW_HEADER_P SW_CMD_L
395 #define SW_BODY_P(n) SW_CMD_L + SW_HEADER_L + (n) * SW_BODY_L
396
397 /* d: SW_CMD_P, SW_HEADER_P, SW_BODY_P(n) */
398 #define SW_PARAM_LENGTH(d,p) (d)[6] = ((p) >> 16) & 0xff; \
399 (d)[7] = ((p) >> 8) & 0xff;\
400 (d)[8] = (p) & 0xff
401 #define SW_WNDDESCVAL SW_BODY_L
402 #define SW_WNDDESCLEN(d,p) (d)[6] = ((p) >> 8) & 0xff; \
403 (d)[7] = (p) & 0xff
404 #define SW_WNDID(d,p) (d)[0] = (p)
405 #define SW_XRESDPI(d,p) (d)[2] = ((p) >> 8) & 0xff; \
406 (d)[3] = (p) & 0xff
407 #define SW_YRESDPI(d,p) (d)[4] = ((p) >> 8) & 0xff; \
408 (d)[5] = (p) & 0xff
409 #define SW_XPOSTL(d,p) (d)[6] = ((p) >> 24) & 0xff; \
410 (d)[7] = ((p) >> 16) & 0xff; \
411 (d)[8] = ((p) >> 8) & 0xff; \
412 (d)[9] = ((p)) & 0xff
413 #define SW_YPOSTL(d,p) (d)[10] = ((p) >> 24) & 0xff; \
414 (d)[11] = ((p) >> 16) & 0xff; \
415 (d)[12] = ((p) >> 8) & 0xff; \
416 (d)[13] = (p) & 0xff
417 #define SW_WNDWIDTH(d,p) (d)[14] = ((p) >> 24) & 0xff; \
418 (d)[15] = ((p) >> 16) & 0xff; \
419 (d)[16] = ((p) >> 8) & 0xff; \
420 (d)[17] = (p) & 0xff
421 #define SW_WNDHEIGHT(d,p) (d)[18] = ((p) >> 24) & 0xff; \
422 (d)[19] = ((p) >> 16) & 0xff; \
423 (d)[20] = ((p) >> 8) & 0xff; \
424 (d)[21] = (p) & 0xff
425 #define SW_BRIGHTNESS_M(d,p) (d)[22] = (p)
426 #define SW_THRESHOLD(d,p) (d)[23] = (p)
427 #define SW_CONTRAST_M(d,p) (d)[24] = (p)
428 #define SW_IMGCOMP(d,p) (d)[25] = (p) & 0x0f /* take lineartfake */
429 /* into account */
430 #define SW_BITSPERPIXEL(d,p) (d)[26] = (p)
431 #define SW_EXPOSURE_M(d,p) (d)[27] = (p)
432 #define SW_EXTHT(d,p) (d)[28] |= (((p) << 7) & 0x80)
433 #define SW_INTHTINDEX(d,p) (d)[28] |= ((p) & 0x7f)
434 #define SW_RIF(d,p) (d)[29] |= (((p) << 7) & 0x80)
435 #define SW_NOGAMMA(d,p) (d)[29] |= (((p) << 6) & 0x40)
436 #define SW_SLOWSCAN(d,p) (d)[29] |= (((p) << 5) & 0x20)
437 #define SW_LENS(d,p) (d)[30] = (p)
438 #define SW_INFINITE(d,p) (d)[31] |= (((p) << 7) & 0x80)
439 #define SW_STAY(d,p) (d)[31] |= (((p) << 6) & 0x40)
440 #define SW_RAWDAT(d,p) (d)[31] |= (((p) << 5) & 0x20)
441 #define SW_QUALITY(d,p) (d)[31] |= (((p) << 4) & 0x10)
442 #define SW_FASTSCAN(d,p) (d)[31] |= (((p) << 3) & 0x08)
443 #define SW_MEDIA(d,p) (d)[31] |= ((p) & 0x07)
444 #define SW_JPEGENABLE(d,p) (d)[34] |= (((p) << 7) & 0x80)
445 #define SW_JPEGALGOR(d,p) (d)[34] |= (((p) << 5) & 0x60)
446 #define SW_JPEGMODE(d,p) (d)[34] |= (((p) << 3) & 0x18)
447 #define SW_SHADOW_M(d,p) (d)[40] = (p)
448 #define SW_MIDTONE_M(d,p) (d)[41] = (p)
449 #define SW_HIGHLIGHT_M(d,p) (d)[42] = (p)
450 #define SW_BRIGHTNESS_R(d,p) (d)[43] = (p)
451 #define SW_CONTRAST_R(d,p) (d)[44] = (p)
452 #define SW_EXPOSURE_R(d,p) (d)[45] = (p)
453 #define SW_SHADOW_R(d,p) (d)[46] = (p)
454 #define SW_MIDTONE_R(d,p) (d)[47] = (p)
455 #define SW_HIGHLIGHT_R(d,p) (d)[48] = (p)
456 #define SW_BRIGHTNESS_G(d,p) (d)[49] = (p)
457 #define SW_CONTRAST_G(d,p) (d)[50] = (p)
458 #define SW_EXPOSURE_G(d,p) (d)[51] = (p)
459 #define SW_SHADOW_G(d,p) (d)[52] = (p)
460 #define SW_MIDTONE_G(d,p) (d)[53] = (p)
461 #define SW_HIGHLIGHT_G(d,p) (d)[54] = (p)
462 #define SW_BRIGHTNESS_B(d,p) (d)[55] = (p)
463 #define SW_CONTRAST_B(d,p) (d)[56] = (p)
464 #define SW_EXPOSURE_B(d,p) (d)[57] = (p)
465 #define SW_SHADOW_B(d,p) (d)[58] = (p)
466 #define SW_MIDTONE_B(d,p) (d)[59] = (p)
467 #define SW_HIGHLIGHT_B(d,p) (d)[60] = (p)
468
469
470 /* READ IMAGE STATUS */
471 #define RIS_SET_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x83; \
472 (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \
473 (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \
474 (d)[9] = 0x00
475 #define RIS_CMD_L 10
476 #define RIS_SET_PCORMAC(d,p) (d)[4] |= (((p) << 7) & 0x80)
477 #define RIS_SET_COLOR(d,p) (d)[4] |= (((p) << 5) & 0x60)
478
479
480 /* REQUEST SENSE */
481 #define RQS_CMD(d) (d)[0] = 0x03; (d)[1] = 0x00; (d)[2] = 0x00; \
482 (d)[3] = 0x00; (d)[5] = 0x00
483 #define RQS_CMD_L 6
484 #define RQS_ALLOCLENGTH(d,p) (d)[4] = (p)
485
486 #define RQS_LENGTH(s) (s)[7] + 7
487
488 #define RQS_SENSEKEY_NOSENSE 0x00
489 #define RQS_SENSEKEY_HWERR 0x04
490 #define RQS_SENSEKEY_ILLEGAL 0x05
491 #define RQS_SENSEKEY_VENDOR 0x09
492 #define RQS_SENSEKEY(s) ((s)[2] & 0x0f)
493
494 #define RQS_INFO(s) ((s)[3] << 24) + ((s)[4] << 16) \
495 + ((s)[5] << 8) + ((s)[6])
496 #define RQS_ASL(s) (s)[7]
497 #define RQS_REMAINBYTES(s) ((s)[8] << 24) + ((s)[9] << 16) \
498 + ((s)[10] << 8) + ((s)[11])
499 #define RQS_ASC(s) (s)[12]
500 /* ASC == 0x40 */
501 #define RQS_ASCQ_CPUERR 0x81
502 #define RQS_ASCQ_SRAMERR 0x82
503 #define RQS_ASCQ_DRAMERR 0x84
504 #define RQS_ASCQ_DCOFF 0x88
505 #define RQS_ASCQ_GAIN 0x90
506 #define RQS_ASCQ_POS 0xa0
507 #define RQS_ASCQ(s) (s)[13]
508
509 #define RQS_ASINFO(s) &((s)[18])
510 #define RQS_ASINFOLENGTH(s) (s)[7] - 11
511
512 /******************************************************************************/
513 /* enumeration of Option Descriptors */
514 /******************************************************************************/
515
516 enum Microtek2_Option
517 {
518 /*0*/
519 OPT_NUM_OPTS = 0,
520
521 /*1*/OPT_MODE_GROUP,
522 OPT_SOURCE,
523 OPT_MODE,
524 OPT_BITDEPTH,
525 OPT_RESOLUTION,
526 OPT_Y_RESOLUTION,
527 OPT_PREVIEW,
528
529 /*9*/ OPT_GEOMETRY_GROUP,
530 OPT_TL_X, /* top-left x */
531 OPT_TL_Y, /* top-left y */
532 OPT_BR_X, /* bottom-right x */
533 OPT_BR_Y, /* bottom-right y */
534
535 /*14*/ OPT_ENHANCEMENT_GROUP,
536 OPT_BRIGHTNESS,
537 OPT_CONTRAST,
538 OPT_THRESHOLD,
539 OPT_HALFTONE,
540 OPT_AUTOADJUST,
541
542 /*20*/ OPT_GAMMA_GROUP,
543 OPT_GAMMA_MODE,
544 OPT_GAMMA_SCALAR,
545 OPT_GAMMA_SCALAR_R,
546 OPT_GAMMA_SCALAR_G,
547 OPT_GAMMA_SCALAR_B,
548 OPT_GAMMA_CUSTOM,
549 OPT_GAMMA_CUSTOM_R,
550 OPT_GAMMA_CUSTOM_G,
551 OPT_GAMMA_CUSTOM_B,
552 OPT_GAMMA_BIND,
553
554 /*31*/ OPT_SMH_GROUP,
555 /* these options must appear in exactly this order, */
556 /* sane_control_option relies on it */
557 OPT_CHANNEL,
558 OPT_SHADOW,
559 OPT_MIDTONE,
560 OPT_HIGHLIGHT,
561 OPT_SHADOW_R,
562 OPT_MIDTONE_R,
563 OPT_HIGHLIGHT_R,
564 OPT_SHADOW_G,
565 OPT_MIDTONE_G,
566 OPT_HIGHLIGHT_G,
567 OPT_SHADOW_B,
568 OPT_MIDTONE_B,
569 OPT_HIGHLIGHT_B,
570 OPT_EXPOSURE,
571 OPT_EXPOSURE_R,
572 OPT_EXPOSURE_G,
573 OPT_EXPOSURE_B,
574
575 /*49*/ OPT_SPECIAL,
576 OPT_RESOLUTION_BIND,
577 OPT_DISABLE_BACKTRACK,
578 OPT_CALIB_BACKEND,
579 OPT_LIGHTLID35,
580 OPT_TOGGLELAMP,
581
582 /*55*/ OPT_COLORBALANCE,
583 OPT_BALANCE_R,
584 OPT_BALANCE_G,
585 OPT_BALANCE_B,
586 OPT_BALANCE_FW,
587
588 /*60*/ NUM_OPTIONS
589 };
590
591
592 /******************************************************************************/
593 /* Description of options not included in saneopts.h */
594 /******************************************************************************/
595
596 #define M_TITLE_SCANMODEGRP SANE_I18N("Scan Mode")
597 #define M_TITLE_GEOMGRP SANE_I18N("Geometry")
598 #define M_TITLE_ENHANCEGRP SANE_I18N("Enhancement")
599 #define M_TITLE_SMHGRP SANE_I18N("Shadow, midtone, highlight,"\
600 " exposure time");
601 #define M_TITLE_SPECIALGRP SANE_I18N("Special options")
602 #define M_TITLE_COLBALANCEGRP SANE_I18N("Color balance")
603
604 #define M_NAME_NOBACKTRACK "no-backtracking"
605 #define M_TITLE_NOBACKTRACK SANE_I18N("Disable backtracking")
606 #define M_DESC_NOBACKTRACK SANE_I18N("If checked the scanner does not" \
607 " perform backtracking")
608
609 #define M_NAME_TOGGLELAMP "toggle-lamp"
610 #define M_TITLE_TOGGLELAMP SANE_I18N("Toggle lamp of flatbed")
611 #define M_DESC_TOGGLELAMP SANE_I18N("Toggles the lamp of the flatbed")
612
613 #define M_NAME_CALIBBACKEND "backend-calibration"
614 #define M_TITLE_CALIBBACKEND SANE_I18N("Calibration by backend")
615 #define M_DESC_CALIBBACKEND SANE_I18N("If checked the color calibration" \
616 " before a scan is done by the backend")
617
618 #define M_NAME_LIGHTLID35 "lightlid35"
619 #define M_TITLE_LIGHTLID35 SANE_I18N("Use the lightlid-35mm adapter")
620 #define M_DESC_LIGHTLID35 SANE_I18N("This option turns off the lamp of" \
621 " the flatbed during a scan")
622
623 #define M_NAME_QUALITY_SCAN "quality-scan"
624 #define M_TITLE_QUALITY_SCAN SANE_I18N("Quality scan")
625 #define M_DESC_QUALITY_SCAN SANE_I18N("Highest quality but lower speed")
626
627 #define M_NAME_FAST_SCAN "fast-scan"
628 #define M_TITLE_FAST_SCAN SANE_I18N("Fast scan")
629 #define M_DESC_FAST_SCAN SANE_I18N("Highest speed but lower quality")
630
631 #define M_NAME_AUTOADJUST "lineart-auto-adjust"
632 #define M_TITLE_AUTOADJUST SANE_I18N("Automatic adjustment of threshold")
633 #define M_DESC_AUTOADJUST SANE_I18N("If checked the backend automatically"\
634 " tries to determine an optimal value for the" \
635 " threshold.")
636
637 #define M_NAME_GAMMA_MODE "gamma-correction"
638 #define M_TITLE_GAMMA_MODE SANE_I18N("Gamma correction")
639 #define M_DESC_GAMMA_MODE SANE_I18N("Selects the gamma correction mode.")
640
641 #define M_NAME_GAMMA_BIND "bind-gamma"
642 #define M_TITLE_GAMMA_BIND SANE_I18N("Bind gamma")
643 #define M_DESC_GAMMA_BIND SANE_I18N("Use same gamma values for all" \
644 " colour channels.")
645
646 #define M_NAME_GAMMA_SCALAR "scalar-gamma"
647 #define M_TITLE_GAMMA_SCALAR SANE_I18N("Scalar gamma")
648 #define M_DESC_GAMMA_SCALAR SANE_I18N("Selects a value for scalar" \
649 " gamma correction.")
650
651 #define M_NAME_GAMMA_SCALAR_R "scalar-gamma-r"
652 #define M_TITLE_GAMMA_SCALAR_R SANE_I18N("Scalar gamma red")
653 #define M_DESC_GAMMA_SCALAR_R SANE_I18N("Selects a value for scalar gamma" \
654 " correction (red channel)")
655
656 #define M_NAME_GAMMA_SCALAR_G "scalar-gamma-g"
657 #define M_TITLE_GAMMA_SCALAR_G SANE_I18N("Scalar gamma green")
658 #define M_DESC_GAMMA_SCALAR_G SANE_I18N("Selects a value for scalar gamma" \
659 " correction (green channel)")
660
661 #define M_NAME_GAMMA_SCALAR_B "scalar-gamma-b"
662 #define M_TITLE_GAMMA_SCALAR_B SANE_I18N("Scalar gamma blue")
663 #define M_DESC_GAMMA_SCALAR_B SANE_I18N("Selects a value for scalar gamma" \
664 " correction (blue channel)")
665
666 #define M_NAME_CHANNEL "channel"
667 #define M_TITLE_CHANNEL SANE_I18N("Channel")
668 #define M_DESC_CHANNEL SANE_I18N("Selects the colour band, \"Master\"" \
669 " means that all colours are affected.")
670
671 #define M_NAME_MIDTONE "midtone"
672 #define M_TITLE_MIDTONE SANE_I18N("Midtone")
673 #define M_DESC_MIDTONE SANE_I18N("Selects which radiance level should" \
674 " be considered \"50 % gray\".")
675
676 #define M_NAME_MIDTONE_R "midtone-r"
677 #define M_TITLE_MIDTONE_R SANE_I18N("Midtone for red")
678 #define M_DESC_MIDTONE_R SANE_I18N("Selects which radiance level should" \
679 " be considered \"50 % red\".")
680
681 #define M_NAME_MIDTONE_G "midtone-g"
682 #define M_TITLE_MIDTONE_G SANE_I18N("Midtone for green")
683 #define M_DESC_MIDTONE_G SANE_I18N("Selects which radiance level should" \
684 " be considered \"50 % green\".")
685
686 #define M_NAME_MIDTONE_B "midtone-b"
687 #define M_TITLE_MIDTONE_B SANE_I18N("Midtone for blue")
688 #define M_DESC_MIDTONE_B SANE_I18N("Selects which radiance level should" \
689 " be considered \"50 % blue\".")
690
691 #define M_NAME_BALANCE_R "balance-r"
692 #define M_TITLE_BALANCE_R SANE_I18N("Red balance")
693 #define M_DESC_BALANCE_R SANE_I18N("Balance factor for red. A value of" \
694 " 100% means no correction.")
695
696 #define M_NAME_BALANCE_G "balance-g"
697 #define M_TITLE_BALANCE_G SANE_I18N("Green balance")
698 #define M_DESC_BALANCE_G SANE_I18N("Balance factor for green. A value of"\
699 " 100% means no correction.")
700
701 #define M_NAME_BALANCE_B "balance-b"
702 #define M_TITLE_BALANCE_B SANE_I18N("Blue balance")
703 #define M_DESC_BALANCE_B SANE_I18N("Balance factor for blue. A value of" \
704 " 100% means no correction.")
705
706 #define M_NAME_BALANCE_FW "balance-fw"
707 #define M_TITLE_BALANCE_FW SANE_I18N("Firmware balance")
708 #define M_DESC_BALANCE_FW SANE_I18N("Sets the color balance values to"\
709 " the firmware provided values.")
710
711 /******************************************************************************/
712 /* Structure that contains global options */
713 /******************************************************************************/
714
715 typedef struct Config_Options
716 {
717 double strip_height; /* inch */
718 char *no_backtracking; /* enable/disable option for */
719 /* backtracking */
720 char *lightlid35; /* enable/disable lightlid35 option */
721 char *toggle_lamp; /* enable/disable lightlid35 option */
722 char *backend_calibration; /* calibration by backend */
723 char *auto_adjust; /* automatically choose threshold */
724 char *colorbalance_adjust; /* color balance can be modified */
725 } Config_Options;
726
727
728
729 /******************************************************************************/
730 /* Structure that is temporarily used, when the config file is parsed */
731 /******************************************************************************/
732
733 typedef struct Config_Temp
734 {
735 struct Config_Temp *next;
736 char *device; /* possible device name */
737 Config_Options opts; /* options belonging to this device name */
738
739 } Config_Temp;
740
741
742 /******************************************************************************/
743 /* scanner hardware info (as discovered by INQUIRY and READ ATTRIBUTES) */
744 /******************************************************************************/
745
746 typedef struct Microtek2_Info {
747 /* from inquiry */
748 SANE_Byte device_qualifier;
749 #define MI_DEVTYPE_SCANNER 0x06
750 SANE_Byte device_type;
751 #define MI_SCSI_II_VERSION 0x02
752 SANE_Byte scsi_version;
753 SANE_Char vendor[INQ_VENDOR_L + 1];
754 SANE_Char model[INQ_MODEL_L + 1];
755 SANE_Char revision[INQ_REV_L + 1];
756 SANE_Byte model_code;
757 /* from read scanner attributes */
758 SANE_Bool color;
759 #define MI_HAS_ONEPASS SANE_TRUE
760 SANE_Bool onepass;
761 /* the following 3 defines must correspond to byte 31 of SET WINDOW cmd */
762 #define MI_TYPE_FLATBED 0x01
763 #define MI_TYPE_SHEEDFEED 0x02
764 #define MI_TYPE_TRANSPARENCY 0x03
765 SANE_Byte scanner_type;
766 #define MI_HAS_FEPROM SANE_TRUE
767 SANE_Bool feprom;
768 /* MI_DATAFMT_X must correspond to Byte 0 in READ SCANNER ATTRIBUTE */
769 #define MI_DATAFMT_CHUNKY 1
770 #define MI_DATAFMT_LPLCONCAT 2
771 #define MI_DATAFMT_LPLSEGREG 3
772 #define MI_DATAFMT_9800 4
773 #define MI_DATAFMT_WORDCHUNKY 5
774 SANE_Byte data_format;
775 #define MI_COLSEQ_RED 0
776 #define MI_COLSEQ_GREEN 1
777 #define MI_COLSEQ_BLUE 2
778 #define MI_COLSEQ_ILLEGAL 3
779 uint8_t color_sequence[RSA_COLORSEQUENCE_L];
780 SANE_Bool new_image_status;
781 #define MI_DATSEQ_RTOL 1
782 uint8_t direction;
783 SANE_Byte ccd_gap;
784 SANE_Int max_xresolution;
785 SANE_Int max_yresolution;
786 SANE_Int geo_width;
787 SANE_Int geo_height;
788 SANE_Int opt_resolution;
789 #define MI_HASDEPTH_NIBBLE 1
790 #define MI_HASDEPTH_10 2
791 #define MI_HASDEPTH_12 4
792 #define MI_HASDEPTH_16 8
793 #define MI_HASDEPTH_14 16 /*This is not in Byte 13 of
794 scanner attributes but in
795 byte 48-bit0*/
796
797 SANE_Byte depth;
798 #define MI_LINEART_NONE(d) (((d) & 0x01) == 0)
799 #define MI_HASMODE_LINEART 1
800 #define MI_HASMODE_HALFTONE 2
801 #define MI_HASMODE_GRAY 4
802 #define MI_HASMODE_COLOR 8
803 SANE_Byte scanmode;
804 SANE_Int ccd_pixels;
805 #define MI_LUTCAP_NONE(d) ((d) == 0)
806 #define MI_LUTCAP_256B 1
807 #define MI_LUTCAP_1024B 2
808 #define MI_LUTCAP_1024W 4
809 #define MI_LUTCAP_4096B 8
810 #define MI_LUTCAP_4096W 16
811 #define MI_LUTCAP_64k_W 32
812 #define MI_LUTCAP_16k_W 64
813 #define MI_LUTCAP_UNKNOWN 128
814 SANE_Byte lut_cap;
815 #define MI_HAS_DNLDPTRN SANE_TRUE
816 SANE_Bool has_dnldptrn;
817 SANE_Byte grain_slct;
818 #define MI_OPTDEV_ADF 0x01
819 #define MI_OPTDEV_TMA 0x02
820 #define MI_OPTDEV_ADP 0x10
821 #define MI_OPTDEV_APS 0x20
822 #define MI_OPTDEV_STRIPE 0x40
823 #define MI_OPTDEV_SLIDE 0x80
824 SANE_Byte option_device;
825 SANE_Int calib_white;
826 SANE_Int calib_space;
827 SANE_Byte nlens;
828 SANE_Byte nwindows;
829 SANE_Byte shtrnsferequ;
830 #define MI_WHITE_SHADING_ONLY(x) (((x) & 0x20) == 0)
831 #define MI_HAS_SCNBTTN SANE_TRUE
832 SANE_Bool scnbuttn;
833 #define MI_HAS_PIPOBUF SANE_TRUE
834 SANE_Bool buftype;
835 uint16_t balance[3]; /* balance factor for red, green */
836 /* and blue data */
837 uint16_t aps_maxframes;
838 SANE_Int calib_divisor; /* e.g. the X12USL reads and sends */
839 /* shading at 1/2 * opt_resolution */
840 } Microtek2_Info;
841
842 /******************************************************************************/
843 /* device structure (one for each device in config file) */
844 /******************************************************************************/
845
846 typedef struct Microtek2_Device {
847 struct Microtek2_Device *next; /* next, for linked list */
848
849 #define MD_SOURCE_FLATBED 0
850 #define MD_SOURCE_ADF 1
851 #define MD_SOURCE_TMA 2
852 #define MD_SOURCE_SLIDE 3
853 #define MD_SOURCE_STRIPE 4
854 Microtek2_Info info[5]; /* detailed scanner spec */
855 SANE_Device sane; /* SANE generic device block */
856 char name[PATH_MAX]; /* name from config file */
857
858 SANE_Int *custom_gamma_table[4]; /* used for the custom gamma */
859 /* values before a scan starts */
860 /* the following two are derived from lut_cap */
861 int max_lut_size; /* in bytes */
862 int lut_entry_size; /* word or byte transfer in LUT */
863 uint8_t scan_source;
864 double revision;
865
866 /* basically the following two variables should go into the */
867 /* Microtek2_Scanner structure, but their values must be retained */
868 /* over several scans, and would be lost, if the application issues */
869 /* a sane_close. */
870 uint8_t *shading_table_w; /* shading table white */
871 uint8_t *shading_table_d; /* shading table dark */
872 uint8_t shading_table_contents; /* values like ms->mode */
873 /* the following structure describes the device status */
874 #define MD_TLAMP_ON 2
875 #define MD_FLAMP_ON 1
876 #define MD_NCALIB_ON 4
877 #define MD_NTRACK_ON 8
878 #define MD_STICK_ON 16
879 #define MD_RESERVED17_ON 128
880 #define MD_CURRENT_MODE_FLATBED 0
881 struct {
882 uint8_t sskip;
883 uint8_t stick;
884 uint8_t ntrack;
885 uint8_t ncalib;
886 uint8_t tlamp;
887 uint8_t flamp;
888 uint8_t reserved17;
889 uint8_t rdyman;
890 uint8_t trdy;
891 uint8_t frdy;
892 uint8_t adp;
893 uint8_t detect;
894 uint8_t adptime;
895 uint8_t lensstatus;
896 uint8_t aloff;
897 uint8_t timeremain;
898 uint8_t tmacnt;
899 uint8_t paper;
900 uint8_t adfcnt;
901 uint8_t currentmode;
902 uint8_t buttoncount;
903 } status;
904
905 /* The following defines are related to the model. Some models have */
906 /* more or less subtle deviations from the spec, which are indicated */
907 /* by these defines */
908 uint32_t model_flags;
909 #define MD_NO_SLIDE_MODE 1 /* indicates that it has slide */
910 /* mode, but it does not */
911 #define MD_DATA_FORMAT_WRONG 2 /* X6 indicates wrong mode for TMA */
912 #define MD_NO_ENHANCEMENTS 4 /* image enhancements do not work */
913 /* (Brightness, contrast, .....) */
914 #define MD_RII_TWO_BYTES 8 /* return some image information */
915 /* in two byte */
916 #define MD_NO_GAMMA 16 /* if device does not accept */
917 /* gamma tables */
918 #define MD_PHANTOM336CX_TYPE_SHADING 32 /* Phantom 336cx type shading */
919 #define MD_READ_CONTROL_BIT 64 /* uses "read control bit" */
920 #define MD_PHANTOM_C6 128 /* It is a Phantom C6 */
921 #define MD_OFFSET_2 256 /* Image data starts 2 bytes */
922 /* from the beginning of a */
923 /* scanline */
924 #define MD_X6_SHORT_TRANSFER 512 /* X6 USB crashes if you read
925 too much */
926 #define MD_NO_RIS_COMMAND 1024 /* doesn't like read_image_status */
927 #define MD_16BIT_TRANSFER 2048 /* transfers 10/12/14bit scans as */
928 /* 16bit data */
929 #define MD_CALIB_DIVISOR_600 4096 /* uses mi->calib_divisor=2 below
930 600dpi */
931
932 size_t n_control_bytes; /* for read_control_bits; the */
933 /* number is model dependent */
934 /* and can not be inquired */
935 uint32_t shading_length; /* length of the shading image */
936 /* Phantom 336cx, C6, ... */
937 uint8_t shading_depth; /* bit depth of shading image */
938 uint8_t controlbit_offset; /* first relevant control bit */
939
940
941 #define MD_MODESTRING_NUMS 4
942 #define MD_MODESTRING_COLOR SANE_VALUE_SCAN_MODE_COLOR
943 #define MD_MODESTRING_GRAY SANE_VALUE_SCAN_MODE_GRAY
944 #define MD_MODESTRING_HALFTONE SANE_VALUE_SCAN_MODE_HALFTONE
945 #define MD_MODESTRING_LINEART SANE_VALUE_SCAN_MODE_LINEART
946 SANE_String_Const scanmode_list[MD_MODESTRING_NUMS + 1];
947
948 #define MD_DEPTHVAL_NUMS 6
949 #define MD_DEPTHVAL_16 16
950 #define MD_DEPTHVAL_14 14
951 #define MD_DEPTHVAL_12 12
952 #define MD_DEPTHVAL_10 10
953 #define MD_DEPTHVAL_8 8
954 #define MD_DEPTHVAL_4 4
955 SANE_Int bitdepth_list[MD_DEPTHVAL_NUMS + 1];
956
957 #define MD_SOURCESTRING_NUMS 5
958 #define MD_SOURCESTRING_FLATBED "Flatbed"
959 #define MD_SOURCESTRING_ADF "ADF"
960 #define MD_SOURCESTRING_TMA "TMA"
961 #define MD_SOURCESTRING_STRIPE "Filmstrip"
962 #define MD_SOURCESTRING_SLIDE "Slide"
963 SANE_String_Const scansource_list[MD_SOURCESTRING_NUMS + 1];
964
965 #define MD_HALFTONE_NUMS 12
966 #define MD_HALFTONE0 "53-dot screen (53 gray levels)"
967 #define MD_HALFTONE1 "Horiz. screen (65 gray levels)"
968 #define MD_HALFTONE2 "Vert. screen (65 gray levels)"
969 #define MD_HALFTONE3 "Mixed page (33 gray levels)"
970 #define MD_HALFTONE4 "71-dot screen (29 gray levels)"
971 #define MD_HALFTONE5 "60-dot #1 (26 gray levels)"
972 #define MD_HALFTONE6 "60-dot #2 (26 gray levels)"
973 #define MD_HALFTONE7 "Fine detail #1 (17 gray levels)"
974 #define MD_HALFTONE8 "Fine detail #2 (17 gray levels)"
975 #define MD_HALFTONE9 "Slant line (17 gray levels)"
976 #define MD_HALFTONE10 "Posterizing (10 gray levels)"
977 #define MD_HALFTONE11 "High Contrast (5 gray levels)"
978 SANE_String_Const halftone_mode_list[MD_HALFTONE_NUMS + 1];
979
980 #define MD_CHANNEL_NUMS 4
981 #define MD_CHANNEL_MASTER "Master"
982 #define MD_CHANNEL_RED "Red"
983 #define MD_CHANNEL_GREEN "Green"
984 #define MD_CHANNEL_BLUE "Blue"
985 SANE_String_Const channel_list[MD_CHANNEL_NUMS + 1];
986
987 #define MD_GAMMAMODE_NUMS 3
988 #define MD_GAMMAMODE_LINEAR "None"
989 #define MD_GAMMAMODE_SCALAR "Scalar"
990 #define MD_GAMMAMODE_CUSTOM "Custom"
991 SANE_String_Const gammamode_list[MD_GAMMAMODE_NUMS + 1];
992
993 SANE_Range x_res_range_dpi; /* X resolution in dpi */
994 SANE_Range y_res_range_dpi; /* Y resolution in dpi */
995 SANE_Range x_range_mm; /* scan width in mm */
996 SANE_Range y_range_mm; /* scan height in mm */
997 SANE_Range percentage_range; /* for brightness, shadow, ... */
998 SANE_Range custom_gamma_range; /* for custom gamma values */
999 SANE_Range scalar_gamma_range; /* for scalar gamma values */
1000 SANE_Range shadow_range; /* shadow of blue channel */
1001 SANE_Range midtone_range; /* midtone shadow of blue channel */
1002 SANE_Range exposure_range; /* for lengthening exposure time */
1003 SANE_Range highlight_range; /* highlight of master channel */
1004 SANE_Range threshold_range; /* 1 - 255 */
1005 SANE_Range balance_range; /* for user provided color balance */
1006 Config_Options opts; /* options from the config file */
1007 SANE_Word opt_backend_calib_default; /* corresponds to scanner model */
1008 SANE_Word opt_no_backtrack_default; /* corresponds to scanner model */
1009 } Microtek2_Device;
1010
1011
1012
1013 /******************************************************************************/
1014 /* scanner structure (one for each device in use) */
1015 /* ....all the state needed to define a scan request */
1016 /******************************************************************************/
1017
1018 typedef struct Microtek2_Scanner {
1019 struct Microtek2_Scanner *next; /* for linked list */
1020 Microtek2_Device *dev; /* raw device info */
1021 Option_Value val[NUM_OPTIONS + 1]; /* option values for session */
1022 SANE_Parameters params; /* format, lastframe, lines, depth, ppl, bpl */
1023 SANE_Option_Descriptor sod[NUM_OPTIONS + 1]; /* option list for session */
1024
1025 uint8_t *gamma_table;
1026 uint8_t *shading_image; /* used for shading image */
1027 uint8_t *condensed_shading_w; /* used when a model uses "read */
1028 uint8_t *condensed_shading_d; /* control bit", stores the relevant */
1029 /* shading pixels for each color */
1030 uint8_t *temporary_buffer; /* used when automatic adjustment */
1031 /* is selected */
1032 char *gamma_mode; /* none, linear or custom */
1033
1034 /* the following defines must correspond to byte 25 of SET WINDOW body */
1035 #define MS_MODE_LINEART 0x00
1036 #define MS_MODE_HALFTONE 0x01
1037 #define MS_MODE_GRAY 0x02
1038 #define MS_MODE_LINEARTFAKE 0x12 /* no real mode */
1039 #define MS_MODE_COLOR 0x05
1040
1041 /* the following defines must correspond to byte 31 of SET WINDOW body */
1042 #define MS_SOURCE_FLATBED 0x00
1043 #define MS_SOURCE_ADF 0x01
1044 #define MS_SOURCE_TMA 0x02
1045 #define MS_SOURCE_STRIPE 0x05
1046 #define MS_SOURCE_SLIDE 0x06
1047
1048 SANE_Int mode;
1049 SANE_Int depth;
1050 SANE_Int x_resolution_dpi;
1051 SANE_Int y_resolution_dpi;
1052 SANE_Int x1_dots; /* x-position in units of optical resolution */
1053 SANE_Int y1_dots; /* same for y-position */
1054 SANE_Int width_dots; /* scan width in units of optical resolution */
1055 SANE_Int height_dots; /* same for height */
1056 uint8_t brightness_m;
1057 uint8_t contrast_m;
1058 uint8_t exposure_m;
1059 uint8_t shadow_m;
1060 uint8_t midtone_m;
1061 uint8_t highlight_m;
1062 uint8_t brightness_r;
1063 uint8_t contrast_r;
1064 uint8_t exposure_r;
1065 uint8_t shadow_r;
1066 uint8_t midtone_r;
1067 uint8_t highlight_r;
1068 uint8_t brightness_g;
1069 uint8_t contrast_g;
1070 uint8_t exposure_g;
1071 uint8_t shadow_g;
1072 uint8_t midtone_g;
1073 uint8_t highlight_g;
1074 uint8_t brightness_b;
1075 uint8_t contrast_b;
1076 uint8_t exposure_b;
1077 uint8_t shadow_b;
1078 uint8_t midtone_b;
1079 uint8_t highlight_b;
1080 uint8_t threshold;
1081
1082 SANE_Bool use_external_ht;
1083 SANE_Byte internal_ht_index;
1084 uint8_t stay;
1085 uint8_t rawdat;
1086 SANE_Bool quality;
1087 SANE_Bool fastscan;
1088 SANE_Byte scan_source;
1089 uint8_t no_backtracking;
1090 uint8_t lightlid35;
1091 uint8_t auto_adjust;
1092 uint8_t calib_backend;
1093 uint8_t colorbalance_adjust;
1094 int current_pass; /* current pass if 3-pass scan */
1095 int lut_size; /* size of gamma lookup table */
1096 int lut_entry_size; /* size of one entry in lookup table */
1097 uint32_t lut_size_bytes; /* size of LUT in bytes */
1098 uint8_t word; /* word transfer, used in some read cmds */
1099 /* MS_COLOR_X must correspond to color field in READ IMAGE STATUS */
1100 #define MS_COLOR_RED 0
1101 #define MS_COLOR_GREEN 1
1102 #define MS_COLOR_BLUE 2
1103 #define MS_COLOR_ALL 3
1104 uint8_t current_color; /* for gamma calc. and 3-pass scanners */
1105 uint8_t current_read_color; /* dto, for RI and RIS */
1106 uint8_t dark; /* is 1 for reading dark shading */
1107 uint32_t ppl; /* pixels per line as returned by RII */
1108 uint32_t bpl; /* bytes per line as returned by RII */
1109 uint32_t remaining_bytes; /* remaining bytes as returned by RII */
1110 uint32_t real_remaining_bytes;/* bytes to transfer to the frontend */
1111 uint32_t real_bpl; /* bpl to transfer to the frontend */
1112 SANE_Int src_remaining_lines; /* remaining lines to read */
1113 SANE_Int src_lines_to_read; /* actual number of lines read */
1114 SANE_Int src_max_lines; /* maximum number of lines that fit */
1115 /* into the scsi buffer */
1116 /* sent to the frontend */
1117 int bits_per_pixel_in; /* bits per pixel transferred from scanner */
1118 int bits_per_pixel_out; /* bits per pixel transf. to frontend */
1119 uint32_t src_buffer_size; /* size of the buffer */
1120 int transfer_length; /* transfer length for RI command */
1121 uint8_t balance[3]; /* user provided balance factor for */
1122 /* red, green and blue data */
1123 struct {
1124 uint8_t *src_buffer[2]; /* two buffers because of CCD gap */
1125 uint8_t *src_buf;
1126 int current_src;
1127 SANE_Int free_lines;
1128 SANE_Int free_max_lines;
1129 uint8_t *current_pos[3]; /* actual position in the source buffer */
1130 int planes[2][3]; /* # of red, green, blue planes in the */
1131 /* current source buffer and leftover */
1132 /* planes from previous "read image" */
1133 } buf;
1134
1135 SANE_Bool onepass;
1136
1137 size_t n_control_bytes; /* for READ CONTROL BITS */
1138 uint8_t *control_bytes; /* pointer to the result */
1139
1140 int scanning; /* true == between sane_start & sane_read=EOF */
1141 int cancelled;
1142 int sfd; /* SCSI filedescriptor */
1143 int fd[2]; /* file descriptors for pipe */
1144 SANE_Pid pid; /* pid of child process */
1145 FILE *fp;
1146
1147 } Microtek2_Scanner;
1148
1149 /******************************************************************************/
1150 /* Function prototypes */
1151 /******************************************************************************/
1152
1153 static SANE_Status
1154 add_device_list(SANE_String_Const, Microtek2_Device **);
1155
1156 static SANE_Status
1157 attach(Microtek2_Device *);
1158
1159 static SANE_Status
1160 attach_one (const char *);
1161
1162 static SANE_Status
1163 auto_adjust_proc_data (Microtek2_Scanner *, uint8_t **);
1164
1165 static SANE_Status
1166 calc_cx_shading_line(Microtek2_Scanner *); /* (KF) new */
1167
1168 static SANE_Status
1169 calculate_gamma(Microtek2_Scanner *, uint8_t *, int, char *);
1170
1171 static SANE_Status
1172 calculate_sane_params(Microtek2_Scanner *);
1173
1174 static SANE_Status
1175 cancel_scan(Microtek2_Scanner *);
1176
1177 static SANE_Status
1178 check_inquiry(Microtek2_Device *, SANE_String *);
1179
1180 static void
1181 check_option(const char *, Config_Options *);
1182
1183 static SANE_Status
1184 chunky_copy_pixels(Microtek2_Scanner *, uint8_t *);
1185
1186 static SANE_Status
1187 chunky_proc_data(Microtek2_Scanner *);
1188
1189 #if 0
1190 static void
1191 chunky_set_exposure(uint8_t *, uint32_t, uint8_t, uint8_t, int);
1192 #endif
1193
1194 static void
1195 cleanup_scanner(Microtek2_Scanner *);
1196
1197 static SANE_Status
1198 condense_shading(Microtek2_Scanner *);
1199
1200 #ifdef HAVE_AUTHORIZATION
1201 static SANE_Status
1202 do_authorization(char *);
1203 #endif
1204
1205 static SANE_Status
1206 read_shading_image(Microtek2_Scanner *);
1207
1208 static SANE_Status
1209 dump_area(uint8_t *, int, char *);
1210
1211 static SANE_Status
1212 dump_area2(uint8_t *, int, char *);
1213
1214 /* currently not used */
1215 #if 0
1216 static SANE_Status
1217 dump_to_file(uint8_t *, int, char *, char *);
1218 #endif
1219
1220 static SANE_Status
1221 dump_attributes(Microtek2_Info *);
1222
1223 static void
1224 get_calib_params(Microtek2_Scanner *);
1225
1226 static SANE_Status
1227 get_cshading_values(Microtek2_Scanner *,uint8_t, uint32_t, float, int,
1228 float *, float *); /* (KF) new */
1229 static SANE_Status
1230 get_scan_mode_and_depth(Microtek2_Scanner *, int *, SANE_Int *, int *, int *);
1231
1232 static SANE_Status
1233 get_scan_parameters(Microtek2_Scanner *);
1234
1235 static SANE_Status
1236 get_lut_size(Microtek2_Info *, int *, int *);
1237
1238 static SANE_Status
1239 gray_copy_pixels(Microtek2_Scanner *ms, uint8_t *, int, int);
1240
1241 static SANE_Status
1242 gray_proc_data(Microtek2_Scanner *);
1243
1244 #if 0
1245 static void
1246 gray_set_exposure(uint8_t *, uint32_t, uint8_t, uint8_t);
1247 #endif
1248
1249 static SANE_Status
1250 init_options(Microtek2_Scanner *, uint8_t);
1251
1252 static SANE_Status
1253 lineartfake_copy_pixels(Microtek2_Scanner *, uint8_t *, uint32_t, uint8_t,
1254 int, FILE *);
1255
1256 static SANE_Status
1257 lineartfake_proc_data(Microtek2_Scanner *);
1258
1259 static SANE_Status
1260 lplconcat_copy_pixels(Microtek2_Scanner *, uint8_t **, int, int);
1261
1262 static SANE_Status
1263 lplconcat_proc_data(Microtek2_Scanner *ms);
1264
1265 static size_t
1266 max_string_size (const SANE_String_Const * /* strings[] */);
1267
1268 static void
1269 parse_config_file(FILE *, Config_Temp **);
1270
1271 static SANE_Status
1272 prepare_buffers(Microtek2_Scanner *);
1273
1274 static SANE_Status
1275 prepare_shading_data(Microtek2_Scanner *, uint32_t, uint8_t **);
1276
1277 static SANE_Status
1278 proc_onebit_data(Microtek2_Scanner *);
1279
1280 static SANE_Status
1281 read_cx_shading_image(Microtek2_Scanner *);
1282
1283 static SANE_Status
1284 read_cx_shading(Microtek2_Scanner *);
1285
1286 static int
1287 reader_process(void *);
1288
1289 static SANE_Status
1290 restore_gamma_options(SANE_Option_Descriptor *, Option_Value *);
1291
1292 static SANE_Status
1293 segreg_copy_pixels(Microtek2_Scanner *);
1294
1295 static SANE_Status
1296 segreg_proc_data(Microtek2_Scanner *ms);
1297
1298 static void
1299 set_exposure(Microtek2_Scanner *);
1300
1301 static SANE_Status
1302 set_option_dependencies(Microtek2_Scanner *,
1303 SANE_Option_Descriptor *, Option_Value *);
1304
1305 static SANE_Status
1306 shading_function(Microtek2_Scanner *, uint8_t *);
1307
1308 static void
1309 signal_handler (int);
1310
1311 static SANE_Status
1312 wordchunky_copy_pixels(uint8_t *, uint32_t, int, FILE *);
1313
1314 static SANE_Status
1315 wordchunky_proc_data(Microtek2_Scanner *);
1316
1317 typedef int (*qsortfunc)(const void *, const void *);
1318
compare_func_16(const uint16_t * p1,uint16_t * p2)1319 static int compare_func_16(const uint16_t *p1, uint16_t *p2)
1320 {
1321 return ( *p1 - *p2 );
1322 }
1323
1324
1325 /******************************************************************************/
1326 /* Function prototypes for basic SCSI commands */
1327 /******************************************************************************/
1328
1329 static SANE_Status
1330 scsi_inquiry(Microtek2_Info *, char *);
1331
1332 static SANE_Status
1333 scsi_read_attributes(Microtek2_Info *, char *, uint8_t);
1334
1335 static SANE_Status
1336 scsi_read_control_bits(Microtek2_Scanner *);
1337
1338 /* currently not used */
1339 /* static SANE_Status
1340 scsi_read_gamma(Microtek2_Scanner *); */
1341
1342 static SANE_Status
1343 scsi_read_image(Microtek2_Scanner *, uint8_t *, int);
1344
1345 static SANE_Status
1346 scsi_read_image_info(Microtek2_Scanner *);
1347
1348 static SANE_Status
1349 scsi_read_image_status(Microtek2_Scanner *);
1350
1351 static SANE_Status
1352 scsi_read_system_status(Microtek2_Device *, int);
1353
1354 /* currently not used */
1355 /* static SANE_Status
1356 scsi_request_sense(Microtek2_Scanner *); */
1357
1358 static SANE_Status
1359 scsi_send_gamma(Microtek2_Scanner *);
1360
1361 static SANE_Status
1362 scsi_send_shading(Microtek2_Scanner *, uint8_t *, uint32_t, uint8_t);
1363
1364 static SANE_Status
1365 scsi_read_shading(Microtek2_Scanner *, uint8_t *, uint32_t);
1366
1367 static SANE_Status
1368 scsi_send_system_status(Microtek2_Device *, int);
1369
1370 static SANE_Status
1371 scsi_sense_handler (int, u_char *, void *);
1372
1373 static SANE_Status
1374 scsi_test_unit_ready(Microtek2_Device *);
1375
1376 static SANE_Status
1377 scsi_set_window(Microtek2_Scanner *, int);
1378
1379 static SANE_Status
1380 scsi_wait_for_image(Microtek2_Scanner *);
1381
1382 #endif
1383