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