1 /* sane - Scanner Access Now Easy.
2
3 Copyright (C) 2007-2008 Philippe Rétornaz
4
5 This file is part of the SANE package.
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <https://www.gnu.org/licenses/>.
19
20 As a special exception, the authors of SANE give permission for
21 additional uses of the libraries contained in this release of SANE.
22
23 The exception is that, if you link a SANE library with other files
24 to produce an executable, this does not by itself cause the
25 resulting executable to be covered by the GNU General Public
26 License. Your use of that executable is in no way restricted on
27 account of linking the SANE library code into it.
28
29 This exception does not, however, invalidate any other reasons why
30 the executable file might be covered by the GNU General Public
31 License.
32
33 If you submit changes to SANE to the maintainers to be included in
34 a subsequent release, you agree by submitting the changes that
35 those changes may be distributed with this exception intact.
36
37 If you write modifications of your own for SANE, it is your choice
38 whether to permit this exception to apply to your modifications.
39 If you do not wish that, delete this exception notice.
40
41 This backend is for HP LaserJet M1005 MFP
42
43 Highly inspired from the epson backend
44 */
45
46 #define BUILD 1
47
48 #include "../include/sane/config.h"
49 #include <math.h>
50
51 #include <limits.h>
52 #include <stdio.h>
53 #include <string.h>
54 #include <stdlib.h>
55 #include <ctype.h>
56 #include <fcntl.h>
57 #include <unistd.h>
58 #include <errno.h>
59 #include <stdint.h>
60 #include <netinet/in.h>
61 #define BACKEND_NAME hpljm1005
62 #include "../include/sane/sanei_backend.h"
63 #include "../include/sane/sanei_usb.h"
64 #include "../include/sane/saneopts.h"
65
66 #define MAGIC_NUMBER 0x41535001
67 #define PKT_READ_STATUS 0x0
68 #define PKT_UNKNOW_1 0x1
69 #define PKT_START_SCAN 0x2
70 #define PKT_GO_IDLE 0x3
71 #define PKT_DATA 0x5
72 #define PKT_READCONF 0x6
73 #define PKT_SETCONF 0x7
74 #define PKT_END_DATA 0xe
75 #define PKT_RESET 0x15
76
77 #define RED_LAYER 0x3
78 #define GREEN_LAYER 0x4
79 #define BLUE_LAYER 0x5
80 #define GRAY_LAYER 0x6
81
82 #define MIN_SCAN_ZONE 101
83
84 struct usbdev_s
85 {
86 SANE_Int vendor_id;
87 SANE_Int product_id;
88 SANE_String_Const vendor_s;
89 SANE_String_Const model_s;
90 SANE_String_Const type_s;
91 };
92
93 /* Zero-terminated USB VID/PID array */
94 static struct usbdev_s usbid[] = {
95 {0x03f0, 0x3b17, "Hewlett-Packard", "LaserJet M1005",
96 "multi-function peripheral"},
97 {0x03f0, 0x5617, "Hewlett-Packard", "LaserJet M1120",
98 "multi-function peripheral"},
99 {0x03f0, 0x5717, "Hewlett-Packard", "LaserJet M1120n",
100 "multi-function peripheral"},
101 {0, 0, NULL, NULL, NULL},
102 {0, 0, NULL, NULL, NULL}
103 };
104
105 static int cur_idx;
106
107 #define BR_CONT_MIN 0x1
108 #define BR_CONT_MAX 0xb
109
110 #define RGB 1
111 #define GRAY 0
112
113 #define MAX_X_H 0x350
114 #define MAX_Y_H 0x490
115 #define MAX_X_S 220
116 #define MAX_Y_S 330
117
118 #define OPTION_MAX 9
119
120 static SANE_Word resolution_list[] = {
121 7, 75, 100, 150, 200, 300, 600, 1200
122 };
123 static SANE_Range range_x = { 0, MAX_X_S, 0 };
124 static SANE_Range range_y = { 0, MAX_Y_S, 0 };
125
126 static SANE_Range range_br_cont = { BR_CONT_MIN, BR_CONT_MAX, 0 };
127
128 static const SANE_String_Const mode_list[] = {
129 SANE_VALUE_SCAN_MODE_GRAY,
130 SANE_VALUE_SCAN_MODE_COLOR,
131 NULL
132 };
133
134 #define X1_OFFSET 2
135 #define X2_OFFSET 4
136 #define Y1_OFFSET 3
137 #define Y2_OFFSET 5
138 #define RES_OFFSET 1
139 #define COLOR_OFFSET 8
140 #define BRIGH_OFFSET 6
141 #define CONTR_OFFSET 7
142
143 #define STATUS_IDLE 0
144 #define STATUS_SCANNING 1
145 #define STATUS_CANCELING 2
146
147 struct device_s
148 {
149 struct device_s *next;
150 SANE_String_Const devname;
151 int idx; /* Index in the usbid array */
152 int dn; /* Usb "Handle" */
153 SANE_Option_Descriptor optiond[OPTION_MAX];
154 char *buffer;
155 int bufs;
156 int read_offset;
157 int write_offset_r;
158 int write_offset_g;
159 int write_offset_b;
160 int status;
161 int width;
162 int height;
163 SANE_Word optionw[OPTION_MAX];
164 uint32_t conf_data[512];
165 uint32_t packet_data[512];
166 };
167
168
169 static void
170 do_cancel(struct device_s *dev);
171
172
173 static struct device_s *devlist_head;
174 static int devlist_count; /* Number of element in the list */
175
176 /*
177 * List of pointers to devices - will be dynamically allocated depending
178 * on the number of devices found.
179 */
180 static SANE_Device **devlist = NULL;
181
182 /* round() is c99, so we provide our own, though this version won't return -0 */
183 static double
round2(double x)184 round2(double x)
185 {
186 return (double)(x >= 0.0) ? (int)(x+0.5) : (int)(x-0.5);
187 }
188
189 static void
update_img_size(struct device_s * dev)190 update_img_size (struct device_s *dev)
191 {
192 int dx, dy;
193
194 /* Only update the width when not scanning,
195 * otherwise the scanner give us the correct width */
196 if (dev->status == STATUS_SCANNING)
197 {
198 dev->height = -1;
199 return;
200 }
201
202 dx = dev->optionw[X2_OFFSET] - dev->optionw[X1_OFFSET];
203 dy = dev->optionw[Y2_OFFSET] - dev->optionw[Y1_OFFSET];
204
205 switch (dev->optionw[RES_OFFSET])
206 {
207 case 75:
208 dev->width = round2 ((dx / ((double) MAX_X_S)) * 640);
209 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 880);
210 break;
211 case 100:
212 dev->width = round2 ((dx / ((double) MAX_X_S)) * 848);
213 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 1180);
214 break;
215 case 150:
216 dev->width = round2 ((dx / ((double) MAX_X_S)) * 1264);
217 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 1775);
218 break;
219 case 200:
220 dev->width = round2 ((dx / ((double) MAX_X_S)) * 1696);
221 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 2351);
222 break;
223 case 300:
224 dev->width = round2 ((dx / ((double) MAX_X_S)) * 2528);
225 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 3510);
226 break;
227 case 600:
228 dev->width = round2 ((dx / ((double) MAX_X_S)) * 5088);
229 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 7020);
230 break;
231 case 1200:
232 dev->width = round2 ((dx / ((double) MAX_X_S)) * 10208);
233 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 14025);
234 break;
235 }
236
237 DBG(2,"New image size: %dx%d\n",dev->width, dev->height);
238
239 }
240
241 /* This function is copy/pasted from the Epson backend */
242 static size_t
max_string_size(const SANE_String_Const strings[])243 max_string_size (const SANE_String_Const strings[])
244 {
245 size_t size, max_size = 0;
246 int i;
247
248 for (i = 0; strings[i]; i++)
249 {
250 size = strlen (strings[i]) + 1;
251 if (size > max_size)
252 max_size = size;
253 }
254 return max_size;
255 }
256
257
258 static SANE_Status
attach(SANE_String_Const devname)259 attach (SANE_String_Const devname)
260 {
261 struct device_s *dev;
262
263 dev = malloc (sizeof (struct device_s));
264 if (!dev)
265 return SANE_STATUS_NO_MEM;
266 memset (dev, 0, sizeof (struct device_s));
267
268 dev->devname = devname;
269 DBG(1,"New device found: %s\n",dev->devname);
270
271 /* Init the whole structure with default values */
272 /* Number of options */
273 dev->optiond[0].name = "";
274 dev->optiond[0].title = NULL;
275 dev->optiond[0].desc = NULL;
276 dev->optiond[0].type = SANE_TYPE_INT;
277 dev->optiond[0].unit = SANE_UNIT_NONE;
278 dev->optiond[0].size = sizeof (SANE_Word);
279 dev->optionw[0] = OPTION_MAX;
280
281 /* resolution */
282 dev->optiond[RES_OFFSET].name = "resolution";
283 dev->optiond[RES_OFFSET].title = "resolution";
284 dev->optiond[RES_OFFSET].desc = "resolution";
285 dev->optiond[RES_OFFSET].type = SANE_TYPE_INT;
286 dev->optiond[RES_OFFSET].unit = SANE_UNIT_DPI;
287 dev->optiond[RES_OFFSET].type = SANE_TYPE_INT;
288 dev->optiond[RES_OFFSET].size = sizeof (SANE_Word);
289 dev->optiond[RES_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
290 dev->optiond[RES_OFFSET].constraint_type = SANE_CONSTRAINT_WORD_LIST;
291 dev->optiond[RES_OFFSET].constraint.word_list = resolution_list;
292 dev->optionw[RES_OFFSET] = 75;
293
294 /* scan area */
295 dev->optiond[X1_OFFSET].name = "tl-x";
296 dev->optiond[X1_OFFSET].title = "tl-x";
297 dev->optiond[X1_OFFSET].desc = "tl-x";
298 dev->optiond[X1_OFFSET].type = SANE_TYPE_INT;
299 dev->optiond[X1_OFFSET].unit = SANE_UNIT_MM;
300 dev->optiond[X1_OFFSET].size = sizeof (SANE_Word);
301 dev->optiond[X1_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
302 dev->optiond[X1_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
303 dev->optiond[X1_OFFSET].constraint.range = &range_x;
304 dev->optionw[X1_OFFSET] = 0;
305
306 dev->optiond[Y1_OFFSET].name = "tl-y";
307 dev->optiond[Y1_OFFSET].title = "tl-y";
308 dev->optiond[Y1_OFFSET].desc = "tl-y";
309 dev->optiond[Y1_OFFSET].type = SANE_TYPE_INT;
310 dev->optiond[Y1_OFFSET].unit = SANE_UNIT_MM;
311 dev->optiond[Y1_OFFSET].size = sizeof (SANE_Word);
312 dev->optiond[Y1_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
313 dev->optiond[Y1_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
314 dev->optiond[Y1_OFFSET].constraint.range = &range_y;
315 dev->optionw[Y1_OFFSET] = 0;
316
317 dev->optiond[X2_OFFSET].name = "br-x";
318 dev->optiond[X2_OFFSET].title = "br-x";
319 dev->optiond[X2_OFFSET].desc = "br-x";
320 dev->optiond[X2_OFFSET].type = SANE_TYPE_INT;
321 dev->optiond[X2_OFFSET].unit = SANE_UNIT_MM;
322 dev->optiond[X2_OFFSET].size = sizeof (SANE_Word);
323 dev->optiond[X2_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
324 dev->optiond[X2_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
325 dev->optiond[X2_OFFSET].constraint.range = &range_x;
326 dev->optionw[X2_OFFSET] = MAX_X_S;
327
328 dev->optiond[Y2_OFFSET].name = "br-y";
329 dev->optiond[Y2_OFFSET].title = "br-y";
330 dev->optiond[Y2_OFFSET].desc = "br-y";
331 dev->optiond[Y2_OFFSET].type = SANE_TYPE_INT;
332 dev->optiond[Y2_OFFSET].unit = SANE_UNIT_MM;
333 dev->optiond[Y2_OFFSET].size = sizeof (SANE_Word);
334 dev->optiond[Y2_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
335 dev->optiond[Y2_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
336 dev->optiond[Y2_OFFSET].constraint.range = &range_y;
337 dev->optionw[Y2_OFFSET] = MAX_Y_S;
338
339 /* brightness */
340 dev->optiond[BRIGH_OFFSET].name = "brightness";
341 dev->optiond[BRIGH_OFFSET].title = "Brightness";
342 dev->optiond[BRIGH_OFFSET].desc = "Set the brightness";
343 dev->optiond[BRIGH_OFFSET].type = SANE_TYPE_INT;
344 dev->optiond[BRIGH_OFFSET].unit = SANE_UNIT_NONE;
345 dev->optiond[BRIGH_OFFSET].size = sizeof (SANE_Word);
346 dev->optiond[BRIGH_OFFSET].cap =
347 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
348 dev->optiond[BRIGH_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
349 dev->optiond[BRIGH_OFFSET].constraint.range = &range_br_cont;
350 dev->optionw[BRIGH_OFFSET] = 0x6;
351
352 /* contrast */
353 dev->optiond[CONTR_OFFSET].name = "contrast";
354 dev->optiond[CONTR_OFFSET].title = "Contrast";
355 dev->optiond[CONTR_OFFSET].desc = "Set the contrast";
356 dev->optiond[CONTR_OFFSET].type = SANE_TYPE_INT;
357 dev->optiond[CONTR_OFFSET].unit = SANE_UNIT_NONE;
358 dev->optiond[CONTR_OFFSET].size = sizeof (SANE_Word);
359 dev->optiond[CONTR_OFFSET].cap =
360 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
361 dev->optiond[CONTR_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
362 dev->optiond[CONTR_OFFSET].constraint.range = &range_br_cont;
363 dev->optionw[CONTR_OFFSET] = 0x6;
364
365 /* Color */
366 dev->optiond[COLOR_OFFSET].name = SANE_NAME_SCAN_MODE;
367 dev->optiond[COLOR_OFFSET].title = SANE_TITLE_SCAN_MODE;
368 dev->optiond[COLOR_OFFSET].desc = SANE_DESC_SCAN_MODE;
369 dev->optiond[COLOR_OFFSET].type = SANE_TYPE_STRING;
370 dev->optiond[COLOR_OFFSET].size = max_string_size (mode_list);
371 dev->optiond[COLOR_OFFSET].cap =
372 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
373 dev->optiond[COLOR_OFFSET].constraint_type = SANE_CONSTRAINT_STRING_LIST;
374 dev->optiond[COLOR_OFFSET].constraint.string_list = mode_list;
375 dev->optionw[COLOR_OFFSET] = RGB;
376 dev->dn = 0;
377 dev->idx = cur_idx;
378 dev->status = STATUS_IDLE;
379
380 dev->next = devlist_head;
381 devlist_head = dev;
382 devlist_count++;
383
384
385
386 return SANE_STATUS_GOOD;
387 }
388
389 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback __sane_unused__ authorize)390 sane_init (SANE_Int * version_code,
391 SANE_Auth_Callback __sane_unused__ authorize)
392 {
393
394 if (version_code != NULL)
395 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
396
397 DBG_INIT();
398
399 sanei_usb_init ();
400
401 return SANE_STATUS_GOOD;
402 }
403
404 void
sane_exit(void)405 sane_exit (void)
406 {
407 /* free everything */
408 struct device_s *iter;
409
410 if (devlist)
411 {
412 int i;
413 for (i = 0; devlist[i]; i++)
414 free (devlist[i]);
415 free (devlist);
416 devlist = NULL;
417 }
418 if (devlist_head)
419 {
420 iter = devlist_head->next;
421 free (devlist_head);
422 devlist_head = NULL;
423 while (iter)
424 {
425 struct device_s *tmp = iter;
426 iter = iter->next;
427 free (tmp);
428 }
429 }
430 devlist_count = 0;
431 }
432
433 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool __sane_unused__ local_only)434 sane_get_devices (const SANE_Device * **device_list,
435 SANE_Bool __sane_unused__ local_only)
436 {
437 struct device_s *iter;
438 int i;
439
440 devlist_count = 0;
441
442 if (devlist_head)
443 {
444 iter = devlist_head->next;
445 free (devlist_head);
446 devlist_head = NULL;
447 while (iter)
448 {
449 struct device_s *tmp = iter;
450 iter = iter->next;
451 free (tmp);
452 }
453 }
454
455 /* Rebuild our internal scanner list */
456 for (cur_idx = 0; usbid[cur_idx].vendor_id; cur_idx++)
457 sanei_usb_find_devices (usbid[cur_idx].vendor_id,
458 usbid[cur_idx].product_id, attach);
459
460 if (devlist)
461 {
462 for (i = 0; devlist[i]; i++)
463 free (devlist[i]);
464 free (devlist);
465 }
466
467 /* rebuild the sane-API scanner list array */
468 devlist = malloc (sizeof (devlist[0]) * (devlist_count + 1));
469 if (!devlist)
470 return SANE_STATUS_NO_MEM;
471
472 memset (devlist, 0, sizeof (devlist[0]) * (devlist_count + 1));
473
474 for (i = 0, iter = devlist_head; i < devlist_count; i++, iter = iter->next)
475 {
476 devlist[i] = malloc (sizeof (SANE_Device));
477 if (!devlist[i])
478 {
479 int j;
480 for (j = 0; j < i; j++)
481 free (devlist[j]);
482 free (devlist);
483 devlist = NULL;
484 return SANE_STATUS_NO_MEM;
485 }
486 devlist[i]->name = iter->devname;
487 devlist[i]->vendor = usbid[iter->idx].vendor_s;
488 devlist[i]->model = usbid[iter->idx].model_s;
489 devlist[i]->type = usbid[iter->idx].type_s;
490 }
491 if (device_list)
492 *device_list = (const SANE_Device **) devlist;
493 return SANE_STATUS_GOOD;
494 }
495
496 SANE_Status
sane_open(SANE_String_Const name,SANE_Handle * h)497 sane_open (SANE_String_Const name, SANE_Handle * h)
498 {
499 struct device_s *dev;
500 int ret;
501
502 if(!devlist_head)
503 sane_get_devices(NULL,(SANE_Bool)0);
504
505 dev = devlist_head;
506
507 if (strlen (name))
508 for (; dev; dev = dev->next)
509 if (!strcmp (name, dev->devname))
510 break;
511
512 if (!dev) {
513 DBG(1,"Unable to find device %s\n",name);
514 return SANE_STATUS_INVAL;
515 }
516
517 DBG(1,"Found device %s\n",name);
518
519 /* Now open the usb device */
520 ret = sanei_usb_open (name, &(dev->dn));
521 if (ret != SANE_STATUS_GOOD) {
522 DBG(1,"Unable to open device %s\n",name);
523 return ret;
524 }
525
526 /* Claim the first interface */
527 ret = sanei_usb_claim_interface (dev->dn, 0);
528 if (ret != SANE_STATUS_GOOD)
529 {
530 sanei_usb_close (dev->dn);
531 /* if we cannot claim the interface, this is because
532 someone else is using it */
533 DBG(1,"Unable to claim scanner interface on device %s\n",name);
534 return SANE_STATUS_DEVICE_BUSY;
535 }
536 #ifdef HAVE_SANEI_USB_SET_TIMEOUT
537 sanei_usb_set_timeout (30000); /* 30s timeout */
538 #endif
539
540 *h = dev;
541
542 return SANE_STATUS_GOOD;
543 }
544
545 void
sane_close(SANE_Handle h)546 sane_close (SANE_Handle h)
547 {
548 struct device_s *dev = (struct device_s *) h;
549
550 /* Just in case if sane_cancel() is called
551 * after starting a scan but not while a sane_read
552 */
553 if (dev->status == STATUS_CANCELING)
554 {
555 do_cancel(dev);
556 }
557
558 sanei_usb_release_interface (dev->dn, 0);
559 sanei_usb_close (dev->dn);
560
561 }
562
563 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle h,SANE_Int option)564 sane_get_option_descriptor (SANE_Handle h, SANE_Int option)
565 {
566 struct device_s *dev = (struct device_s *) h;
567
568 if (option >= OPTION_MAX || option < 0)
569 return NULL;
570 return &(dev->optiond[option]);
571 }
572
573 static SANE_Status
getvalue(SANE_Handle h,SANE_Int option,void * v)574 getvalue (SANE_Handle h, SANE_Int option, void *v)
575 {
576 struct device_s *dev = (struct device_s *) h;
577
578 if (option != COLOR_OFFSET)
579 *((SANE_Word *) v) = dev->optionw[option];
580 else
581 {
582 strcpy ((char *) v,
583 dev->optiond[option].constraint.string_list[dev->
584 optionw[option]]);
585 }
586 return SANE_STATUS_GOOD;
587 }
588
589 static SANE_Status
setvalue(SANE_Handle h,SANE_Int option,void * value,SANE_Int * info)590 setvalue (SANE_Handle h, SANE_Int option, void *value, SANE_Int * info)
591 {
592 struct device_s *dev = (struct device_s *) h;
593 SANE_Status status = SANE_STATUS_GOOD;
594 int s_unit;
595 int s_unit_2;
596
597 if (option == 0)
598 return SANE_STATUS_UNSUPPORTED;
599
600
601 status = sanei_constrain_value (&(dev->optiond[option]), value, info);
602
603 if (status != SANE_STATUS_GOOD)
604 return status;
605
606
607
608 if (info)
609 *info |= SANE_INFO_RELOAD_PARAMS;
610 switch (option)
611 {
612 case X1_OFFSET:
613 dev->optionw[option] = *((SANE_Word *) value);
614 s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_X_S))
615 * MAX_X_H);
616 s_unit_2 = (int) round2 ((dev->optionw[X2_OFFSET] / ((double) MAX_X_S))
617 * MAX_X_H);
618 if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE)
619 s_unit = s_unit_2 - MIN_SCAN_ZONE;
620 dev->optionw[option] = round2 ((s_unit / ((double) MAX_X_H)) * MAX_X_S);
621 if (info)
622 *info |= SANE_INFO_INEXACT;
623 break;
624
625 case X2_OFFSET:
626 /* X units */
627 /* convert into "scanner" unit, then back into mm */
628 dev->optionw[option] = *((SANE_Word *) value);
629
630 s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_X_S))
631 * MAX_X_H);
632 s_unit_2 = (int) round2 ((dev->optionw[X1_OFFSET] / ((double) MAX_X_S))
633 * MAX_X_H);
634 if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE)
635 s_unit = s_unit_2 + MIN_SCAN_ZONE;
636 dev->optionw[option] = round2 ((s_unit / ((double) MAX_X_H)) * MAX_X_S);
637 if (info)
638 *info |= SANE_INFO_INEXACT;
639 break;
640 case Y1_OFFSET:
641 /* Y units */
642 dev->optionw[option] = *((SANE_Word *) value);
643
644 s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_Y_S))
645 * MAX_Y_H);
646
647 s_unit_2 = (int) round2 ((dev->optionw[Y2_OFFSET] / ((double) MAX_Y_S))
648 * MAX_Y_H);
649 if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE)
650 s_unit = s_unit_2 - MIN_SCAN_ZONE;
651
652 dev->optionw[option] = round2 ((s_unit / ((double) MAX_Y_H)) * MAX_Y_S);
653 if (info)
654 *info |= SANE_INFO_INEXACT;
655 break;
656 case Y2_OFFSET:
657 /* Y units */
658 dev->optionw[option] = *((SANE_Word *) value);
659
660 s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_Y_S))
661 * MAX_Y_H);
662
663 s_unit_2 = (int) round2 ((dev->optionw[Y1_OFFSET] / ((double) MAX_Y_S))
664 * MAX_Y_H);
665 if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE)
666 s_unit = s_unit_2 + MIN_SCAN_ZONE;
667
668 dev->optionw[option] = round2 ((s_unit / ((double) MAX_Y_H)) * MAX_Y_S);
669 if (info)
670 *info |= SANE_INFO_INEXACT;
671 break;
672 case COLOR_OFFSET:
673 if (!strcmp ((char *) value, mode_list[0]))
674 dev->optionw[option] = GRAY; /* Gray */
675 else if (!strcmp ((char *) value, mode_list[1]))
676 dev->optionw[option] = RGB; /* RGB */
677 else
678 return SANE_STATUS_INVAL;
679 break;
680 default:
681 dev->optionw[option] = *((SANE_Word *) value);
682 }
683 return SANE_STATUS_GOOD;
684 }
685
686 SANE_Status
sane_control_option(SANE_Handle h,SANE_Int option,SANE_Action a,void * v,SANE_Int * i)687 sane_control_option (SANE_Handle h, SANE_Int option,
688 SANE_Action a, void *v, SANE_Int * i)
689 {
690
691 if (option < 0 || option >= OPTION_MAX)
692 return SANE_STATUS_INVAL;
693
694 if (i)
695 *i = 0;
696
697
698 switch (a)
699 {
700 case SANE_ACTION_GET_VALUE:
701 return getvalue (h, option, v);
702
703 case SANE_ACTION_SET_VALUE:
704 return setvalue (h, option, v, i);
705
706 default:
707 return SANE_STATUS_INVAL;
708 }
709 }
710
711 SANE_Status
sane_get_parameters(SANE_Handle h,SANE_Parameters * p)712 sane_get_parameters (SANE_Handle h, SANE_Parameters * p)
713 {
714 struct device_s *dev = (struct device_s *) h;
715
716 if (!p)
717 return SANE_STATUS_INVAL;
718
719 p->format =
720 dev->optionw[COLOR_OFFSET] == RGB ? SANE_FRAME_RGB : SANE_FRAME_GRAY;
721 p->last_frame = SANE_TRUE;
722 p->depth = 8;
723
724 update_img_size (dev);
725 p->pixels_per_line = dev->width;
726 p->lines = dev->height;
727 p->bytes_per_line = p->pixels_per_line;
728 if (p->format == SANE_FRAME_RGB)
729 p->bytes_per_line *= 3;
730
731 return SANE_STATUS_GOOD;
732 }
733
734 static void
send_pkt(int command,int data_size,struct device_s * dev)735 send_pkt (int command, int data_size, struct device_s *dev)
736 {
737 size_t size = 32;
738
739 DBG(100,"Sending packet %d, next data size %d, device %s\n", command, data_size, dev->devname);
740
741 memset (dev->packet_data, 0, size);
742 dev->packet_data[0] = htonl (MAGIC_NUMBER);
743 dev->packet_data[1] = htonl (command);
744 dev->packet_data[5] = htonl (data_size);
745 sanei_usb_write_bulk (dev->dn, (unsigned char *) dev->packet_data, &size);
746 }
747
748
749 /* s: printer status */
750 /* Return the next packet size */
751 static int
wait_ack(struct device_s * dev,int * s)752 wait_ack (struct device_s *dev, int *s)
753 {
754 SANE_Status ret;
755 size_t size;
756 DBG(100, "Waiting scanner answer on device %s\n",dev->devname);
757 do
758 {
759 size = 32;
760 ret =
761 sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->packet_data,
762 &size);
763 }
764 while (SANE_STATUS_EOF == ret || size == 0);
765 if (s)
766 *s = ntohl (dev->packet_data[4]);
767 return ntohl (dev->packet_data[5]);
768 }
769
770 static void
send_conf(struct device_s * dev)771 send_conf (struct device_s *dev)
772 {
773 int y1, y2, x1, x2;
774 size_t size = 100;
775 DBG(100,"Sending configuration packet on device %s\n",dev->devname);
776 y1 = (int) round2 ((dev->optionw[Y1_OFFSET] / ((double) MAX_Y_S)) * MAX_Y_H);
777 y2 = (int) round2 ((dev->optionw[Y2_OFFSET] / ((double) MAX_Y_S)) * MAX_Y_H);
778 x1 = (int) round2 ((dev->optionw[X1_OFFSET] / ((double) MAX_X_S)) * MAX_X_H);
779 x2 = (int) round2 ((dev->optionw[X2_OFFSET] / ((double) MAX_X_S)) * MAX_X_H);
780
781 DBG(100,"\t x1: %d, x2: %d, y1: %d, y2: %d\n",x1, x2, y1, y2);
782 DBG(100,"\t brightness: %d, contrast: %d\n", dev->optionw[BRIGH_OFFSET], dev->optionw[CONTR_OFFSET]);
783 DBG(100,"\t resolution: %d\n",dev->optionw[RES_OFFSET]);
784
785 dev->conf_data[0] = htonl (0x15);
786 dev->conf_data[1] = htonl (dev->optionw[BRIGH_OFFSET]);
787 dev->conf_data[2] = htonl (dev->optionw[CONTR_OFFSET]);
788 dev->conf_data[3] = htonl (dev->optionw[RES_OFFSET]);
789 dev->conf_data[4] = htonl (0x1);
790 dev->conf_data[5] = htonl (0x1);
791 dev->conf_data[6] = htonl (0x1);
792 dev->conf_data[7] = htonl (0x1);
793 dev->conf_data[8] = 0;
794 dev->conf_data[9] = 0;
795 dev->conf_data[10] = htonl (0x8);
796 dev->conf_data[11] = 0;
797 dev->conf_data[12] = 0;
798 dev->conf_data[13] = 0;
799 dev->conf_data[14] = 0;
800 dev->conf_data[16] = htonl (y1);
801 dev->conf_data[17] = htonl (x1);
802 dev->conf_data[18] = htonl (y2);
803 dev->conf_data[19] = htonl (x2);
804 dev->conf_data[20] = 0;
805 dev->conf_data[21] = 0;
806 dev->conf_data[22] = htonl (0x491);
807 dev->conf_data[23] = htonl (0x352);
808
809 if (dev->optionw[COLOR_OFFSET] == RGB)
810 {
811 dev->conf_data[15] = htonl (0x2);
812 dev->conf_data[24] = htonl (0x1);
813 DBG(100,"\t Scanning in RGB format\n");
814 }
815 else
816 {
817 dev->conf_data[15] = htonl (0x6);
818 dev->conf_data[24] = htonl (0x0);
819 DBG(100,"\t Scanning in Grayscale format\n");
820 }
821 sanei_usb_write_bulk (dev->dn, (unsigned char *) dev->conf_data, &size);
822 }
823
824 static SANE_Status
get_data(struct device_s * dev)825 get_data (struct device_s *dev)
826 {
827 int color;
828 size_t size;
829 int packet_size;
830 unsigned char *buffer = (unsigned char *) dev->packet_data;
831 if (dev->status == STATUS_IDLE)
832 return SANE_STATUS_IO_ERROR;
833 /* first wait a standard data pkt */
834 do
835 {
836 size = 32;
837 sanei_usb_read_bulk (dev->dn, buffer, &size);
838 if (size)
839 {
840 if (ntohl (dev->packet_data[0]) == MAGIC_NUMBER)
841 {
842 if (ntohl (dev->packet_data[1]) == PKT_DATA)
843 break;
844 if (ntohl (dev->packet_data[1]) == PKT_END_DATA)
845 {
846 dev->status = STATUS_IDLE;
847 DBG(100,"End of scan encountered on device %s\n",dev->devname);
848 send_pkt (PKT_GO_IDLE, 0, dev);
849 wait_ack (dev, NULL);
850 wait_ack (dev, NULL);
851 send_pkt (PKT_UNKNOW_1, 0, dev);
852 wait_ack (dev, NULL);
853 send_pkt (PKT_RESET, 0, dev);
854 sleep (2); /* Time for the scanning head to go back home */
855 return SANE_STATUS_EOF;
856 }
857 }
858 }
859 }
860 while (1);
861 packet_size = ntohl (dev->packet_data[5]);
862 if (!dev->buffer)
863 {
864 dev->bufs = packet_size - 24 /* size of header */ ;
865 if (dev->optionw[COLOR_OFFSET] == RGB)
866 dev->bufs *= 3;
867 dev->buffer = malloc (dev->bufs);
868 if (!dev->buffer)
869 return SANE_STATUS_NO_MEM;
870 dev->write_offset_r = 0;
871 dev->write_offset_g = 1;
872 dev->write_offset_b = 2;
873
874 }
875 /* Get the "data header" */
876 do
877 {
878 size = 24;
879 sanei_usb_read_bulk (dev->dn, buffer, &size);
880 }
881 while (!size);
882 color = ntohl (dev->packet_data[0]);
883 packet_size -= size;
884 dev->width = ntohl (dev->packet_data[5]);
885 DBG(100,"Got data size %d on device %s. Scan width: %d\n",packet_size, dev->devname, dev->width);
886 /* Now, read the data */
887 do
888 {
889 int j;
890 int i;
891 int ret;
892 do
893 {
894 size = packet_size > 512 ? 512 : packet_size;
895 ret = sanei_usb_read_bulk (dev->dn, buffer, &size);
896 }
897 while (!size || ret != SANE_STATUS_GOOD);
898 packet_size -= size;
899 switch (color)
900 {
901 case RED_LAYER:
902 DBG(101,"Got red layer data on device %s\n",dev->devname);
903 i = dev->write_offset_r + 3 * size;
904 if (i > dev->bufs)
905 i = dev->bufs;
906 for (j = 0; dev->write_offset_r < i; dev->write_offset_r += 3)
907 dev->buffer[dev->write_offset_r] = buffer[j++];
908 break;
909 case GREEN_LAYER:
910 DBG(101,"Got green layer data on device %s\n",dev->devname);
911 i = dev->write_offset_g + 3 * size;
912 if (i > dev->bufs)
913 i = dev->bufs;
914 for (j = 0; dev->write_offset_g < i; dev->write_offset_g += 3)
915 dev->buffer[dev->write_offset_g] = buffer[j++];
916 break;
917 case BLUE_LAYER:
918 DBG(101,"Got blue layer data on device %s\n",dev->devname);
919 i = dev->write_offset_b + 3 * size;
920 if (i > dev->bufs)
921 i = dev->bufs;
922 for (j = 0; dev->write_offset_b < i; dev->write_offset_b += 3)
923 dev->buffer[dev->write_offset_b] = buffer[j++];
924 break;
925 case GRAY_LAYER:
926 DBG(101,"Got gray layer data on device %s\n",dev->devname);
927 if (dev->write_offset_r + (int)size >= dev->bufs)
928 size = dev->bufs - dev->write_offset_r;
929 memcpy (dev->buffer + dev->write_offset_r, buffer, size);
930 dev->write_offset_r += size;
931 break;
932 }
933 }
934 while (packet_size > 0);
935 return SANE_STATUS_GOOD;
936 }
937
938 SANE_Status
sane_start(SANE_Handle h)939 sane_start (SANE_Handle h)
940 {
941 struct device_s *dev = (struct device_s *) h;
942 int status;
943 size_t size;
944
945 dev->read_offset = 0;
946 dev->write_offset_r = 0;
947 dev->write_offset_g = 1;
948 dev->write_offset_b = 2;
949
950 free (dev->buffer);
951 dev->buffer = NULL;
952
953
954 send_pkt (PKT_RESET, 0, dev);
955 send_pkt (PKT_READ_STATUS, 0, dev);
956 wait_ack (dev, &status);
957 if (status)
958 return SANE_STATUS_IO_ERROR;
959
960 send_pkt (PKT_READCONF, 0, dev);
961
962 if ((size = wait_ack (dev, NULL)))
963 {
964 sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size);
965 }
966 send_pkt (PKT_SETCONF, 100, dev);
967 send_conf (dev);
968 wait_ack (dev, NULL);
969
970 send_pkt (PKT_START_SCAN, 0, dev);
971 wait_ack (dev, NULL);
972 if ((size = wait_ack (dev, NULL)))
973 {
974 sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size);
975 }
976 if ((size = wait_ack (dev, NULL)))
977 {
978 sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size);
979 }
980 if ((size = wait_ack (dev, NULL)))
981 {
982 sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size);
983 }
984
985 dev->status = STATUS_SCANNING;
986 /* Get the first data */
987 return get_data (dev);
988 }
989
990
991 static void
do_cancel(struct device_s * dev)992 do_cancel(struct device_s *dev)
993 {
994 while (get_data (dev) == SANE_STATUS_GOOD);
995 free (dev->buffer);
996 dev->buffer = NULL;
997 }
998
999 static int
min3(int r,int g,int b)1000 min3 (int r, int g, int b)
1001 {
1002 /* Optimize me ! */
1003 g--;
1004 b -= 2;
1005 if (r < g && r < b)
1006 return r;
1007 if (b < r && b < g)
1008 return b;
1009 return g;
1010 }
1011
1012 SANE_Status
sane_read(SANE_Handle h,SANE_Byte * buf,SANE_Int maxlen,SANE_Int * len)1013 sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
1014 {
1015 struct device_s *dev = (struct device_s *) h;
1016 int available;
1017 int ret;
1018 *len = 0;
1019 if (dev->status == STATUS_IDLE)
1020 return SANE_STATUS_IO_ERROR;
1021 if (dev->optionw[COLOR_OFFSET] == RGB)
1022 {
1023 while (min3 (dev->write_offset_r, dev->write_offset_g,
1024 dev->write_offset_b) <= dev->read_offset)
1025 {
1026 ret = get_data (dev);
1027 if (ret != SANE_STATUS_GOOD)
1028 {
1029 if (min3 (dev->write_offset_r,
1030 dev->write_offset_g,
1031 dev->write_offset_b) <= dev->read_offset)
1032 return ret;
1033 }
1034 }
1035 available = min3 (dev->write_offset_r, dev->write_offset_g,
1036 dev->write_offset_b);
1037 }
1038 else
1039 {
1040 while (dev->write_offset_r <= dev->read_offset)
1041 {
1042 ret = get_data (dev);
1043 if (ret != SANE_STATUS_GOOD)
1044 if (dev->write_offset_r <= dev->read_offset)
1045 return ret;
1046 }
1047 available = dev->write_offset_r;
1048 }
1049 *len = available - dev->read_offset;
1050 if (*len > maxlen)
1051 *len = maxlen;
1052 memcpy (buf, dev->buffer + dev->read_offset, *len);
1053 dev->read_offset += *len;
1054 if (dev->read_offset == dev->bufs)
1055 {
1056 free (dev->buffer);
1057 dev->buffer = NULL;
1058 dev->read_offset = 0;
1059 dev->write_offset_r = 0;
1060 dev->write_offset_g = 1;
1061 dev->write_offset_b = 2;
1062 }
1063
1064 /* Special case where sane_cancel is called while scanning */
1065 if (dev->status == STATUS_CANCELING)
1066 {
1067 do_cancel(dev);
1068 return SANE_STATUS_CANCELLED;
1069 }
1070 return SANE_STATUS_GOOD;
1071 }
1072
1073 void
sane_cancel(SANE_Handle h)1074 sane_cancel (SANE_Handle h)
1075 {
1076 struct device_s *dev = (struct device_s *) h;
1077
1078
1079 if (dev->status == STATUS_SCANNING)
1080 {
1081 dev->status = STATUS_CANCELING;
1082 return;
1083 }
1084
1085 free (dev->buffer);
1086 dev->buffer = NULL;
1087 }
1088
1089 SANE_Status
sane_set_io_mode(SANE_Handle __sane_unused__ handle,SANE_Bool __sane_unused__ non_blocking)1090 sane_set_io_mode (SANE_Handle __sane_unused__ handle,
1091 SANE_Bool __sane_unused__ non_blocking)
1092 {
1093 return SANE_STATUS_UNSUPPORTED;
1094 }
1095
1096 SANE_Status
sane_get_select_fd(SANE_Handle __sane_unused__ handle,SANE_Int __sane_unused__ * fd)1097 sane_get_select_fd (SANE_Handle __sane_unused__ handle,
1098 SANE_Int __sane_unused__ * fd)
1099 {
1100 return SANE_STATUS_UNSUPPORTED;
1101 }
1102