1 /* sane - Scanner Access Now Easy.
2
3 Copyright (C) 2000 Mustek.
4 Originally maintained by Tom Wang <tom.wang@mustek.com.tw>
5
6 Copyright (C) 2001 - 2004 by Henning Meier-Geinitz.
7
8 This file is part of the SANE package.
9
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2 of the
13 License, or (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <https://www.gnu.org/licenses/>.
22
23 As a special exception, the authors of SANE give permission for
24 additional uses of the libraries contained in this release of SANE.
25
26 The exception is that, if you link a SANE library with other files
27 to produce an executable, this does not by itself cause the
28 resulting executable to be covered by the GNU General Public
29 License. Your use of that executable is in no way restricted on
30 account of linking the SANE library code into it.
31
32 This exception does not, however, invalidate any other reasons why
33 the executable file might be covered by the GNU General Public
34 License.
35
36 If you submit changes to SANE to the maintainers to be included in
37 a subsequent release, you agree by submitting the changes that
38 those changes may be distributed with this exception intact.
39
40 If you write modifications of your own for SANE, it is your choice
41 whether to permit this exception to apply to your modifications.
42 If you do not wish that, delete this exception notice.
43
44 This file implements a SANE backend for Mustek 1200UB and similar
45 USB flatbed scanners. */
46
47 #define BUILD 18
48
49 #include "../include/sane/config.h"
50
51 #include <ctype.h>
52 #include <errno.h>
53 #include <fcntl.h>
54 #include <limits.h>
55 #include <signal.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include <unistd.h>
60
61 #include <sys/time.h>
62 #include <sys/types.h>
63 #include <sys/wait.h>
64
65 #include "../include/sane/sane.h"
66 #include "../include/sane/sanei.h"
67 #include "../include/sane/saneopts.h"
68
69 #define BACKEND_NAME mustek_usb
70
71 #include "../include/sane/sanei_backend.h"
72 #include "../include/sane/sanei_config.h"
73 #include "../include/sane/sanei_usb.h"
74
75 #include "mustek_usb.h"
76 #include "mustek_usb_high.c"
77
78 #ifndef SANE_I18N
79 #define SANE_I18N(text) text
80 #endif
81
82 static SANE_Int num_devices;
83 static Mustek_Usb_Device *first_dev;
84 static Mustek_Usb_Scanner *first_handle;
85 static const SANE_Device **devlist = 0;
86
87 /* Maximum amount of data read in one turn from USB. */
88 static SANE_Word max_block_size = (8 * 1024);
89
90 /* Array of newly attached devices */
91 static Mustek_Usb_Device **new_dev;
92
93 /* Length of new_dev array */
94 static SANE_Int new_dev_len;
95
96 /* Number of entries allocated for new_dev */
97 static SANE_Int new_dev_alloced;
98
99 static SANE_String_Const mode_list[6];
100
101 static const SANE_Range u8_range = {
102 0, /* minimum */
103 255, /* maximum */
104 0 /* quantization */
105 };
106
107
108 static size_t
max_string_size(const SANE_String_Const strings[])109 max_string_size (const SANE_String_Const strings[])
110 {
111 size_t size, max_size = 0;
112 SANE_Int i;
113
114 for (i = 0; strings[i]; ++i)
115 {
116 size = strlen (strings[i]) + 1;
117 if (size > max_size)
118 max_size = size;
119 }
120 return max_size;
121 }
122
123
124 static SANE_Status
calc_parameters(Mustek_Usb_Scanner * s)125 calc_parameters (Mustek_Usb_Scanner * s)
126 {
127 SANE_String val;
128 SANE_Status status = SANE_STATUS_GOOD;
129 SANE_Int max_x, max_y;
130
131 DBG (5, "calc_parameters: start\n");
132 val = s->val[OPT_MODE].s;
133
134 s->params.last_frame = SANE_TRUE;
135
136 if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART))
137 {
138 s->params.format = SANE_FRAME_GRAY;
139 s->params.depth = 1;
140 s->bpp = 1;
141 s->channels = 1;
142 }
143 else if (!strcmp (val, SANE_VALUE_SCAN_MODE_GRAY))
144 {
145 s->params.format = SANE_FRAME_GRAY;
146 s->params.depth = 8;
147 s->bpp = 8;
148 s->channels = 1;
149 }
150 else if (!strcmp (val, SANE_VALUE_SCAN_MODE_COLOR))
151 {
152 s->params.format = SANE_FRAME_RGB;
153 s->params.depth = 8;
154 s->bpp = 24;
155 s->channels = 3;
156 }
157 else
158 {
159 DBG (1, "calc_parameters: invalid mode %s\n", (SANE_Char *) val);
160 status = SANE_STATUS_INVAL;
161 }
162
163 s->tl_x = SANE_UNFIX (s->val[OPT_TL_X].w) / MM_PER_INCH;
164 s->tl_y = SANE_UNFIX (s->val[OPT_TL_Y].w) / MM_PER_INCH;
165 s->width = SANE_UNFIX (s->val[OPT_BR_X].w) / MM_PER_INCH - s->tl_x;
166 s->height = SANE_UNFIX (s->val[OPT_BR_Y].w) / MM_PER_INCH - s->tl_y;
167
168 if (s->width < 0)
169 {
170 DBG (1, "calc_parameters: warning: tl_x > br_x\n");
171 }
172 if (s->height < 0)
173 {
174 DBG (1, "calc_parameters: warning: tl_y > br_y\n");
175 }
176 max_x = s->hw->max_width * SANE_UNFIX (s->val[OPT_RESOLUTION].w) / 300;
177 max_y = s->hw->max_height * SANE_UNFIX (s->val[OPT_RESOLUTION].w) / 300;
178
179 s->tl_x_dots = s->tl_x * SANE_UNFIX (s->val[OPT_RESOLUTION].w);
180 s->width_dots = s->width * SANE_UNFIX (s->val[OPT_RESOLUTION].w);
181 s->tl_y_dots = s->tl_y * SANE_UNFIX (s->val[OPT_RESOLUTION].w);
182 s->height_dots = s->height * SANE_UNFIX (s->val[OPT_RESOLUTION].w);
183
184 if (s->width_dots > max_x)
185 s->width_dots = max_x;
186 if (s->height_dots > max_y)
187 s->height_dots = max_y;
188 if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART))
189 {
190 s->width_dots = (s->width_dots / 8) * 8;
191 if (s->width_dots == 0)
192 s->width_dots = 8;
193 }
194 if (s->tl_x_dots < 0)
195 s->tl_x_dots = 0;
196 if (s->tl_y_dots < 0)
197 s->tl_y_dots = 0;
198 if (s->tl_x_dots + s->width_dots > max_x)
199 s->tl_x_dots = max_x - s->width_dots;
200 if (s->tl_y_dots + s->height_dots > max_y)
201 s->tl_y_dots = max_y - s->height_dots;
202
203 s->val[OPT_TL_X].w = SANE_FIX (s->tl_x * MM_PER_INCH);
204 s->val[OPT_TL_Y].w = SANE_FIX (s->tl_y * MM_PER_INCH);
205 s->val[OPT_BR_X].w = SANE_FIX ((s->tl_x + s->width) * MM_PER_INCH);
206 s->val[OPT_BR_Y].w = SANE_FIX ((s->tl_y + s->height) * MM_PER_INCH);
207
208 s->params.pixels_per_line = s->width_dots;
209 if (s->params.pixels_per_line < 0)
210 s->params.pixels_per_line = 0;
211 s->params.lines = s->height_dots;
212 if (s->params.lines < 0)
213 s->params.lines = 0;
214 s->params.bytes_per_line = s->params.pixels_per_line * s->params.depth / 8
215 * s->channels;
216
217 DBG (4, "calc_parameters: format=%d\n", s->params.format);
218 DBG (4, "calc_parameters: last frame=%d\n", s->params.last_frame);
219 DBG (4, "calc_parameters: lines=%d\n", s->params.lines);
220 DBG (4, "calc_parameters: pixels per line=%d\n", s->params.pixels_per_line);
221 DBG (4, "calc_parameters: bytes per line=%d\n", s->params.bytes_per_line);
222 DBG (4, "calc_parameters: Pixels %dx%dx%d\n",
223 s->params.pixels_per_line, s->params.lines, 1 << s->params.depth);
224
225 DBG (5, "calc_parameters: exit\n");
226 return status;
227 }
228
229
230 static SANE_Status
init_options(Mustek_Usb_Scanner * s)231 init_options (Mustek_Usb_Scanner * s)
232 {
233 SANE_Int option;
234 SANE_Status status;
235
236 DBG (5, "init_options: start\n");
237
238 memset (s->opt, 0, sizeof (s->opt));
239 memset (s->val, 0, sizeof (s->val));
240
241 for (option = 0; option < NUM_OPTIONS; ++option)
242 {
243 s->opt[option].size = sizeof (SANE_Word);
244 s->opt[option].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
245 }
246 s->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS;
247 s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
248 s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
249 s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
250 s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
251 s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
252
253 /* "Mode" group: */
254 s->opt[OPT_MODE_GROUP].title = SANE_I18N ("Scan Mode");
255 s->opt[OPT_MODE_GROUP].desc = "";
256 s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
257 s->opt[OPT_MODE_GROUP].size = 0;
258 s->opt[OPT_MODE_GROUP].cap = 0;
259 s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
260
261 /* scan mode */
262 mode_list[0] = SANE_VALUE_SCAN_MODE_COLOR;
263 mode_list[1] = SANE_VALUE_SCAN_MODE_GRAY;
264 mode_list[2] = SANE_VALUE_SCAN_MODE_LINEART;
265 mode_list[3] = NULL;
266
267 s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
268 s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
269 s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
270 s->opt[OPT_MODE].type = SANE_TYPE_STRING;
271 s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
272 s->opt[OPT_MODE].size = max_string_size (mode_list);
273 s->opt[OPT_MODE].constraint.string_list = mode_list;
274 s->val[OPT_MODE].s = strdup (mode_list[1]);
275
276 /* resolution */
277 s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
278 s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
279 s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
280 s->opt[OPT_RESOLUTION].type = SANE_TYPE_FIXED;
281 s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
282 s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
283 s->opt[OPT_RESOLUTION].constraint.range = &s->hw->dpi_range;
284 s->val[OPT_RESOLUTION].w = s->hw->dpi_range.min;
285 if (s->hw->chip->scanner_type == MT_600CU)
286 s->hw->dpi_range.max = SANE_FIX (600);
287 else
288 s->hw->dpi_range.max = SANE_FIX (1200);
289
290 /* preview */
291 s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
292 s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
293 s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
294 s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
295 s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
296 s->val[OPT_PREVIEW].w = SANE_FALSE;
297
298 /* "Geometry" group: */
299 s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N ("Geometry");
300 s->opt[OPT_GEOMETRY_GROUP].desc = "";
301 s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
302 s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
303 s->opt[OPT_GEOMETRY_GROUP].size = 0;
304 s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
305
306 /* top-left x */
307 s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
308 s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
309 s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
310 s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
311 s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
312 s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
313 s->opt[OPT_TL_X].constraint.range = &s->hw->x_range;
314 s->val[OPT_TL_X].w = 0;
315
316 /* top-left y */
317 s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
318 s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
319 s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
320 s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
321 s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
322 s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
323 s->opt[OPT_TL_Y].constraint.range = &s->hw->y_range;
324 s->val[OPT_TL_Y].w = 0;
325
326 /* bottom-right x */
327 s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
328 s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
329 s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
330 s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
331 s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
332 s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
333 s->opt[OPT_BR_X].constraint.range = &s->hw->x_range;
334 s->val[OPT_BR_X].w = s->hw->x_range.max;
335
336 /* bottom-right y */
337 s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
338 s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
339 s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
340 s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
341 s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
342 s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
343 s->opt[OPT_BR_Y].constraint.range = &s->hw->y_range;
344 s->val[OPT_BR_Y].w = s->hw->y_range.max;
345
346 /* "Enhancement" group: */
347 s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement");
348 s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
349 s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
350 s->opt[OPT_ENHANCEMENT_GROUP].size = 0;
351 s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
352 s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
353
354 /* threshold */
355 s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
356 s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
357 s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
358 s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
359 s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
360 s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
361 s->opt[OPT_THRESHOLD].constraint.range = &u8_range;
362 s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
363 s->val[OPT_THRESHOLD].w = 128;
364
365 /* custom-gamma table */
366 s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA;
367 s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
368 s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA;
369 s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
370 s->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE;
371
372 /* gray gamma vector */
373 s->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
374 s->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
375 s->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
376 s->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
377 s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
378 s->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
379 s->opt[OPT_GAMMA_VECTOR].size = 256 * sizeof (SANE_Word);
380 s->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
381 s->opt[OPT_GAMMA_VECTOR].constraint.range = &u8_range;
382 s->val[OPT_GAMMA_VECTOR].wa = &s->gray_gamma_table[0];
383
384 /* red gamma vector */
385 s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
386 s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
387 s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
388 s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
389 s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
390 s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
391 s->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word);
392 s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
393 s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range;
394 s->val[OPT_GAMMA_VECTOR_R].wa = &s->red_gamma_table[0];
395
396 /* green gamma vector */
397 s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
398 s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
399 s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
400 s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
401 s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
402 s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
403 s->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word);
404 s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
405 s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range;
406 s->val[OPT_GAMMA_VECTOR_G].wa = &s->green_gamma_table[0];
407
408 /* blue gamma vector */
409 s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
410 s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
411 s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
412 s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
413 s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
414 s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
415 s->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word);
416 s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
417 s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;
418 s->val[OPT_GAMMA_VECTOR_B].wa = &s->blue_gamma_table[0];
419
420 RIE (calc_parameters (s));
421
422 DBG (5, "init_options: exit\n");
423 return SANE_STATUS_GOOD;
424 }
425
426
427 static SANE_Status
attach(SANE_String_Const devname, Mustek_Usb_Device ** devp, SANE_Bool may_wait)428 attach (SANE_String_Const devname, Mustek_Usb_Device ** devp,
429 SANE_Bool may_wait)
430 {
431 Mustek_Usb_Device *dev;
432 SANE_Status status;
433 Mustek_Type scanner_type;
434 SANE_Int fd;
435
436 DBG (5, "attach: start: devp %s NULL, may_wait = %d\n", devp ? "!=" : "==",
437 may_wait);
438 if (!devname)
439 {
440 DBG (1, "attach: devname == NULL\n");
441 return SANE_STATUS_INVAL;
442 }
443
444 for (dev = first_dev; dev; dev = dev->next)
445 if (strcmp (dev->sane.name, devname) == 0)
446 {
447 if (devp)
448 *devp = dev;
449 DBG (4, "attach: device `%s' was already in device list\n", devname);
450 return SANE_STATUS_GOOD;
451 }
452
453 DBG (4, "attach: trying to open device `%s'\n", devname);
454 status = sanei_usb_open (devname, &fd);
455 if (status != SANE_STATUS_GOOD)
456 {
457 DBG (3, "attach: couldn't open device `%s': %s\n", devname,
458 sane_strstatus (status));
459 return status;
460 }
461 DBG (4, "attach: device `%s' successfully opened\n", devname);
462
463 /* try to identify model */
464 DBG (4, "attach: trying to identify device `%s'\n", devname);
465 status = usb_low_identify_scanner (fd, &scanner_type);
466 if (status != SANE_STATUS_GOOD)
467 {
468 DBG (1, "attach: device `%s' doesn't look like a supported scanner\n",
469 devname);
470 sanei_usb_close (fd);
471 return status;
472 }
473 sanei_usb_close (fd);
474 if (scanner_type == MT_UNKNOWN)
475 {
476 DBG (3, "attach: warning: couldn't identify device `%s', must set "
477 "type manually\n", devname);
478 }
479
480 dev = malloc (sizeof (Mustek_Usb_Device));
481 if (!dev)
482 {
483 DBG (1, "attach: couldn't malloc Mustek_Usb_Device\n");
484 return SANE_STATUS_NO_MEM;
485 }
486
487 memset (dev, 0, sizeof (*dev));
488 dev->name = strdup (devname);
489 dev->sane.name = (SANE_String_Const) dev->name;
490 dev->sane.vendor = "Mustek";
491 switch (scanner_type)
492 {
493 case MT_1200CU:
494 dev->sane.model = "1200 CU";
495 break;
496 case MT_1200CU_PLUS:
497 dev->sane.model = "1200 CU Plus";
498 break;
499 case MT_1200USB:
500 dev->sane.model = "1200 USB (unsupported)";
501 break;
502 case MT_1200UB:
503 dev->sane.model = "1200 UB";
504 break;
505 case MT_600CU:
506 dev->sane.model = "600 CU";
507 break;
508 case MT_600USB:
509 dev->sane.model = "600 USB (unsupported)";
510 break;
511 default:
512 dev->sane.model = "(unidentified)";
513 break;
514 }
515 dev->sane.type = "flatbed scanner";
516
517 dev->x_range.min = 0;
518 dev->x_range.max = SANE_FIX (8.4 * MM_PER_INCH);
519 dev->x_range.quant = 0;
520
521 dev->y_range.min = 0;
522 dev->y_range.max = SANE_FIX (11.7 * MM_PER_INCH);
523 dev->y_range.quant = 0;
524
525 dev->max_height = 11.7 * 300;
526 dev->max_width = 8.4 * 300;
527 dev->dpi_range.min = SANE_FIX (50);
528 dev->dpi_range.max = SANE_FIX (600);
529 dev->dpi_range.quant = SANE_FIX (1);
530
531 status = usb_high_scan_init (dev);
532 if (status != SANE_STATUS_GOOD)
533 {
534 DBG (1, "attach: usb_high_scan_init returned status: %s\n",
535 sane_strstatus (status));
536 free (dev);
537 return status;
538 }
539 dev->chip->scanner_type = scanner_type;
540 dev->chip->max_block_size = max_block_size;
541
542 DBG (2, "attach: found %s %s %s at %s\n", dev->sane.vendor, dev->sane.type,
543 dev->sane.model, dev->sane.name);
544 ++num_devices;
545 dev->next = first_dev;
546 first_dev = dev;
547
548 if (devp)
549 *devp = dev;
550
551 DBG (5, "attach: exit\n");
552 return SANE_STATUS_GOOD;
553 }
554
555 static SANE_Status
attach_one_device(SANE_String_Const devname)556 attach_one_device (SANE_String_Const devname)
557 {
558 Mustek_Usb_Device *dev;
559 SANE_Status status;
560
561 RIE (attach (devname, &dev, SANE_FALSE));
562
563 if (dev)
564 {
565 /* Keep track of newly attached devices so we can set options as
566 necessary. */
567 if (new_dev_len >= new_dev_alloced)
568 {
569 new_dev_alloced += 4;
570 if (new_dev)
571 new_dev =
572 realloc (new_dev, new_dev_alloced * sizeof (new_dev[0]));
573 else
574 new_dev = malloc (new_dev_alloced * sizeof (new_dev[0]));
575 if (!new_dev)
576 {
577 DBG (1, "attach_one_device: out of memory\n");
578 return SANE_STATUS_NO_MEM;
579 }
580 }
581 new_dev[new_dev_len++] = dev;
582 }
583 return SANE_STATUS_GOOD;
584 }
585
586 static SANE_Status
fit_lines(Mustek_Usb_Scanner * s, SANE_Byte * src, SANE_Byte * dst, SANE_Word src_lines, SANE_Word * dst_lines)587 fit_lines (Mustek_Usb_Scanner * s, SANE_Byte * src, SANE_Byte * dst,
588 SANE_Word src_lines, SANE_Word * dst_lines)
589 {
590 SANE_Int threshold;
591 SANE_Word src_width, dst_width;
592 SANE_Word dst_pixel, src_pixel;
593 SANE_Word dst_line, src_line;
594 SANE_Word pixel_switch;
595 SANE_Word src_address, dst_address;
596 src_width = s->hw->width;
597 dst_width = s->width_dots;
598
599 threshold = s->val[OPT_THRESHOLD].w;
600
601 DBG (5, "fit_lines: dst_width=%d, src_width=%d, src_lines=%d, "
602 "offset=%d\n", dst_width, src_width, src_lines, s->hw->line_offset);
603
604 dst_line = 0;
605 src_line = s->hw->line_offset;
606
607 while (src_line < src_lines)
608 {
609 DBG (5, "fit_lines: getting line: dst_line=%d, src_line=%d, "
610 "line_switch=%d\n", dst_line, src_line, s->hw->line_switch);
611
612 src_pixel = 0;
613 pixel_switch = src_width;
614 for (dst_pixel = 0; dst_pixel < dst_width; dst_pixel++)
615 {
616 while (pixel_switch > dst_width)
617 {
618 src_pixel++;
619 pixel_switch -= dst_width;
620 }
621 pixel_switch += src_width;
622
623 src_address = src_pixel * s->hw->bpp / 8
624 + src_width * src_line * s->hw->bpp / 8;
625 dst_address = dst_pixel * s->bpp / 8
626 + dst_width * dst_line * s->bpp / 8;
627
628 if (s->bpp == 8)
629 {
630 dst[dst_address] = s->gray_table[src[src_address]];
631 }
632 else if (s->bpp == 24)
633 {
634 dst[dst_address]
635 = s->red_table[s->gray_table[src[src_address]]];
636 dst[dst_address + 1]
637 = s->green_table[s->gray_table[src[src_address + 1]]];
638 dst[dst_address + 2]
639 = s->blue_table[s->gray_table[src[src_address + 2]]];
640 }
641 else /* lineart */
642 {
643 if ((dst_pixel % 8) == 0)
644 dst[dst_address] = 0;
645 dst[dst_address] |=
646 (((src[src_address] > threshold) ? 0 : 1)
647 << (7 - (dst_pixel % 8)));
648 }
649 }
650
651 dst_line++;
652 while (s->hw->line_switch >= s->height_dots)
653 {
654 src_line++;
655 s->hw->line_switch -= s->height_dots;
656 }
657 s->hw->line_switch += s->hw->height;
658 }
659
660 *dst_lines = dst_line;
661 s->hw->line_offset = (src_line - src_lines);
662
663 DBG (4, "fit_lines: exit, src_line=%d, *dst_lines=%d, offset=%d\n",
664 src_line, *dst_lines, s->hw->line_offset);
665 return SANE_STATUS_GOOD;
666 }
667
668 static SANE_Status
check_gamma_table(SANE_Word * table)669 check_gamma_table (SANE_Word * table)
670 {
671 SANE_Word entry, value;
672 SANE_Status status = SANE_STATUS_GOOD;
673
674 for (entry = 0; entry < 256; entry++)
675 {
676 value = table[entry];
677 if (value > 255)
678 {
679 DBG (1, "check_gamma_table: warning: entry %d > 255 (%d) - fixed\n",
680 entry, value);
681 table[entry] = 255;
682 status = SANE_STATUS_INVAL;
683 }
684 }
685
686 return status;
687 }
688
689 /* -------------------------- SANE API functions ------------------------- */
690
691 SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)692 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
693 {
694 SANE_Char line[PATH_MAX];
695 SANE_Char *word, *end;
696 SANE_String_Const cp;
697 SANE_Int linenumber;
698 FILE *fp;
699
700 DBG_INIT ();
701 DBG (2, "SANE Mustek USB backend version %d.%d build %d from %s\n", SANE_CURRENT_MAJOR,
702 SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING);
703
704 if (version_code)
705 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
706
707 DBG (5, "sane_init: authorize %s null\n", authorize ? "!=" : "==");
708
709
710 num_devices = 0;
711 first_dev = 0;
712 first_handle = 0;
713 devlist = 0;
714 new_dev = 0;
715 new_dev_len = 0;
716 new_dev_alloced = 0;
717
718 sanei_usb_init ();
719
720 fp = sanei_config_open (MUSTEK_USB_CONFIG_FILE);
721 if (!fp)
722 {
723 /* default to /dev/usb/scanner instead of insisting on config file */
724 DBG (3, "sane_init: couldn't open config file `%s': %s. Using "
725 "/dev/usb/scanner directly\n", MUSTEK_USB_CONFIG_FILE,
726 strerror (errno));
727 attach ("/dev/usb/scanner", 0, SANE_FALSE);
728 return SANE_STATUS_GOOD;
729 }
730 linenumber = 0;
731 DBG (4, "sane_init: reading config file `%s'\n", MUSTEK_USB_CONFIG_FILE);
732
733 while (sanei_config_read (line, sizeof (line), fp))
734 {
735 word = 0;
736 linenumber++;
737
738 cp = sanei_config_get_string (line, &word);
739 if (!word || cp == line)
740 {
741 DBG (5, "sane_init: config file line %d: ignoring empty line\n",
742 linenumber);
743 if (word)
744 free (word);
745 continue;
746 }
747 if (word[0] == '#')
748 {
749 DBG (5, "sane_init: config file line %d: ignoring comment line\n",
750 linenumber);
751 free (word);
752 continue;
753 }
754
755 if (strcmp (word, "option") == 0)
756 {
757 free (word);
758 word = 0;
759 cp = sanei_config_get_string (cp, &word);
760
761 if (!word)
762 {
763 DBG (1, "sane_init: config file line %d: missing quotation mark?\n",
764 linenumber);
765 continue;
766 }
767
768 if (strcmp (word, "max_block_size") == 0)
769 {
770 free (word);
771 word = 0;
772 cp = sanei_config_get_string (cp, &word);
773 if (!word)
774 {
775 DBG (1, "sane_init: config file line %d: missing quotation mark?\n",
776 linenumber);
777 continue;
778 }
779
780 errno = 0;
781 max_block_size = strtol (word, &end, 0);
782 if (end == word)
783 {
784 DBG (3, "sane-init: config file line %d: max_block_size "
785 "must have a parameter; using 8192 bytes\n",
786 linenumber);
787 max_block_size = 8192;
788 }
789 if (errno)
790 {
791 DBG (3,
792 "sane-init: config file line %d: max_block_size `%s' "
793 "is invalid (%s); using 8192 bytes\n", linenumber,
794 word, strerror (errno));
795 max_block_size = 8192;
796 }
797 else
798 {
799 DBG (3,
800 "sane_init: config file line %d: max_block_size set "
801 "to %d bytes\n", linenumber, max_block_size);
802 }
803 if (word)
804 free (word);
805 word = 0;
806 }
807 else if (strcmp (word, "1200ub") == 0)
808 {
809 if (new_dev_len > 0)
810 {
811 /* this is a 1200 UB */
812 new_dev[new_dev_len - 1]->chip->scanner_type = MT_1200UB;
813 new_dev[new_dev_len - 1]->sane.model = "1200 UB";
814 DBG (3, "sane_init: config file line %d: `%s' is a Mustek "
815 "1200 UB\n", linenumber,
816 new_dev[new_dev_len - 1]->sane.name);
817 }
818 else
819 {
820 DBG (3, "sane_init: config file line %d: option "
821 "1200ub ignored, was set before any device "
822 "name\n", linenumber);
823 }
824 if (word)
825 free (word);
826 word = 0;
827 }
828 else if (strcmp (word, "1200cu") == 0)
829 {
830 if (new_dev_len > 0)
831 {
832 /* this is a 1200 CU */
833 new_dev[new_dev_len - 1]->chip->scanner_type = MT_1200CU;
834 new_dev[new_dev_len - 1]->sane.model = "1200 CU";
835 DBG (3, "sane_init: config file line %d: `%s' is a Mustek "
836 "1200 CU\n", linenumber,
837 new_dev[new_dev_len - 1]->sane.name);
838 }
839 else
840 {
841 DBG (3, "sane_init: config file line %d: option "
842 "1200cu ignored, was set before any device "
843 "name\n", linenumber);
844 }
845 if (word)
846 free (word);
847 word = 0;
848 }
849 else if (strcmp (word, "1200cu_plus") == 0)
850 {
851 if (new_dev_len > 0)
852 {
853 /* this is a 1200 CU Plus */
854 new_dev[new_dev_len - 1]->chip->scanner_type
855 = MT_1200CU_PLUS;
856 new_dev[new_dev_len - 1]->sane.model = "1200 CU Plus";
857 DBG (3, "sane_init: config file line %d: `%s' is a Mustek "
858 "1200 CU Plus\n", linenumber,
859 new_dev[new_dev_len - 1]->sane.name);
860 }
861 else
862 {
863 DBG (3, "sane_init: config file line %d: option "
864 "1200cu_plus ignored, was set before any device "
865 "name\n", linenumber);
866 }
867 if (word)
868 free (word);
869 word = 0;
870 }
871 else if (strcmp (word, "600cu") == 0)
872 {
873 if (new_dev_len > 0)
874 {
875 /* this is a 600 CU */
876 new_dev[new_dev_len - 1]->chip->scanner_type = MT_600CU;
877 new_dev[new_dev_len - 1]->sane.model = "600 CU";
878 DBG (3, "sane_init: config file line %d: `%s' is a Mustek "
879 "600 CU\n", linenumber,
880 new_dev[new_dev_len - 1]->sane.name);
881 }
882 else
883 {
884 DBG (3, "sane_init: config file line %d: option "
885 "600cu ignored, was set before any device "
886 "name\n", linenumber);
887 }
888 if (word)
889 free (word);
890 word = 0;
891 }
892 else
893 {
894 DBG (3, "sane_init: config file line %d: option "
895 "%s is unknown\n", linenumber, word);
896 if (word)
897 free (word);
898 word = 0;
899 }
900 }
901 else
902 {
903 new_dev_len = 0;
904 DBG (4, "sane_init: config file line %d: trying to attach `%s'\n",
905 linenumber, line);
906 sanei_usb_attach_matching_devices (line, attach_one_device);
907 if (word)
908 free (word);
909 word = 0;
910 }
911 }
912
913 if (new_dev_alloced > 0)
914 {
915 new_dev_len = new_dev_alloced = 0;
916 free (new_dev);
917 }
918
919 fclose (fp);
920 DBG (5, "sane_init: exit\n");
921
922 return SANE_STATUS_GOOD;
923 }
924
925 void
sane_exit(void)926 sane_exit (void)
927 {
928 Mustek_Usb_Device *dev, *next;
929 SANE_Status status;
930
931 DBG (5, "sane_exit: start\n");
932 for (dev = first_dev; dev; dev = next)
933 {
934 next = dev->next;
935 if (dev->is_prepared)
936 {
937 status = usb_high_scan_clearup (dev);
938 if (status != SANE_STATUS_GOOD)
939 DBG (3, "sane_close: usb_high_scan_clearup returned %s\n",
940 sane_strstatus (status));
941 }
942 status = usb_high_scan_exit (dev);
943 if (status != SANE_STATUS_GOOD)
944 DBG (3, "sane_close: usb_high_scan_exit returned %s\n",
945 sane_strstatus (status));
946 if (dev->chip)
947 {
948 status = usb_high_scan_exit (dev);
949 if (status != SANE_STATUS_GOOD)
950 DBG (3,
951 "sane_exit: while closing %s, usb_high_scan_exit returned: "
952 "%s\n", dev->name, sane_strstatus (status));
953 }
954 free ((void *) dev->name);
955 free (dev);
956 }
957 first_dev = 0;
958 if (devlist)
959 free (devlist);
960 devlist = 0;
961
962 DBG (5, "sane_exit: exit\n");
963 }
964
965 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)966 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
967 {
968 Mustek_Usb_Device *dev;
969 SANE_Int dev_num;
970
971 DBG (5, "sane_get_devices: start: local_only = %s\n",
972 local_only == SANE_TRUE ? "true" : "false");
973
974 if (devlist)
975 free (devlist);
976
977 devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
978 if (!devlist)
979 return SANE_STATUS_NO_MEM;
980
981 dev_num = 0;
982 for (dev = first_dev; dev_num < num_devices; dev = dev->next)
983 devlist[dev_num++] = &dev->sane;
984 devlist[dev_num++] = 0;
985
986 *device_list = devlist;
987
988 DBG (5, "sane_get_devices: exit\n");
989
990 return SANE_STATUS_GOOD;
991 }
992
993 SANE_Status
sane_open(SANE_String_Const devicename, SANE_Handle * handle)994 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
995 {
996 Mustek_Usb_Device *dev;
997 SANE_Status status;
998 Mustek_Usb_Scanner *s;
999 SANE_Int value;
1000
1001 DBG (5, "sane_open: start (devicename = `%s')\n", devicename);
1002
1003 if (devicename[0])
1004 {
1005 for (dev = first_dev; dev; dev = dev->next)
1006 if (strcmp (dev->sane.name, devicename) == 0)
1007 break;
1008
1009 if (!dev)
1010 {
1011 DBG (5,
1012 "sane_open: couldn't find `%s' in devlist, trying attach)\n",
1013 devicename);
1014 RIE (attach (devicename, &dev, SANE_TRUE));
1015 }
1016 else
1017 DBG (5, "sane_open: found `%s' in devlist\n", dev->name);
1018 }
1019 else
1020 {
1021 /* empty devicname -> use first device */
1022 dev = first_dev;
1023 if (dev)
1024 DBG (5, "sane_open: empty devicename, trying `%s'\n", dev->name);
1025 }
1026
1027 if (!dev)
1028 return SANE_STATUS_INVAL;
1029
1030 if (dev->chip->scanner_type == MT_UNKNOWN)
1031 {
1032 DBG (0, "sane_open: the type of your scanner is unknown, edit "
1033 "mustek_usb.conf before using the scanner\n");
1034 return SANE_STATUS_INVAL;
1035 }
1036 s = malloc (sizeof (*s));
1037 if (!s)
1038 return SANE_STATUS_NO_MEM;
1039 memset (s, 0, sizeof (*s));
1040 s->hw = dev;
1041
1042 RIE (init_options (s));
1043
1044 /* insert newly opened handle into list of open handles: */
1045 s->next = first_handle;
1046 first_handle = s;
1047
1048 *handle = s;
1049 strcpy (s->hw->device_name, dev->name);
1050
1051 RIE (usb_high_scan_turn_power (s->hw, SANE_TRUE));
1052 RIE (usb_high_scan_back_home (s->hw));
1053
1054 s->hw->scan_buffer = (SANE_Byte *) malloc (SCAN_BUFFER_SIZE * 2);
1055 if (!s->hw->scan_buffer)
1056 {
1057 DBG (5, "sane_open: couldn't malloc s->hw->scan_buffer (%d bytes)\n",
1058 SCAN_BUFFER_SIZE * 2);
1059 return SANE_STATUS_NO_MEM;
1060 }
1061 s->hw->scan_buffer_len = 0;
1062 s->hw->scan_buffer_start = s->hw->scan_buffer;
1063
1064 s->hw->temp_buffer = (SANE_Byte *) malloc (SCAN_BUFFER_SIZE);
1065 if (!s->hw->temp_buffer)
1066 {
1067 DBG (5, "sane_open: couldn't malloc s->hw->temp_buffer (%d bytes)\n",
1068 SCAN_BUFFER_SIZE);
1069 return SANE_STATUS_NO_MEM;
1070 }
1071 s->hw->temp_buffer_len = 0;
1072 s->hw->temp_buffer_start = s->hw->temp_buffer;
1073
1074 for (value = 0; value < 256; value++)
1075 {
1076 s->linear_gamma_table[value] = value;
1077 s->red_gamma_table[value] = value;
1078 s->green_gamma_table[value] = value;
1079 s->blue_gamma_table[value] = value;
1080 s->gray_gamma_table[value] = value;
1081 }
1082
1083 s->red_table = s->linear_gamma_table;
1084 s->green_table = s->linear_gamma_table;
1085 s->blue_table = s->linear_gamma_table;
1086 s->gray_table = s->linear_gamma_table;
1087
1088 DBG (5, "sane_open: exit\n");
1089
1090 return SANE_STATUS_GOOD;
1091 }
1092
1093 void
sane_close(SANE_Handle handle)1094 sane_close (SANE_Handle handle)
1095 {
1096 Mustek_Usb_Scanner *prev, *s;
1097 SANE_Status status;
1098
1099 DBG (5, "sane_close: start\n");
1100
1101 /* remove handle from list of open handles: */
1102 prev = 0;
1103 for (s = first_handle; s; s = s->next)
1104 {
1105 if (s == handle)
1106 break;
1107 prev = s;
1108 }
1109 if (!s)
1110 {
1111 DBG (5, "close: invalid handle %p\n", handle);
1112 return; /* oops, not a handle we know about */
1113 }
1114
1115 if (prev)
1116 prev->next = s->next;
1117 else
1118 first_handle = s->next;
1119
1120 if (s->hw->is_open)
1121 {
1122 status = usb_high_scan_turn_power (s->hw, SANE_FALSE);
1123 if (status != SANE_STATUS_GOOD)
1124 DBG (3, "sane_close: usb_high_scan_turn_power returned %s\n",
1125 sane_strstatus (status));
1126 }
1127 #if 0
1128 if (s->hw->is_prepared)
1129 {
1130 status = usb_high_scan_clearup (s->hw);
1131 if (status != SANE_STATUS_GOOD)
1132 DBG (3, "sane_close: usb_high_scan_clearup returned %s\n",
1133 sane_strstatus (status));
1134 }
1135 status = usb_high_scan_exit (s->hw);
1136 if (status != SANE_STATUS_GOOD)
1137 DBG (3, "sane_close: usb_high_scan_exit returned %s\n",
1138 sane_strstatus (status));
1139 #endif
1140 if (s->hw->scan_buffer)
1141 {
1142 free (s->hw->scan_buffer);
1143 s->hw->scan_buffer = 0;
1144 }
1145 if (s->hw->temp_buffer)
1146 {
1147 free (s->hw->temp_buffer);
1148 s->hw->temp_buffer = 0;
1149 }
1150
1151 free (handle);
1152
1153 DBG (5, "sane_close: exit\n");
1154 }
1155
1156 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)1157 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
1158 {
1159 Mustek_Usb_Scanner *s = handle;
1160
1161 if ((unsigned) option >= NUM_OPTIONS)
1162 return 0;
1163 DBG (5, "sane_get_option_descriptor: option = %s (%d)\n",
1164 s->opt[option].name, option);
1165 return s->opt + option;
1166 }
1167
1168 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int * info)1169 sane_control_option (SANE_Handle handle, SANE_Int option,
1170 SANE_Action action, void *val, SANE_Int * info)
1171 {
1172 Mustek_Usb_Scanner *s = handle;
1173 SANE_Status status;
1174 SANE_Word cap;
1175 SANE_Int myinfo = 0;
1176
1177 DBG (5, "sane_control_option: start: action = %s, option = %s (%d)\n",
1178 (action == SANE_ACTION_GET_VALUE) ? "get" :
1179 (action == SANE_ACTION_SET_VALUE) ? "set" :
1180 (action == SANE_ACTION_SET_AUTO) ? "set_auto" : "unknown",
1181 s->opt[option].name, option);
1182
1183 if (info)
1184 *info = 0;
1185
1186 if (s->scanning)
1187 {
1188 DBG (1, "sane_control_option: don't call this function while "
1189 "scanning\n");
1190 return SANE_STATUS_DEVICE_BUSY;
1191 }
1192
1193 if (option >= NUM_OPTIONS || option < 0)
1194 {
1195 DBG (1, "sane_control_option: option %d >= NUM_OPTIONS || option < 0\n",
1196 option);
1197 return SANE_STATUS_INVAL;
1198 }
1199
1200 cap = s->opt[option].cap;
1201
1202 if (!SANE_OPTION_IS_ACTIVE (cap))
1203 {
1204 DBG (2, "sane_control_option: option %d is inactive\n", option);
1205 return SANE_STATUS_INVAL;
1206 }
1207
1208 if (action == SANE_ACTION_GET_VALUE)
1209 {
1210 switch (option)
1211 {
1212 /* word options: */
1213 case OPT_NUM_OPTS:
1214 case OPT_RESOLUTION:
1215 case OPT_PREVIEW:
1216 case OPT_TL_X:
1217 case OPT_TL_Y:
1218 case OPT_BR_X:
1219 case OPT_BR_Y:
1220 case OPT_THRESHOLD:
1221 case OPT_CUSTOM_GAMMA:
1222 *(SANE_Word *) val = s->val[option].w;
1223 break;
1224 /* word-array options: */
1225 case OPT_GAMMA_VECTOR:
1226 case OPT_GAMMA_VECTOR_R:
1227 case OPT_GAMMA_VECTOR_G:
1228 case OPT_GAMMA_VECTOR_B:
1229 memcpy (val, s->val[option].wa, s->opt[option].size);
1230 break;
1231 /* string options: */
1232 case OPT_MODE:
1233 strcpy (val, s->val[option].s);
1234 break;
1235 default:
1236 DBG (2, "sane_control_option: can't get unknown option %d\n",
1237 option);
1238 }
1239 }
1240 else if (action == SANE_ACTION_SET_VALUE)
1241 {
1242 if (!SANE_OPTION_IS_SETTABLE (cap))
1243 {
1244 DBG (2, "sane_control_option: option %d is not settable\n", option);
1245 return SANE_STATUS_INVAL;
1246 }
1247
1248 status = sanei_constrain_value (s->opt + option, val, &myinfo);
1249
1250 if (status != SANE_STATUS_GOOD)
1251 {
1252 DBG (2, "sane_control_option: sanei_constrain_value returned %s\n",
1253 sane_strstatus (status));
1254 return status;
1255 }
1256
1257 switch (option)
1258 {
1259 /* (mostly) side-effect-free word options: */
1260 case OPT_RESOLUTION:
1261 case OPT_TL_X:
1262 case OPT_TL_Y:
1263 case OPT_BR_X:
1264 case OPT_BR_Y:
1265 s->val[option].w = *(SANE_Word *) val;
1266 RIE (calc_parameters (s));
1267 myinfo |= SANE_INFO_RELOAD_PARAMS;
1268 break;
1269 case OPT_THRESHOLD:
1270 s->val[option].w = *(SANE_Word *) val;
1271 break;
1272 /* Boolean */
1273 case OPT_PREVIEW:
1274 s->val[option].w = *(SANE_Bool *) val;
1275 break;
1276 /* side-effect-free word-array options: */
1277 case OPT_GAMMA_VECTOR:
1278 case OPT_GAMMA_VECTOR_R:
1279 case OPT_GAMMA_VECTOR_G:
1280 case OPT_GAMMA_VECTOR_B:
1281 memcpy (s->val[option].wa, val, s->opt[option].size);
1282 check_gamma_table (s->val[option].wa);
1283 break;
1284 case OPT_CUSTOM_GAMMA:
1285 s->val[OPT_CUSTOM_GAMMA].w = *(SANE_Word *) val;
1286 myinfo |= SANE_INFO_RELOAD_OPTIONS;
1287 if (s->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE)
1288 {
1289 s->red_table = s->red_gamma_table;
1290 s->green_table = s->green_gamma_table;
1291 s->blue_table = s->blue_gamma_table;
1292 s->gray_table = s->gray_gamma_table;
1293 if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY) == 0)
1294 s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
1295 else if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
1296 {
1297 s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
1298 s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
1299 s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
1300 s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
1301 }
1302 }
1303 else
1304 {
1305 s->red_table = s->linear_gamma_table;
1306 s->green_table = s->linear_gamma_table;
1307 s->blue_table = s->linear_gamma_table;
1308 s->gray_table = s->linear_gamma_table;
1309 s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1310 s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1311 s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1312 s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1313 }
1314 break;
1315 case OPT_MODE:
1316 if (s->val[option].s)
1317 free (s->val[option].s);
1318 s->val[option].s = strdup (val);
1319
1320 RIE (calc_parameters (s));
1321
1322 s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
1323 s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
1324 s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1325 s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1326 s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1327 s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1328
1329 if (strcmp (val, SANE_VALUE_SCAN_MODE_LINEART) == 0)
1330 {
1331 s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
1332 }
1333 else
1334 {
1335 s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
1336 if (s->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE)
1337 {
1338 s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
1339 s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
1340 s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
1341 s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
1342 }
1343 }
1344 myinfo |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1345 break;
1346 default:
1347 DBG (2, "sane_control_option: can't set unknown option %d\n",
1348 option);
1349 }
1350 }
1351 else
1352 {
1353 DBG (2, "sane_control_option: unknown action %d for option %d\n",
1354 action, option);
1355 return SANE_STATUS_INVAL;
1356 }
1357 if (info)
1358 *info = myinfo;
1359
1360 DBG (5, "sane_control_option: exit\n");
1361 return SANE_STATUS_GOOD;
1362 }
1363
1364 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)1365 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
1366 {
1367 Mustek_Usb_Scanner *s = handle;
1368 SANE_Status status;
1369
1370 DBG (5, "sane_get_parameters: start\n");
1371
1372 RIE (calc_parameters (s));
1373 if (params)
1374 *params = s->params;
1375
1376 DBG (5, "sane_get_parameters: exit\n");
1377
1378 return SANE_STATUS_GOOD;
1379 }
1380
1381 SANE_Status
sane_start(SANE_Handle handle)1382 sane_start (SANE_Handle handle)
1383 {
1384 Mustek_Usb_Scanner *s = handle;
1385 SANE_Status status;
1386 SANE_String val;
1387 Colormode color_mode;
1388 SANE_Word dpi, x, y, width, height;
1389
1390 DBG (5, "sane_start: start\n");
1391
1392 /* First make sure we have a current parameter set. Some of the
1393 parameters will be overwritten below, but that's OK. */
1394
1395 s->total_bytes = 0;
1396 s->total_lines = 0;
1397 RIE (calc_parameters (s));
1398
1399 if (s->width_dots <= 0)
1400 {
1401 DBG (0, "sane_start: top left x > bottom right x --- exiting\n");
1402 return SANE_STATUS_INVAL;
1403 }
1404 if (s->height_dots <= 0)
1405 {
1406 DBG (0, "sane_start: top left y > bottom right y --- exiting\n");
1407 return SANE_STATUS_INVAL;
1408 }
1409
1410
1411 val = s->val[OPT_MODE].s;
1412 if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART))
1413 color_mode = GRAY8;
1414 else if (!strcmp (val, SANE_VALUE_SCAN_MODE_GRAY))
1415 color_mode = GRAY8;
1416 else /* Color */
1417 color_mode = RGB24;
1418
1419 dpi = SANE_UNFIX (s->val[OPT_RESOLUTION].w);
1420 x = s->tl_x_dots;
1421 y = s->tl_y_dots;
1422 width = s->width_dots;
1423 height = s->height_dots;
1424
1425 if (!s->hw->is_prepared)
1426 {
1427 RIE (usb_high_scan_prepare (s->hw));
1428 RIE (usb_high_scan_reset (s->hw));
1429 }
1430 RIE (usb_high_scan_set_threshold (s->hw, 128));
1431 RIE (usb_high_scan_embed_gamma (s->hw, NULL));
1432 RIE (usb_high_scan_suggest_parameters (s->hw, dpi, x, y, width, height,
1433 color_mode));
1434 RIE (usb_high_scan_setup_scan (s->hw, s->hw->scan_mode, s->hw->x_dpi,
1435 s->hw->y_dpi, 0, s->hw->x, s->hw->y,
1436 s->hw->width));
1437
1438 DBG (3, "sane_start: wanted: dpi=%d, x=%d, y=%d, width=%d, height=%d, "
1439 "scan_mode=%d\n", dpi, x, y, width, height, color_mode);
1440 DBG (3, "sane_start: got: x_dpi=%d, y_dpi=%d, x=%d, y=%d, width=%d, "
1441 "height=%d, scan_mode=%d\n", s->hw->x_dpi, s->hw->y_dpi, s->hw->x,
1442 s->hw->y, s->hw->width, s->hw->height, s->hw->scan_mode);
1443
1444 s->scanning = SANE_TRUE;
1445 s->read_rows = s->hw->height;
1446 s->hw->line_switch = s->hw->height;
1447 s->hw->line_offset = 0;
1448 s->hw->scan_buffer_len = 0;
1449
1450 DBG (5, "sane_start: exit\n");
1451 return SANE_STATUS_GOOD;
1452 }
1453
1454 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len)1455 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
1456 SANE_Int * len)
1457 {
1458 Mustek_Usb_Scanner *s = handle;
1459 SANE_Word lines_to_read, lines_read;
1460 SANE_Status status;
1461
1462 DBG (5, "sane_read: start\n");
1463
1464 if (!s)
1465 {
1466 DBG (1, "sane_read: handle is null!\n");
1467 return SANE_STATUS_INVAL;
1468 }
1469
1470 if (!buf)
1471 {
1472 DBG (1, "sane_read: buf is null!\n");
1473 return SANE_STATUS_INVAL;
1474 }
1475
1476 if (!len)
1477 {
1478 DBG (1, "sane_read: len is null!\n");
1479 return SANE_STATUS_INVAL;
1480 }
1481
1482 *len = 0;
1483
1484 if (!s->scanning)
1485 {
1486 DBG (3, "sane_read: scan was cancelled, is over or has not been "
1487 "initiated yet\n");
1488 return SANE_STATUS_CANCELLED;
1489 }
1490
1491 if (s->hw->scan_buffer_len == 0)
1492 {
1493 if (s->read_rows > 0)
1494 {
1495 lines_to_read = SCAN_BUFFER_SIZE / (s->hw->width * s->hw->bpp / 8);
1496 if (lines_to_read > s->read_rows)
1497 lines_to_read = s->read_rows;
1498 s->hw->temp_buffer_start = s->hw->temp_buffer;
1499 s->hw->temp_buffer_len = (s->hw->width * s->hw->bpp / 8)
1500 * lines_to_read;
1501 DBG (4, "sane_read: reading %d source lines\n", lines_to_read);
1502 RIE (usb_high_scan_get_rows (s->hw, s->hw->temp_buffer,
1503 lines_to_read, SANE_FALSE));
1504 RIE (fit_lines (s, s->hw->temp_buffer, s->hw->scan_buffer,
1505 lines_to_read, &lines_read));
1506 s->read_rows -= lines_to_read;
1507 if ((s->total_lines + lines_read) > s->height_dots)
1508 lines_read = s->height_dots - s->total_lines;
1509 s->total_lines += lines_read;
1510 DBG (4, "sane_read: %d destination lines, %d total\n",
1511 lines_read, s->total_lines);
1512 s->hw->scan_buffer_start = s->hw->scan_buffer;
1513 s->hw->scan_buffer_len = (s->width_dots * s->bpp / 8) * lines_read;
1514 }
1515 else
1516 {
1517 DBG (4, "sane_read: scan finished -- exit\n");
1518 return SANE_STATUS_EOF;
1519 }
1520 }
1521 if (s->hw->scan_buffer_len == 0)
1522 {
1523 DBG (4, "sane_read: scan finished -- exit\n");
1524 return SANE_STATUS_EOF;
1525 }
1526
1527 *len = MIN (max_len, (SANE_Int) s->hw->scan_buffer_len);
1528 memcpy (buf, s->hw->scan_buffer_start, *len);
1529 DBG (4, "sane_read: exit, read %d bytes from scan_buffer; "
1530 "%ld bytes remaining\n", *len,
1531 (long int) (s->hw->scan_buffer_len - *len));
1532 s->hw->scan_buffer_len -= (*len);
1533 s->hw->scan_buffer_start += (*len);
1534 s->total_bytes += (*len);
1535 return SANE_STATUS_GOOD;
1536 }
1537
1538 void
sane_cancel(SANE_Handle handle)1539 sane_cancel (SANE_Handle handle)
1540 {
1541 Mustek_Usb_Scanner *s = handle;
1542 SANE_Status status;
1543
1544 DBG (5, "sane_cancel: start\n");
1545
1546 status = usb_high_scan_stop_scan (s->hw);
1547 if (status != SANE_STATUS_GOOD)
1548 DBG (3, "sane_cancel: usb_high_scan_stop_scan returned `%s' for `%s'\n",
1549 sane_strstatus (status), s->hw->name);
1550 usb_high_scan_back_home (s->hw);
1551 if (status != SANE_STATUS_GOOD)
1552 DBG (3, "sane_cancel: usb_high_scan_back_home returned `%s' for `%s'\n",
1553 sane_strstatus (status), s->hw->name);
1554
1555 if (s->scanning)
1556 {
1557 s->scanning = SANE_FALSE;
1558 if (s->total_bytes != (s->params.bytes_per_line * s->params.lines))
1559 DBG (1, "sane_cancel: warning: scanned %d bytes, expected %d "
1560 "bytes\n", s->total_bytes,
1561 s->params.bytes_per_line * s->params.lines);
1562 else
1563 DBG (3, "sane_cancel: scan finished, scanned %d bytes\n",
1564 s->total_bytes);
1565 }
1566 else
1567 {
1568 DBG (4, "sane_cancel: scan has not been initiated yet, "
1569 "or it is already aborted\n");
1570 }
1571 DBG (5, "sane_cancel: exit\n");
1572 return;
1573 }
1574
1575 SANE_Status
sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)1576 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
1577 {
1578 Mustek_Usb_Scanner *s = handle;
1579
1580 DBG (5, "sane_set_io_mode: handle = %p, non_blocking = %s\n",
1581 handle, non_blocking == SANE_TRUE ? "true" : "false");
1582 if (!s->scanning)
1583 {
1584 DBG (1, "sane_set_io_mode: not scanning\n");
1585 return SANE_STATUS_INVAL;
1586 }
1587 if (non_blocking)
1588 return SANE_STATUS_UNSUPPORTED;
1589 return SANE_STATUS_GOOD;
1590 }
1591
1592 SANE_Status
sane_get_select_fd(SANE_Handle handle, SANE_Int * fd)1593 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
1594 {
1595 Mustek_Usb_Scanner *s = handle;
1596
1597 DBG (5, "sane_get_select_fd: handle = %p, fd = %p\n", handle, (void *) fd);
1598 if (!s->scanning)
1599 {
1600 DBG (1, "sane_get_select_fd: not scanning\n");
1601 return SANE_STATUS_INVAL;
1602 }
1603 return SANE_STATUS_UNSUPPORTED;
1604 }
1605