• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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