• 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  <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