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