1 /*
2    (c) 2001,2002 Nathan Rutman  nathan@gordian.com  10/17/01
3 
4    This program is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <https://www.gnu.org/licenses/>.
16 
17    As a special exception, the authors of SANE give permission for
18    additional uses of the libraries contained in this release of SANE.
19 
20    The exception is that, if you link a SANE library with other files
21    to produce an executable, this does not by itself cause the
22    resulting executable to be covered by the GNU General Public
23    License.  Your use of that executable is in no way restricted on
24    account of linking the SANE library code into it.
25 
26    This exception does not, however, invalidate any other reasons why
27    the executable file might be covered by the GNU General Public
28    License.
29 
30    If you submit changes to SANE to the maintainers to be included in
31    a subsequent release, you agree by submitting the changes that
32    those changes may be distributed with this exception intact.
33 
34    If you write modifications of your own for SANE, it is your choice
35    whether to permit this exception to apply to your modifications.
36    If you do not wish that, delete this exception notice.
37 */
38 
39 /*
40    Communication, calibration, and scanning with the Canon CanoScan FB630U
41    flatbed scanner under linux.
42 
43    Reworked into SANE-compatible format.
44 
45    The usb-parallel port interface chip is GL640usb, on the far side of
46    which is an LM9830 parallel-port scanner-on-a-chip.
47 
48    This code has not been tested on anything other than Linux/i386.
49 */
50 
51 #include <errno.h>
52 #include <fcntl.h>		/* open */
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <string.h>
56 #include <unistd.h>		/* usleep */
57 #include <time.h>
58 #include <math.h>               /* exp() */
59 #ifdef HAVE_OS2_H
60 #include <sys/types.h> 		/* mode_t */
61 #endif
62 #include <sys/stat.h>
63 #include "lm9830.h"
64 
65 #define USB_TYPE_VENDOR                 (0x02 << 5)
66 #define USB_RECIP_DEVICE                0x00
67 #define USB_DIR_OUT                     0x00
68 #define USB_DIR_IN                      0x80
69 
70 /* Assign status and verify a good return code */
71 #define CHK(A) {if( (status = A) != SANE_STATUS_GOOD ) { \
72                  DBG( 1, "Failure on line of %s: %d\n", __FILE__, \
73                       __LINE__ ); return A; }}
74 
75 
76 typedef SANE_Byte byte;
77 
78 
79 /*****************************************************
80             GL640 communication primitives
81    Provides I/O routines to Genesys Logic GL640USB USB-IEEE1284 parallel
82    port bridge.  Used in HP3300c, Canon FB630u.
83 ******************************************************/
84 
85 /* Register codes for the bridge.  These are NOT the registers for the
86    scanner chip on the other side of the bridge. */
87 typedef enum
88 {
89   GL640_BULK_SETUP = 0x82,
90   GL640_EPP_ADDR = 0x83,
91   GL640_EPP_DATA_READ = 0x84,
92   GL640_EPP_DATA_WRITE = 0x85,
93   GL640_SPP_STATUS = 0x86,
94   GL640_SPP_CONTROL = 0x87,
95   GL640_SPP_DATA = 0x88,
96   GL640_GPIO_OE = 0x89,
97   GL640_GPIO_READ = 0x8a,
98   GL640_GPIO_WRITE = 0x8b
99 }
100 GL640_Request;
101 
102 /* Write to the usb-parallel port bridge. */
103 static SANE_Status
gl640WriteControl(int fd,GL640_Request req,byte * data,unsigned int size)104 gl640WriteControl (int fd, GL640_Request req, byte * data, unsigned int size)
105 {
106   SANE_Status status;
107   status = sanei_usb_control_msg (fd,
108 				  /* rqttype */ USB_TYPE_VENDOR |
109 				  USB_RECIP_DEVICE | USB_DIR_OUT /*0x40? */ ,
110 				  /* rqt */ (size > 1) ? 0x04 : 0x0C,
111 				  /* val */ (SANE_Int) req,
112 				  /* ind */ 0,
113 				  /* len */ size,
114 				  /* dat */ data);
115   if (status != SANE_STATUS_GOOD)
116     DBG (1, "gl640WriteControl error\n");
117   return status;
118 }
119 
120 
121 /* Read from the usb-parallel port bridge. */
122 static SANE_Status
gl640ReadControl(int fd,GL640_Request req,byte * data,unsigned int size)123 gl640ReadControl (int fd, GL640_Request req, byte * data, unsigned int size)
124 {
125   SANE_Status status;
126   status = sanei_usb_control_msg (fd,
127 				  /* rqttype */ USB_TYPE_VENDOR |
128 				  USB_RECIP_DEVICE | USB_DIR_IN /*0xc0? */ ,
129 				  /* rqt */ (size > 1) ? 0x04 : 0x0C,
130 				  /* val */ (SANE_Int) req,
131 				  /* ind */ 0,
132 				  /* len */ size,
133 				  /* dat */ data);
134   if (status != SANE_STATUS_GOOD)
135     DBG (1, "gl640ReadControl error\n");
136   return status;
137 }
138 
139 
140 /* Wrappers to read or write a single byte to the bridge */
141 static inline SANE_Status
gl640WriteReq(int fd,GL640_Request req,byte data)142 gl640WriteReq (int fd, GL640_Request req, byte data)
143 {
144   return gl640WriteControl (fd, req, &data, 1);
145 }
146 
147 static inline SANE_Status
gl640ReadReq(int fd,GL640_Request req,byte * data)148 gl640ReadReq (int fd, GL640_Request req, byte * data)
149 {
150   return gl640ReadControl (fd, req, data, 1);
151 }
152 
153 
154 /* Write USB bulk data
155    setup is an apparently scanner-specific sequence:
156    {(0=read, 1=write), 0x00, 0x00, 0x00, sizelo, sizehi, 0x00, 0x00}
157    hp3400: setup[1] = 0x01
158    fb630u: setup[2] = 0x80
159 */
160 static SANE_Status
gl640WriteBulk(int fd,byte * setup,byte * data,size_t size)161 gl640WriteBulk (int fd, byte * setup, byte * data, size_t size)
162 {
163   SANE_Status status;
164   setup[0] = 1;
165   setup[4] = (size) & 0xFF;
166   setup[5] = (size >> 8) & 0xFF;
167 
168   CHK (gl640WriteControl (fd, GL640_BULK_SETUP, setup, 8));
169 
170   status = sanei_usb_write_bulk (fd, data, &size);
171   if (status != SANE_STATUS_GOOD)
172     DBG (1, "gl640WriteBulk error\n");
173 
174   return status;
175 }
176 
177 
178 /* Read USB bulk data
179    setup is an apparently scanner-specific sequence:
180    {(0=read, 1=write), 0x00, 0x00, 0x00, sizelo, sizehi, 0x00, 0x00}
181    fb630u: setup[2] = 0x80
182 */
183 static SANE_Status
gl640ReadBulk(int fd,byte * setup,byte * data,size_t size)184 gl640ReadBulk (int fd, byte * setup, byte * data, size_t size)
185 {
186   SANE_Status status;
187   setup[0] = 0;
188   setup[4] = (size) & 0xFF;
189   setup[5] = (size >> 8) & 0xFF;
190 
191   CHK (gl640WriteControl (fd, GL640_BULK_SETUP, setup, 8));
192 
193   status = sanei_usb_read_bulk (fd, data, &size);
194   if (status != SANE_STATUS_GOOD)
195     DBG (1, "gl640ReadBulk error\n");
196 
197   return status;
198 }
199 
200 
201 /*****************************************************
202             LM9830 communication primitives
203 	    parallel-port scanner-on-a-chip.
204 ******************************************************/
205 
206 /* write 1 byte to a LM9830 register address */
207 static SANE_Status
write_byte(int fd,byte addr,byte val)208 write_byte (int fd, byte addr, byte val)
209 {
210   SANE_Status status;
211   DBG (14, "write_byte(fd, 0x%02x, 0x%02x);\n", addr, val);
212   CHK (gl640WriteReq (fd, GL640_EPP_ADDR, addr));
213   CHK (gl640WriteReq (fd, GL640_EPP_DATA_WRITE, val));
214   return status;
215 }
216 
217 
218 /* read 1 byte from a LM9830 register address */
219 static SANE_Status
read_byte(int fd,byte addr,byte * val)220 read_byte (int fd, byte addr, byte * val)
221 {
222   SANE_Status status;
223   CHK (gl640WriteReq (fd, GL640_EPP_ADDR, addr));
224   CHK (gl640ReadReq (fd, GL640_EPP_DATA_READ, val));
225   DBG (14, "read_byte(fd, 0x%02x, &result); /* got %02x */\n", addr, *val);
226   return status;
227 }
228 
229 
230 static byte bulk_setup_data[] = { 0, 0, 0x80, 0, 0, 0, 0, 0 };
231 
232 /* Bulk write */
233 static SANE_Status
write_bulk(int fd,unsigned int addr,void * src,size_t count)234 write_bulk (int fd, unsigned int addr, void *src, size_t count)
235 {
236   SANE_Status status;
237 
238   DBG (13, "write_bulk(fd, 0x%02x, buf, 0x%04lx);\n", addr, (u_long) count);
239 
240   if (!src)
241     {
242       DBG (1, "write_bulk: bad src\n");
243       return SANE_STATUS_INVAL;
244     }
245 
246   /* destination address */
247   CHK (gl640WriteReq (fd, GL640_EPP_ADDR, addr));
248   /* write */
249   CHK (gl640WriteBulk (fd, bulk_setup_data, src, count));
250   return status;
251 }
252 
253 
254 /* Bulk read */
255 static SANE_Status
read_bulk(int fd,unsigned int addr,void * dst,size_t count)256 read_bulk (int fd, unsigned int addr, void *dst, size_t count)
257 {
258   SANE_Status status;
259 
260   DBG (13, "read_bulk(fd, 0x%02x, buf, 0x%04lx);\n", addr, (u_long) count);
261 
262   if (!dst)
263     {
264       DBG (1, "read_bulk: bad dest\n");
265       return SANE_STATUS_INVAL;
266     }
267 
268   /* destination address */
269   CHK (gl640WriteReq (fd, GL640_EPP_ADDR, addr));
270   /* read */
271   CHK (gl640ReadBulk (fd, bulk_setup_data, dst, count));
272   return status;
273 }
274 
275 
276 
277 /*****************************************************
278             useful macro routines
279 ******************************************************/
280 
281 /* write a 16-bit int to two sequential registers */
282 static SANE_Status
write_word(int fd,unsigned int addr,unsigned int data)283 write_word (int fd, unsigned int addr, unsigned int data)
284 {
285   SANE_Status status;
286   /* MSB */
287   CHK (write_byte (fd, addr, (data >> 8) & 0xff));
288   /* LSB */
289   CHK (write_byte (fd, addr + 1, data & 0xff));
290   return status;
291 }
292 
293 
294 /* write multiple bytes, one at a time (non-bulk) */
295 static SANE_Status
write_many(int fd,unsigned int addr,const byte * src,size_t count)296 write_many (int fd, unsigned int addr, const byte *src, size_t count)
297 {
298   SANE_Status status;
299   size_t i;
300 
301   DBG (14, "multi write %lu\n", (u_long) count);
302   for (i = 0; i < count; i++)
303     {
304       DBG (15, " %04lx:%02x", (u_long) (addr + i), src[i]);
305       status = write_byte (fd, addr + i, src[i]);
306       if (status != SANE_STATUS_GOOD)
307 	{
308 	  DBG (15, "\n");
309 	  return status;
310 	}
311     }
312   DBG (15, "\n");
313   return SANE_STATUS_GOOD;
314 }
315 
316 
317 /* read multiple bytes, one at a time (non-bulk) */
318 static SANE_Status
read_many(int fd,unsigned int addr,void * dst,size_t count)319 read_many (int fd, unsigned int addr, void *dst, size_t count)
320 {
321   SANE_Status status;
322   size_t i;
323   byte val;
324 
325   DBG (14, "multi read %lu\n", (u_long) count);
326   for (i = 0; i < count; i++)
327     {
328       status = read_byte (fd, addr + i, &val);
329       ((byte *) dst)[i] = val;
330       DBG (15, " %04lx:%02x", (u_long) (addr + i), ((byte *) dst)[i]);
331       /* on err, return number of success */
332       if (status != SANE_STATUS_GOOD)
333 	{
334 	  DBG (15, "\n");
335 	  return status;
336 	}
337     }
338   DBG (15, "\n");
339   return SANE_STATUS_GOOD;
340 }
341 
342 
343 /* Poll addr until result & mask = val */
344 static int
read_poll_flag(int fd,unsigned int addr,unsigned int mask,unsigned int val)345 read_poll_flag (int fd,
346 		unsigned int addr, unsigned int mask, unsigned int val)
347 {
348   SANE_Status status;
349   byte result = 0;
350   time_t start_time = time (NULL);
351 
352   DBG (12, "read_poll_flag...\n");
353   do
354     {
355       status = read_byte (fd, addr, &result);
356       if (status != SANE_STATUS_GOOD)
357 	return -1;
358       /* Give it a minute */
359       if ((time (NULL) - start_time) > 60)
360 	{
361 	  DBG (1, "read_poll_flag: timed out (%d)\n", result);
362 	  return -1;
363 	}
364       usleep (100000);
365     }
366   while ((result & mask) != val);
367   return result;
368 }
369 
370 
371 /* Keep reading addr until results >= min */
372 static int
read_poll_min(int fd,unsigned int addr,unsigned int min)373 read_poll_min (int fd, unsigned int addr, unsigned int min)
374 {
375   SANE_Status status;
376   byte result;
377   time_t start_time = time (NULL);
378 
379   DBG (12, "waiting...\n");
380   do
381     {
382       status = read_byte (fd, addr, &result);
383       if (status != SANE_STATUS_GOOD)
384 	return -1;
385       /* Give it a minute */
386       if ((time (NULL) - start_time) > 60)
387 	{
388 	  DBG (1, "read_poll_min: timed out (%d < %d)\n", result, min);
389 	  return -1;
390 	}
391       /* no sleep here, or calibration gets unhappy. */
392     }
393   while (result < min);
394   return result;
395 }
396 
397 
398 /* Bulk read "ks" kilobytes + "remainder" bytes of data, to a buffer if the
399    buffer is valid. */
400 static int
read_bulk_size(int fd,int ks,int remainder,byte * dest,int destsize)401 read_bulk_size (int fd, int ks, int remainder, byte * dest, int destsize)
402 {
403   byte *buf;
404   int bytes = (ks - 1) * 1024 + remainder;
405   int dropdata = ((dest == 0) || (destsize < bytes));
406 
407   if (bytes < 0)
408     {
409       DBG (1, "read_bulk_size: invalid size %02x (%d)\n", ks, bytes);
410       return -1;
411     }
412   if (destsize && (destsize < bytes))
413     {
414       DBG (3, "read_bulk_size: more data than buffer (%d/%d)\n",
415 	   destsize, bytes);
416       bytes = destsize;
417     }
418 
419   if (bytes == 0)
420     return 0;
421 
422   if (dropdata)
423     {
424       buf = malloc (bytes);
425       DBG (3, " ignoring data ");
426     }
427   else
428     buf = dest;
429 
430   read_bulk (fd, 0x00, buf, bytes);
431 
432   if (dropdata)
433     free (buf);
434   return bytes;
435 }
436 
437 
438 
439 /*****************************************************
440 
441             fb630u calibration and scan
442 
443 ******************************************************/
444 
445 /* data structures and constants */
446 
447 typedef struct CANON_Handle
448 {
449   int fd;			/* scanner fd */
450   int x1, x2, y1, y2;		/* in pixels, 600 dpi */
451   int width, height;		/* at scan resolution */
452   int resolution;		/* dpi */
453   char *fname;			/* output file name */
454   FILE *fp;			/* output file pointer (for reading) */
455   char *buf, *ptr;		/* data buffer */
456   unsigned char gain;		/* static analog gain, 0 - 31 */
457   double gamma;		        /* gamma correction */
458   int flags;
459 #define FLG_GRAY	0x01	/* grayscale */
460 #define FLG_FORCE_CAL	0x02	/* force calibration */
461 #define FLG_BUF		0x04	/* save scan to buffer instead of file */
462 #define FLG_NO_INTERLEAVE 0x08	/* don't interleave r,g,b pixels; leave them
463 				   in row format */
464 #define FLG_PPM_HEADER	0x10	/* include PPM header in scan file */
465 }
466 CANON_Handle;
467 
468 
469 /* offset/gain calibration file name */
470 #define CAL_FILE_OGN "/tmp/canon.cal"
471 
472 /* at 600 dpi */
473 #define CANON_MAX_WIDTH    5100	/* 8.5in */
474 /* this may not be right */
475 #define CANON_MAX_HEIGHT   7000	/* 11.66in */
476 
477 /* scanline end-of-line data byte, returned after each r,g,b segment,
478    specific to the FB630u */
479 #define SCANLINE_END	0x0c
480 
481 
482 static const byte seq002[] =
483   { /*r08 */ 0x04, /*300 dpi */ 0x1a, 0x00, 0x0d, 0x4c, 0x2f, 0x00, 0x01,
484 /*r10 */ 0x07, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x25, 0x00,
485 0x4b, /*r20 */ 0x15, 0xe0, /*data px start */ 0x00, 0x4b, /*data px end */ 0x14, 0x37, 0x15, 0x00 };
486 
487 static const byte seq003[] =
488   { 0x02, 0x00, 0x00, /*lights out */ 0x03, 0xff, 0x00, 0x01, 0x03, 0xff,
489 0x00, 0x01, 0x03, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
490 0x1d, 0x00, 0x13, 0x04, 0x1a, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x57, 0x02, 0x00, 0x3c, 0x35, 0x94,
491 0x00, 0x10, 0x08, 0x3f, 0x2b, 0x91, 0x00, 0x00, 0x01, 0x00, 0x80, 0x00 };
492 
493 
494 /* Scanner init, called at calibration and scan time.  Returns 1 if this
495    was the first time the scanner was plugged in, 0 afterward, and
496    -1 on error. */
497 static int
init(int fd)498 init (int fd)
499 {
500   byte result, rv;
501 
502   if (gl640WriteReq (fd, GL640_GPIO_OE, 0x71) != SANE_STATUS_GOOD) {
503       DBG(1, "Initial write request failed.\n");
504       return -1;
505   }
506   /* Gets 0x04 or 0x05 first run, gets 0x64 subsequent runs. */
507   if (gl640ReadReq (fd, GL640_GPIO_READ, &rv) != SANE_STATUS_GOOD) {
508       DBG(1, "Initial read request failed.\n");
509       return -1;
510   }
511   gl640WriteReq (fd, GL640_GPIO_OE, 0x70);
512 
513   DBG (2, "init query: %x\n", rv);
514   if (rv != 0x64)
515     {
516       gl640WriteReq (fd, GL640_GPIO_WRITE, 0x00);
517       gl640WriteReq (fd, GL640_GPIO_WRITE, 0x40);
518     }
519 
520   gl640WriteReq (fd, GL640_SPP_DATA, 0x99);
521   gl640WriteReq (fd, GL640_SPP_DATA, 0x66);
522   gl640WriteReq (fd, GL640_SPP_DATA, 0xcc);
523   gl640WriteReq (fd, GL640_SPP_DATA, 0x33);
524   /* parallel port setting */
525   write_byte (fd, PARALLEL_PORT, 0x06);
526   /* sensor control settings */
527   write_byte (fd, 0x0b, 0x0d);
528   write_byte (fd, 0x0c, 0x4c);
529   write_byte (fd, 0x0d, 0x2f);
530   read_byte (fd, 0x0b, &result);	/* wants 0d */
531   read_byte (fd, 0x0c, &result);	/* wants 4c */
532   read_byte (fd, 0x0d, &result);	/* wants 2f */
533   /* parallel port noise filter */
534   write_byte (fd, 0x70, 0x73);
535 
536   DBG (2, "init post-reset: %x\n", rv);
537   /* Returns 1 if this was the first time the scanner was plugged in. */
538   return (rv != 0x64);
539 }
540 
541 
542 /* Turn off the lamps */
543 static void
lights_out(int fd)544 lights_out (int fd)
545 {
546   write_word (fd, LAMP_R_ON, 0x3fff);
547   write_word (fd, LAMP_R_OFF, 0x0001);
548   write_word (fd, LAMP_G_ON, 0x3fff);
549   write_word (fd, LAMP_G_OFF, 0x0001);
550   write_word (fd, LAMP_B_ON, 0x3fff);
551   write_word (fd, LAMP_B_OFF, 0x0001);
552 }
553 
554 
555 /* Do the scan and save the resulting image as r,g,b interleaved PPM
556    file.  */
557 static SANE_Status
do_scan(CANON_Handle * s)558 do_scan (CANON_Handle * s)
559 {
560   SANE_Status status = SANE_STATUS_GOOD;
561   int numbytes, datasize, level = 0, line = 0, pixel = 0;
562   byte *buf, *ptr, *redptr;
563   FILE *fp;
564 
565 #define BUFSIZE 0xf000
566   buf = malloc (BUFSIZE);
567   if (!buf)
568     return SANE_STATUS_NO_MEM;
569 
570   if (s->flags & FLG_BUF)
571     {
572       /* read the whole thing into buf */
573       if (!s->buf)
574 	return SANE_STATUS_NO_MEM;
575       s->ptr = s->buf;
576       fp = NULL;
577     }
578   else
579     {
580       fp = fopen (s->fname, "w");
581       if (!fp)
582 	{
583 	  free (buf);
584 	  DBG (1, "err:%s when opening %s\n", strerror (errno), s->fname);
585 	  return SANE_STATUS_IO_ERROR;
586 	}
587     }
588   if (fp && (s->flags & FLG_PPM_HEADER))
589     /* PPM format header */
590     fprintf (fp, "P6\n%d %d\n255\n", s->width, s->height);
591 
592   /* lights off */
593   write_byte (s->fd, COMMAND, 0x08);
594   /* lights on */
595   write_byte (s->fd, COMMAND, 0x00);
596   /* begin scan */
597   write_byte (s->fd, COMMAND, 0x03);
598 
599   ptr = redptr = buf;
600   while (line < s->height)
601     {
602       datasize = read_poll_min (s->fd, IMAGE_DATA_AVAIL, 2);
603       if (datasize < 0)
604 	{
605 	  DBG (1, "no data\n");
606 	  break;
607 	}
608       DBG (12, "scan line %d %dk\n", line, datasize - 1);
609       /* Read may cause scan head to move */
610       numbytes = read_bulk_size (s->fd, datasize, 0, ptr, BUFSIZE - level);
611       if (numbytes < 0)
612 	{
613 	  status = SANE_STATUS_INVAL;
614 	  break;
615 	}
616       /* Data coming back is "width" bytes Red data followed by 0x0c,
617          width bytes Green, 0x0c, width bytes Blue, 0x0c, repeat for
618          "height" lines. */
619       if (s->flags & FLG_NO_INTERLEAVE)
620 	{
621 	  /* number of full lines */
622 	  line += (numbytes + level) / (s->width * 3);
623 	  /* remainder (partial line) */
624 	  level = (numbytes + level) % (s->width * 3);
625 	  /* but if last line, don't store extra */
626 	  if (line >= s->height)
627 	    numbytes -= (line - s->height) * s->width * 3 + level;
628 	  if (fp)
629 	    fwrite (buf, 1, numbytes, fp);
630 	  else
631 	    {
632 	      memcpy (s->ptr, buf, numbytes);
633 	      s->ptr += numbytes;
634 	    }
635 	}
636       else
637 	{
638 	  /* Contorsions to convert data from line-by-line RGB to
639 	     byte-by-byte RGB, without reading in the whole buffer first.
640 	     We use the sliding window redptr with the temp buffer buf. */
641 	  ptr += numbytes;	/* point to the end of data */
642 	  /* while we have RGB triple data */
643 	  while (redptr + s->width + s->width <= ptr)
644 	    {
645 	      if (*redptr == SCANLINE_END)
646 		DBG (13, "-%d- ", pixel);
647 	      if (fp)
648 		{
649 		  /* for PPM binary (P6), 3-byte RGB pixel */
650 		  fwrite (redptr, 1, 1, fp);	/* Red */
651 		  fwrite (redptr + s->width, 1, 1, fp);	/* Green */
652 		  fwrite (redptr + s->width + s->width, 1, 1, fp);	/* Blue */
653 		  /* for PPM ascii (P3)
654 		     fprintf(fp, "%3d %3d %3d\n",  *redptr,
655 		     *(redptr + s->width),
656 		     *(redptr + s->width + s->width));
657 		   */
658 		}
659 	      else
660 		{
661 		  /* R */ *s->ptr = *redptr;
662 		  s->ptr++;
663 		  /* G */ *s->ptr = *(redptr + s->width);
664 		  s->ptr++;
665 		  /* B */ *s->ptr = *(redptr + s->width + s->width);
666 		  s->ptr++;
667 		}
668 	      redptr++;
669 	      pixel++;
670 	      if (pixel && !(pixel % s->width))
671 		{
672 		  /* end of a line, move redptr to the next Red section */
673 		  line++;
674 		  redptr += s->width + s->width;
675 #if 0
676 		  /* progress */
677 		  printf ("%2d%%\r", line * 100 / s->height);
678 		  fflush (stdout);
679 #endif
680 		  /* don't record any extra */
681 		  if (line >= s->height)
682 		    break;
683 		}
684 	    }
685 	  /* keep the extra around for next time */
686 	  level = ptr - redptr;
687 	  if (level < 0)
688 	    level = 0;
689 	  memmove (buf, redptr, level);
690 	  ptr = buf + level;
691 	  redptr = buf;
692 	}
693     }
694 
695   if (fp)
696     {
697       fclose (fp);
698       DBG (6, "created scan file %s\n", s->fname);
699     }
700   free (buf);
701   DBG (6, "%d lines, %d pixels, %d extra bytes\n", line, pixel, level);
702 
703   /* motor off */
704   write_byte (s->fd, COMMAND, 0x00);
705 
706   return status;
707 }
708 
709 
710 static int
wait_for_return(int fd)711 wait_for_return (int fd)
712 {
713   return read_poll_flag (fd, STATUS, STATUS_HOME, STATUS_HOME);
714 }
715 
716 
717 static SANE_Status compute_ogn (char *calfilename);
718 
719 
720 /* This is the calibration routine Win2k goes through when the scanner is
721    first plugged in.
722    Original usb trace from Win2k with USBSnoopy ("usb sniffer for w2k"
723    http://benoit.papillault.free.fr/speedtouch/sniff-2000.en.php3)
724  */
725 static int
plugin_cal(CANON_Handle * s)726 plugin_cal (CANON_Handle * s)
727 {
728   SANE_Status status;
729   unsigned int temp;
730   byte result;
731   byte *buf;
732   int fd = s->fd;
733 
734   DBG (6, "Calibrating\n");
735 
736   /* reserved? */
737   read_byte (fd, 0x69, &result);	/* wants 02 */
738 
739   /* parallel port setting */
740   write_byte (fd, PARALLEL_PORT, 0x06);
741 
742   write_many (fd, 0x08, seq002, sizeof (seq002));
743   /* addr 0x28 isn't written */
744   write_many (fd, 0x29, seq003, sizeof (seq003));
745   /* Verification */
746   buf = malloc (0x400);
747   read_many (fd, 0x08, buf, sizeof (seq002));
748   if (memcmp (seq002, buf, sizeof (seq002)))
749     DBG (1, "seq002 verification error\n");
750   /* addr 0x28 isn't read */
751   read_many (fd, 0x29, buf, sizeof (seq003));
752   if (memcmp (seq003, buf, sizeof (seq003)))
753     DBG (1, "seq003 verification error\n");
754 
755   /* parallel port noise filter */
756   write_byte (fd, 0x70, 0x73);
757 
758   lights_out (fd);
759 
760   /* Home motor */
761   read_byte (fd, STATUS, &result);	/* wants 2f or 2d */
762   if (!(result & STATUS_HOME) /*0x2d */ )
763     write_byte (fd, COMMAND, 0x02);
764 
765   wait_for_return (fd);
766 
767   /* Motor forward */
768   write_byte (fd, COMMAND, 0x01);
769   usleep (600000);
770   read_byte (fd, STATUS, &result);	/* wants 0c or 2c */
771   read_byte (fd, STATUS, &result);	/* wants 0c */
772   /* Return home */
773   write_byte (fd, COMMAND, 0x02);
774 
775   /* Gamma tables */
776   /* Linear gamma */
777   for (temp = 0; temp < 0x0400; temp++)
778     buf[temp] = temp / 4;
779   /* Gamma Red */
780   write_byte (fd, DATAPORT_TARGET, DP_R | DP_GAMMA);
781   write_word (fd, DATAPORT_ADDR, DP_WRITE);
782   write_bulk (fd, DATAPORT, buf, 0x0400);
783   /* Gamma Green */
784   write_byte (fd, DATAPORT_TARGET, DP_G | DP_GAMMA);
785   write_word (fd, DATAPORT_ADDR, DP_WRITE);
786   write_bulk (fd, DATAPORT, buf, 0x0400);
787   /* Gamma Blue */
788   write_byte (fd, DATAPORT_TARGET, DP_B | DP_GAMMA);
789   write_word (fd, DATAPORT_ADDR, DP_WRITE);
790   write_bulk (fd, DATAPORT, buf, 0x0400);
791 
792   /* Read back gamma tables.  I suppose I should check results... */
793   /* Gamma Red */
794   write_byte (fd, DATAPORT_TARGET, DP_R | DP_GAMMA);
795   write_word (fd, DATAPORT_ADDR, DP_READ);
796   read_bulk (fd, DATAPORT, buf, 0x0400);
797   /* Gamma Green */
798   write_byte (fd, DATAPORT_TARGET, DP_G | DP_GAMMA);
799   write_word (fd, DATAPORT_ADDR, DP_READ);
800   read_bulk (fd, DATAPORT, buf, 0x0400);
801   /* Gamma Blue */
802   write_byte (fd, DATAPORT_TARGET, DP_B | DP_GAMMA);
803   write_word (fd, DATAPORT_ADDR, DP_READ);
804   read_bulk (fd, DATAPORT, buf, 0x0400);
805   free (buf);
806 
807   /* Make sure STATUS_HOME */
808   read_byte (fd, STATUS, &result);	/* wants 0e */
809   /* stepper forward */
810   write_byte (fd, COMMAND, 0x01);
811   read_byte (fd, STATUS, &result);	/* wants 0c */
812   /* not sure if this rigid read/write pattern is required */
813   read_byte (fd, CLOCK_DIV, &result);	/* wants 04 */
814   write_byte (fd, CLOCK_DIV, 0x04);
815   read_byte (fd, STEP_SIZE, &result);	/* wants 04 */
816   write_byte (fd, STEP_SIZE, 0x3f);
817   read_byte (fd, 0x47, &result);	/* wants 1a */
818   write_byte (fd, 0x47, 0xff);
819   read_byte (fd, FAST_STEP, &result);	/* wants 01 */
820   write_byte (fd, FAST_STEP, 0x01);
821   read_byte (fd, 0x49, &result);	/* wants 04 */
822   write_byte (fd, 0x49, 0x04);
823   read_byte (fd, SKIP_STEPS, &result);	/* wants 00 */
824   write_byte (fd, SKIP_STEPS, 0x00);
825   read_byte (fd, 0x4b, &result);	/* wants 00 */
826   write_byte (fd, 0x4b, 0xc8);
827   read_byte (fd, BUFFER_LIMIT, &result);	/* wants 57 */
828   write_byte (fd, BUFFER_LIMIT, 0x04);
829   read_byte (fd, BUFFER_RESUME, &result);	/* wants 02 */
830   write_byte (fd, BUFFER_RESUME, 0x02);
831   read_byte (fd, REVERSE_STEPS, &result);	/* wants 00 */
832   write_byte (fd, REVERSE_STEPS, 0x00);
833   write_byte (fd, STEP_PWM, 0x1f);
834 
835   /* Reset motor */
836   write_byte (fd, COMMAND, 0x08);
837   write_byte (fd, COMMAND, 0x00);
838   /* Scan */
839   write_byte (fd, COMMAND, 0x03);
840   /* Wants 02 or 03, gets a bunch of 0's first */
841   read_poll_min (fd, IMAGE_DATA_AVAIL, 2);
842   write_byte (fd, COMMAND, 0x00);
843 
844   write_byte (fd, STEP_PWM, 0x3f);
845   write_byte (fd, CLOCK_DIV, 0x04);
846   /* 300 dpi */
847   write_word (fd, STEP_SIZE, 0x041a);
848   write_word (fd, FAST_STEP, 0x0104);
849   /* Don't skip the black/white calibration area at the bottom of the
850      scanner. */
851   write_word (fd, SKIP_STEPS, 0x0000);
852   write_byte (fd, BUFFER_LIMIT, 0x57);
853   write_byte (fd, BUFFER_RESUME, 0x02);
854   write_byte (fd, REVERSE_STEPS, 0x00);
855   write_byte (fd, BUFFER_LIMIT, 0x09);
856   write_byte (fd, STEP_PWM, 0x1f);
857   read_byte (fd, MICROSTEP, &result);	/* wants 13, active */
858   write_byte (fd, MICROSTEP, 0x03 /* tristate */ );
859 
860   /* Calibration data taken under 3 different lighting conditions */
861   /* dark */
862   write_word (fd, LAMP_R_ON, 0x0017);
863   write_word (fd, LAMP_R_OFF, 0x0100);
864   write_word (fd, LAMP_G_ON, 0x0017);
865   write_word (fd, LAMP_G_OFF, 0x0100);
866   write_word (fd, LAMP_B_ON, 0x0017);
867   write_word (fd, LAMP_B_OFF, 0x0100);
868   /* coming in, we've got 300dpi,
869      data px start : 0x004b
870      data px end  : 0x1437 for a total of 5100(13ec) 600-dpi pixels,
871      (8.5 inches) or 2550 300-dpi pixels (7653 bytes).
872      Interestingly, the scan head never moves, no matter how many rows
873      are read. */
874   s->width = 2551;
875   s->height = 1;
876   s->flags = FLG_BUF | FLG_NO_INTERLEAVE;
877   s->buf = malloc (s->width * s->height * 3);
878   /* FIXME do something with this data */
879   CHK (do_scan (s));
880 
881   /* Lighting */
882   /* medium */
883   write_word (fd, LAMP_R_ON, 0x0017);
884   write_word (fd, LAMP_R_OFF, 0x0200);
885   write_word (fd, LAMP_G_ON, 0x0017);
886   write_word (fd, LAMP_G_OFF, 0x01d7 /* also 01db */ );
887   write_word (fd, LAMP_B_ON, 0x0017);
888   write_word (fd, LAMP_B_OFF, 0x01af /* also 01b2 */ );
889   /* FIXME do something with this data */
890   CHK (do_scan (s));
891 
892   /* Lighting */
893   /* bright */
894   write_word (fd, LAMP_R_ON, 0x0017);
895   write_word (fd, LAMP_R_OFF, 0x0e8e /* also 1040 */ );
896   write_word (fd, LAMP_G_ON, 0x0017);
897   write_word (fd, LAMP_G_OFF, 0x0753 /* also 0718 */ );
898   write_word (fd, LAMP_B_ON, 0x0017);
899   write_word (fd, LAMP_B_OFF, 0x03f8 /* also 040d */ );
900   /* FIXME do something with this data */
901   CHK (do_scan (s));
902   free (s->buf);
903   s->buf = NULL;
904 
905   /* The trace gets a little iffy from here on out since the log files
906      are missing different urb's.  This is kind of a puzzled-out
907      compilation. */
908 
909   write_byte (fd, MICROSTEP, 0x13 /* pins active */ );
910   write_byte (fd, STEP_PWM, 0x3f);
911   read_byte (fd, STATUS, &result);	/* wants 0c */
912 
913   /* Stepper home */
914   write_byte (fd, COMMAND, 0x02);
915   /* Step size */
916   write_word (fd, STEP_SIZE, 0x041a /* 300 dpi */ );
917   /* Skip steps */
918   write_word (fd, SKIP_STEPS, 0x0000);
919   /* Pause buffer levels */
920   write_byte (fd, BUFFER_LIMIT, 0x57);
921   /* Resume buffer levels */
922   write_byte (fd, BUFFER_RESUME, 0x02);
923 
924   wait_for_return (fd);
925   /* stepper forward small */
926   write_byte (fd, COMMAND, 0x01);
927   read_byte (fd, STATUS, &result);	/* wants 0c */
928   usleep (200000);
929   write_byte (fd, STEP_PWM, 0x1f);
930 
931   /* Read in cal strip at bottom of scanner (to adjust gain/offset
932      tables.  Note that this isn't the brightest lighting condition.)
933      At 300 dpi: black rows 0-25; white rows 30-75; beginning
934      of glass 90.
935      This produces 574k of data, so save it to a temp file. */
936   if (!s->fname)
937     {
938       DBG (1, "No temp filename!\n");
939       s->fname = strdup ("/tmp/cal.XXXXXX");
940       mkstemp (s->fname);
941     }
942   s->width = 2551;
943   s->height = 75;
944   s->flags = FLG_PPM_HEADER | FLG_NO_INTERLEAVE;
945   CHK (do_scan (s));
946   compute_ogn (s->fname);
947   unlink (s->fname);
948 
949   write_byte (fd, STEP_PWM, 0x3f);
950   /* stepper home */
951   write_byte (fd, COMMAND, 0x02);
952 
953   /* discard the remaining data */
954   read_byte (fd, IMAGE_DATA_AVAIL, &result);	/* wants 42,4c */
955   if (result > 1)
956     {
957       read_bulk_size (fd, result, 0, 0, 0);
958       DBG (11, "read %dk extra\n", result);
959     }
960   read_byte (fd, 0x69, &result);	/* wants 02 */
961   write_byte (fd, 0x69, 0x0a);
962 
963   lights_out (fd);
964   init (fd);
965 
966 #if 0
967   /* Repeatedly send this every 1 second.  Button scan?  FIXME */
968   gl640ReadReq (fd, GL640_GPIO_READ, &result);	/* wants 00 */
969 #endif
970 
971   return 0;
972 }
973 
974 
975 /* The number of regions in the calibration strip (black & white). */
976 #define NREGIONS 2
977 
978 /* Compute the offset/gain table from the calibration strip.  This is
979    somewhat more complicated than necessary because I don't hard-code the
980    strip widths; I try to figure out the regions based on the scan data.
981    Theoretically, the region-finder should work for any number of distinct
982    regions (but there are only 2 on this scanner.)
983    This produces the CAL_FILE_OGN file, the final offset/gain table. */
984 static SANE_Status
compute_ogn(char * calfilename)985 compute_ogn (char *calfilename)
986 {
987   byte *linebuf, *oldline, *newline;
988   mode_t oldmask;
989   FILE *fp;
990   int width, height, nlines = 0, region = -1, i, transition = 1, badcnt;
991   int pct;
992   int reglines[NREGIONS];
993   float *avg;
994   float max_range[3], tmp1, tmp2;
995 
996   fp = fopen (calfilename, "r");
997   if (!fp)
998     {
999       DBG (1, "open %s\n", calfilename);
1000       return SANE_STATUS_EOF;
1001     }
1002   fscanf (fp, "P6 %d %d %*d ", &width, &height);
1003   DBG (12, "cal file %s %dx%d\n", calfilename, width, height);
1004   width = width * 3;		/* 1 byte each of r, g, b */
1005   /* make a buffer holding 2 lines of data */
1006   linebuf = calloc (width * 2, sizeof (linebuf[0]));
1007   /* first line is data read buffer */
1008   newline = linebuf;
1009   /* second line is a temporary holding spot in case the next line read
1010      is the black/white transition, in which case we'll disregard this
1011      one. */
1012   oldline = linebuf + width;
1013   /* column averages per region */
1014   avg = calloc (width * NREGIONS, sizeof (avg[0]));
1015 
1016   while (nlines < height)
1017     {
1018       if (fread (newline, 1, width, fp) != (size_t) width)
1019 	break;
1020       nlines++;
1021       /* Check if new line is majorly different than old.
1022          Criteria is 10 pixels differing by more than 10%. */
1023       badcnt = 0;
1024       for (i = 0; i < width; i++)
1025 	{
1026 	  pct = newline[i] - oldline[i];
1027 	  /* Fix by M.Reinelt <reinelt@eunet.at>
1028 	   * do NOT use 10% (think of a dark area with
1029 	   * oldline=4 and newline=5, which is a change of 20% !!
1030 	   * Use an absolute difference of 10 as criteria
1031 	   */
1032 	  if (pct < -10 || pct > 10)
1033 	    {
1034 	      badcnt++;
1035 	      DBG (16, "pix%d[%d/%d] ", i, newline[i], oldline[i]);
1036 	    }
1037 	}
1038       DBG (13, "line %d changed %d\n", nlines, badcnt);
1039       if ((badcnt > 10) || (nlines == height))
1040 	{
1041 	  /* End of region.  Lines are different or end of data. */
1042 	  transition++;
1043 	  if (transition == 1)
1044 	    DBG (12, "Region %d lines %d-%d\n",
1045 		 region, nlines - reglines[region], nlines - 1);
1046 	}
1047       else
1048 	{
1049 	  /* Lines are similar, so still in region.  */
1050 	  if (transition)
1051 	    {
1052 	      /* There was just a transition, so this is the start of a
1053 	         new region. */
1054 	      region++;
1055 	      if (region >= NREGIONS)
1056 		/* Too many regions detected.  Err below. */
1057 		break;
1058 	      transition = 0;
1059 	      reglines[region] = 0;
1060 	    }
1061 	  /* Add oldline to the current region's average */
1062 	  for (i = 0; i < width; i++)
1063 	    avg[i + region * width] += oldline[i];
1064 	  reglines[region]++;
1065 	}
1066       /* And newline becomes old */
1067       memcpy (oldline, newline, width);
1068     }
1069   fclose (fp);
1070   free (linebuf);
1071   region++;			/* now call it number of regions instead of index */
1072   DBG (11, "read %d lines as %d regions\n", nlines, region);
1073 
1074   /* Check to see if we screwed up */
1075   if (region != NREGIONS)
1076     {
1077       DBG (1, "Warning: gain/offset compute failed.\n"
1078 	   "Found %d regions instead of %d.\n", region, NREGIONS);
1079       for (i = 0; i < region; i++)
1080 	DBG (1, "   Region %d: %d lines\n",
1081 	     i, (i >= NREGIONS) ? -1 : reglines[i]);
1082       free (avg);
1083       return SANE_STATUS_UNSUPPORTED;
1084     }
1085 
1086   /* Now we've got regions and sums.  Find averages and range. */
1087   max_range[0] = max_range[1] = max_range[2] = 0.0;
1088   for (i = 0; i < width; i++)
1089     {
1090       /* Convert sums to averages */
1091       /* black region */
1092       tmp1 = avg[i] /= reglines[0];
1093       /* white region */
1094       tmp2 = avg[i + width] /= reglines[1];
1095       /* Track largest range for each color.
1096          If image is interleaved, use 'i%3', if not, 'i/(width/3)' */
1097       if ((tmp2 - tmp1) > max_range[i / (width / 3)])
1098 	{
1099 	  max_range[i / (width / 3)] = tmp2 - tmp1;
1100 	  DBG (14, "max %d@%d %f-%f=%f\n",
1101 	       i / (width / 3), i, tmp2, tmp1, tmp2 - tmp1);
1102 	}
1103     }
1104   DBG (13, "max range r %f\n", max_range[0]);
1105   DBG (13, "max range g %f\n", max_range[1]);
1106   DBG (13, "max range b %f\n", max_range[2]);
1107 
1108   /* Set umask to world r/w so other users can overwrite common cal... */
1109   oldmask = umask (0);
1110   fp = fopen (CAL_FILE_OGN, "w");
1111   /* ... and set it back. */
1112   umask (oldmask);
1113   if (!fp)
1114     {
1115       DBG (1, "open " CAL_FILE_OGN);
1116       free (avg);
1117       return SANE_STATUS_IO_ERROR;
1118     }
1119 
1120   /* Finally, compute offset and gain */
1121   for (i = 0; i < width; i++)
1122     {
1123       int gain, offset;
1124       byte ogn[2];
1125 
1126       /* skip line termination flags */
1127       if (!((i + 1) % (width / 3)))
1128 	{
1129 	  DBG (13, "skip scanline EOL %d/%d\n", i, width);
1130 	  continue;
1131 	}
1132 
1133       /* Gain multiplier:
1134          255 : 1.5 times brighter
1135          511 : 2 times brighter
1136          1023: 3 times brighter */
1137 #if 1
1138       /* Original gain/offset */
1139       gain = 512 * ((max_range[i / (width / 3)] /
1140 		     (avg[i + width] - avg[i])) - 1);
1141       offset = avg[i];
1142 #else
1143       /* This doesn't work for some people.  For instance, a negative
1144          offset would be bad.  */
1145 
1146       /* Enhanced offset and gain calculation by M.Reinelt <reinelt@eunet.at>
1147        * These expressions were found by an iterative calibration process,
1148        * by changing gain and offset values for every pixel until the desired
1149        * values for black and white were reached, and finding an approximation
1150        * formula.
1151        * Note that offset is linear, but gain isn't!
1152        */
1153       offset = (double)3.53 * avg[i] - 125;
1154       gain = (double)3861.0 * exp(-0.0168 * (avg[i + width] - avg[i]));
1155 #endif
1156 
1157       DBG (14, "%d wht=%f blk=%f diff=%f gain=%d offset=%d\n", i,
1158 	   avg[i + width], avg[i], avg[i + width] - avg[i], gain, offset);
1159       /* 10-bit gain, 6-bit offset (subtractor) in two bytes */
1160       ogn[0] = (byte) (((offset << 2) + (gain >> 8)) & 0xFF);
1161       ogn[1] = (byte) (gain & 0xFF);
1162       fwrite (ogn, sizeof (byte), 2, fp);
1163       /* Annoyingly, we seem to use ogn data at 600dpi, while we scanned
1164          at 300, so double our file.  Much easier than doubling at the
1165          read. */
1166       fwrite (ogn, sizeof (byte), 2, fp);
1167     }
1168 
1169   fclose (fp);
1170   free (avg);
1171   return SANE_STATUS_GOOD;
1172 }
1173 
1174 static int
check_ogn_file(void)1175 check_ogn_file (void)
1176 {
1177   FILE *fp;
1178   fp = fopen (CAL_FILE_OGN, "r");
1179   if (fp)
1180     {
1181       fclose (fp);
1182       return 1;
1183     }
1184   return 0;
1185 }
1186 
1187 /* Load or fake the offset/gain table */
1188 static void
install_ogn(int fd)1189 install_ogn (int fd)
1190 {
1191   int temp;
1192   byte *buf;
1193   FILE *fp;
1194 
1195   /* 8.5in at 600dpi = 5104 pixels in scan head
1196      10-bit gain + 6-bit offset = 2 bytes per pixel, so 10208 bytes */
1197   buf = malloc (10208);
1198 
1199   fp = fopen (CAL_FILE_OGN, "r");
1200   if (fp)
1201     {
1202       fread (buf, 2, 5100, fp);
1203       /* screw the last 4 pixels */
1204     }
1205   else
1206     {
1207       /* Make up the gain/offset data. */
1208 #define GAIN 256		/* 1.5x */
1209 #define OFFSET 0
1210       for (temp = 0; temp < 10208; temp += 2)
1211 	{
1212 	  buf[temp] = (byte) ((OFFSET << 2) + (GAIN >> 8));
1213 	  buf[temp + 1] = (byte) (GAIN & 0xFF);
1214 	}
1215     }
1216   /* Gain/offset table (r,g,b) */
1217   write_byte (fd, DATAPORT_TARGET, DP_R | DP_OFFSET);
1218   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1219   write_bulk (fd, DATAPORT, buf, 10208);
1220   if (fp)
1221     fread (buf, 2, 5100, fp);
1222   write_byte (fd, DATAPORT_TARGET, DP_G | DP_OFFSET);
1223   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1224   write_bulk (fd, DATAPORT, buf, 10208);
1225   if (fp)
1226     {
1227       fread (buf, 2, 5100, fp);
1228       fclose (fp);
1229     }
1230   write_byte (fd, DATAPORT_TARGET, DP_B | DP_OFFSET);
1231   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1232   write_bulk (fd, DATAPORT, buf, 10208);
1233 
1234   free (buf);
1235   return;
1236 }
1237 
1238 
1239 /* Scan sequence */
1240 /* resolution is 75,150,300,600,1200
1241    scan coordinates in 600-dpi pixels */
1242 static SANE_Status
scan(CANON_Handle * opt)1243 scan (CANON_Handle * opt)
1244 {
1245   SANE_Status status;
1246   const int left_edge = 0x004b;	/* Just for my scanner, or is this
1247 				   universal?  Calibrate? */
1248   int temp;
1249   int fd = opt->fd;
1250   byte result;
1251   byte *buf;
1252 
1253   /* Check status. (not in w2k driver) */
1254   read_byte (fd, STATUS, &result);	/* wants 2f or 2d */
1255   if (!(result & STATUS_HOME) /*0x2d */ )
1256     return SANE_STATUS_DEVICE_BUSY;
1257   /* or force it to return?
1258      write_byte(fd, COMMAND, 0x02);
1259      wait_for_return(fd);
1260    */
1261 
1262   /* reserved? */
1263   read_byte (fd, 0x69, &result);	/* wants 0a */
1264 
1265   read_byte (fd, STATUS, &result);	/* wants 0e */
1266   read_byte (fd, PAPER_SENSOR, &result);	/* wants 2b */
1267   write_byte (fd, PAPER_SENSOR, 0x2b);
1268   /* Color mode:
1269      1-Channel Line Rate Color 0x15.
1270      1-Channel Grayscale 0x14 (and we skip some of these tables) */
1271   write_byte (fd, COLOR_MODE, 0x15);
1272 
1273   /* install the offset/gain table */
1274   install_ogn (fd);
1275 
1276   read_byte (fd, STATUS, &result);	/* wants 0e */
1277   /* move forward to "glass 0" */
1278   write_byte (fd, COMMAND, 0x01);
1279   read_byte (fd, STATUS, &result);	/* wants 0c */
1280 
1281   /* create gamma table */
1282   buf = malloc (0x400);
1283   for (temp = 0; temp < 0x0400; temp++)
1284     /* gamma calculation by M.Reinelt <reinelt@eunet.at> */
1285     buf[temp] = (double) 255.0 * exp(log((temp + 0.5) / 1023.0) / opt->gamma)
1286 	+ 0.5;
1287 
1288   /* Gamma R, write and verify */
1289   write_byte (fd, DATAPORT_TARGET, DP_R | DP_GAMMA);
1290   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1291   write_bulk (fd, DATAPORT, buf, 0x0400);
1292   write_byte (fd, DATAPORT_TARGET, DP_R | DP_GAMMA);
1293   write_word (fd, DATAPORT_ADDR, DP_READ);
1294   read_bulk (fd, DATAPORT, buf, 0x0400);
1295   /* Gamma G */
1296   write_byte (fd, DATAPORT_TARGET, DP_G | DP_GAMMA);
1297   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1298   write_bulk (fd, DATAPORT, buf, 0x0400);
1299   write_byte (fd, DATAPORT_TARGET, DP_G | DP_GAMMA);
1300   write_word (fd, DATAPORT_ADDR, DP_READ);
1301   read_bulk (fd, DATAPORT, buf, 0x0400);
1302   /* Gamma B */
1303   write_byte (fd, DATAPORT_TARGET, DP_B | DP_GAMMA);
1304   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1305   write_bulk (fd, DATAPORT, buf, 0x0400);
1306   write_byte (fd, DATAPORT_TARGET, DP_B | DP_GAMMA);
1307   write_word (fd, DATAPORT_ADDR, DP_READ);
1308   read_bulk (fd, DATAPORT, buf, 0x0400);
1309   free (buf);
1310 
1311   write_byte (fd, CLOCK_DIV, 0x04);
1312   /* Resolution: dpi 75(ie) 100,150(1c) 200,300(1a) 600,1200(18) */
1313   switch (opt->resolution)
1314     {
1315     case 150:
1316       write_byte (fd, 0x09, 0x1c);
1317       break;
1318     case 300:
1319       write_byte (fd, 0x09, 0x1a);
1320       break;
1321     case 600:
1322     case 1200:
1323       /* actually 600 dpi horiz max */
1324       write_byte (fd, 0x09, 0x18);
1325       break;
1326     default:			/* 75 */
1327       write_byte (fd, 0x09, 0x1e);
1328       opt->resolution = 75;
1329     }
1330 
1331   write_word (fd, ACTIVE_PX_START, left_edge);
1332   /* Data pixel start.  Measured at 600dpi regardless of
1333      scan resolution.  0-position is 0x004b */
1334   write_word (fd, DATA_PX_START, left_edge + opt->x1);
1335   /* Data pixel end.  Measured at 600dpi regardless of scan
1336      resolution. */
1337   write_word (fd, DATA_PX_END, left_edge + opt->x2);
1338   /* greyscale has 14,03, different lights */
1339   write_byte (fd, COLOR_MODE, 0x15);
1340   write_byte (fd, 0x29, 0x02);
1341   /* Lights */
1342   write_word (fd, LAMP_R_ON, 0x0017);
1343   /* "Hi-low color" selection from windows driver.  low(1437) hi(1481) */
1344   write_word (fd, LAMP_R_OFF, 0x1437);
1345   write_word (fd, LAMP_G_ON, 0x0017);
1346   write_word (fd, LAMP_G_OFF, 0x094e);
1347   write_word (fd, LAMP_B_ON, 0x0017);
1348   write_word (fd, LAMP_B_OFF, 0x0543);
1349 
1350   /* Analog static offset R,G,B.  Greyscale has 0,0,0 */
1351   write_byte (fd, 0x38, 0x3f);
1352   write_byte (fd, 0x39, 0x3f);
1353   write_byte (fd, 0x3a, 0x3f);
1354   /* Analog static gain R,G,B (normally 0x01) */
1355   write_byte (fd, 0x3b, opt->gain);
1356   write_byte (fd, 0x3c, opt->gain);
1357   write_byte (fd, 0x3d, opt->gain);
1358   /* Digital gain/offset settings.  Greyscale has 0 */
1359   write_byte (fd, 0x3e, 0x1a);
1360 
1361   {
1362     /* Stepper motion setup. */
1363     int stepsize, faststep = 0x0104, reverse = 0x28, phase, pwm = 0x1f;
1364     switch (opt->resolution)
1365       {
1366       case 75:
1367 	stepsize = 0x0106;
1368 	faststep = 0x0106;
1369 	reverse = 0;
1370 	phase = 0x39a8;
1371 	pwm = 0x3f;
1372 	break;
1373       case 150:
1374 	stepsize = 0x020d;
1375 	phase = 0x3198;
1376 	break;
1377       case 300:
1378 	stepsize = 0x041a;
1379 	phase = 0x2184;
1380 	break;
1381       case 600:
1382 	stepsize = 0x0835;
1383 	phase = 0x0074;
1384 	break;
1385       case 1200:
1386 	/* 1200 dpi y only, x is 600 dpi */
1387 	stepsize = 0x106b;
1388 	phase = 0x41ac;
1389 	break;
1390       default:
1391 	DBG (1, "BAD RESOLUTION");
1392 	return SANE_STATUS_UNSUPPORTED;
1393       }
1394 
1395     write_word (fd, STEP_SIZE, stepsize);
1396     write_word (fd, FAST_STEP, faststep);
1397     /* There sounds like a weird step disjoint at the end of skipsteps
1398        at 75dpi, so I think that's why skipsteps=0 at 75dpi in the
1399        Windows driver.  It still works at the normal 0x017a though. */
1400     /* cal strip is 0x17a steps, plus 2 300dpi microsteps per pixel */
1401     write_word (fd, SKIP_STEPS, 0x017a /* cal strip */  + opt->y1 * 2);
1402     /* FIXME could be 0x57, why not? */
1403     write_byte (fd, BUFFER_LIMIT, 0x20);
1404     write_byte (fd, BUFFER_RESUME, 0x02);
1405     write_byte (fd, REVERSE_STEPS, reverse);
1406     /* motor resume phasing */
1407     write_word (fd, 0x52, phase);
1408     write_byte (fd, STEP_PWM, pwm);
1409   }
1410 
1411   read_byte (fd, PAPER_SENSOR, &result);	/* wants 2b */
1412   write_byte (fd, PAPER_SENSOR, 0x0b);
1413 
1414   opt->width = (opt->x2 - opt->x1) * opt->resolution / 600 + 1;
1415   opt->height = (opt->y2 - opt->y1) * opt->resolution / 600;
1416   opt->flags = 0;
1417   DBG (1, "width=%d height=%d dpi=%d\n", opt->width, opt->height,
1418        opt->resolution);
1419   CHK (do_scan (opt));
1420 
1421   read_byte (fd, PAPER_SENSOR, &result);	/* wants 0b */
1422   write_byte (fd, PAPER_SENSOR, 0x2b);
1423   write_byte (fd, STEP_PWM, 0x3f);
1424 
1425   lights_out (fd);
1426   /* home */
1427   write_byte (fd, COMMAND, 0x02);
1428 
1429   return status;
1430 }
1431 
1432 
1433 static SANE_Status
CANON_set_scan_parameters(CANON_Handle * scan,const int forceCal,const int gray,const int left,const int top,const int right,const int bottom,const int res,const int gain,const double gamma)1434 CANON_set_scan_parameters (CANON_Handle * scan,
1435 			   const int forceCal,
1436 			   const int gray,
1437 			   const int left,
1438 			   const int top,
1439 			   const int right,
1440 			   const int bottom,
1441 			   const int res,
1442 			   const int gain,
1443 			   const double gamma)
1444 {
1445   DBG (2, "CANON_set_scan_parameters:\n");
1446   DBG (2, "cal   = %d\n", forceCal);
1447   DBG (2, "gray  = %d (ignored)\n", gray);
1448   DBG (2, "res   = %d\n", res);
1449   DBG (2, "gain  = %d\n", gain);
1450   DBG (2, "gamma = %f\n", gamma);
1451   DBG (2, "in 600dpi pixels:\n");
1452   DBG (2, "left  = %d, top    = %d\n", left, top);
1453   DBG (2, "right = %d, bottom = %d\n", right, bottom);
1454 
1455   /* Validate the input parameters */
1456   if ((left < 0) || (right > CANON_MAX_WIDTH))
1457     return SANE_STATUS_INVAL;
1458 
1459   if ((top < 0) || (bottom > CANON_MAX_HEIGHT))
1460     return SANE_STATUS_INVAL;
1461 
1462   if (((right - left) < 10) || ((bottom - top) < 10))
1463     return SANE_STATUS_INVAL;
1464 
1465   if ((res != 75) && (res != 150) && (res != 300)
1466       && (res != 600) && (res != 1200))
1467     return SANE_STATUS_INVAL;
1468 
1469   if ((gain < 0) || (gain > 64))
1470     return SANE_STATUS_INVAL;
1471 
1472   if (gamma <= 0.0)
1473     return SANE_STATUS_INVAL;
1474 
1475   /* Store params */
1476   scan->resolution = res;
1477   scan->x1 = left;
1478   scan->x2 = right - /* subtract 1 pixel */ 600 / scan->resolution;
1479   scan->y1 = top;
1480   scan->y2 = bottom;
1481   scan->gain = gain;
1482   scan->gamma = gamma;
1483   scan->flags = forceCal ? FLG_FORCE_CAL : 0;
1484 
1485   return SANE_STATUS_GOOD;
1486 }
1487 
1488 
1489 static SANE_Status
CANON_close_device(CANON_Handle * scan)1490 CANON_close_device (CANON_Handle * scan)
1491 {
1492   DBG (3, "CANON_close_device:\n");
1493   sanei_usb_close (scan->fd);
1494   return SANE_STATUS_GOOD;
1495 }
1496 
1497 
1498 static SANE_Status
CANON_open_device(CANON_Handle * scan,const char * dev)1499 CANON_open_device (CANON_Handle * scan, const char *dev)
1500 {
1501   SANE_Word vendor;
1502   SANE_Word product;
1503   SANE_Status res;
1504 
1505   DBG (3, "CANON_open_device: `%s'\n", dev);
1506 
1507   scan->fname = NULL;
1508   scan->fp = NULL;
1509   scan->flags = 0;
1510 
1511   res = sanei_usb_open (dev, &scan->fd);
1512   if (res != SANE_STATUS_GOOD)
1513     {
1514       DBG (1, "CANON_open_device: couldn't open device `%s': %s\n", dev,
1515 	   sane_strstatus (res));
1516       return res;
1517     }
1518 
1519 #ifndef NO_AUTODETECT
1520   /* We have opened the device. Check that it is a USB scanner. */
1521   if (sanei_usb_get_vendor_product (scan->fd, &vendor, &product) !=
1522       SANE_STATUS_GOOD)
1523     {
1524       DBG (1, "CANON_open_device: sanei_usb_get_vendor_product failed\n");
1525       /* This is not a USB scanner, or SANE or the OS doesn't support it. */
1526       sanei_usb_close (scan->fd);
1527       scan->fd = -1;
1528       return SANE_STATUS_UNSUPPORTED;
1529     }
1530 
1531   /* Make sure we have a CANON scanner */
1532   if ((vendor != 0x04a9) || (product != 0x2204))
1533     {
1534       DBG (1, "CANON_open_device: incorrect vendor/product (0x%x/0x%x)\n",
1535 	   vendor, product);
1536       sanei_usb_close (scan->fd);
1537       scan->fd = -1;
1538       return SANE_STATUS_UNSUPPORTED;
1539     }
1540 #endif
1541 
1542   return SANE_STATUS_GOOD;
1543 }
1544 
1545 
1546 static const char *
CANON_get_device_name(CANON_Handle * scanner)1547 CANON_get_device_name (CANON_Handle * scanner)
1548 {
1549   scanner = scanner;		/* Eliminate warning about unused parameters */
1550   return "Canoscan FB630U";
1551 }
1552 
1553 
1554 static SANE_Status
CANON_finish_scan(CANON_Handle * scanner)1555 CANON_finish_scan (CANON_Handle * scanner)
1556 {
1557   DBG (3, "CANON_finish_scan:\n");
1558   if (scanner->fp)
1559     fclose (scanner->fp);
1560   scanner->fp = NULL;
1561 
1562   /* remove temp file */
1563   if (scanner->fname)
1564     {
1565       DBG (4, "removing temp file %s\n", scanner->fname);
1566       unlink (scanner->fname);
1567       free (scanner->fname);
1568     }
1569   scanner->fname = NULL;
1570 
1571   return SANE_STATUS_GOOD;
1572 }
1573 
1574 
1575 static SANE_Status
CANON_start_scan(CANON_Handle * scanner)1576 CANON_start_scan (CANON_Handle * scanner)
1577 {
1578   int rv;
1579   SANE_Status status;
1580   DBG (3, "CANON_start_scan called\n");
1581 
1582   /* choose a temp file name for scan data */
1583   scanner->fname = strdup ("/tmp/scan.XXXXXX");
1584   if (!mkstemp (scanner->fname))
1585     return SANE_STATUS_IO_ERROR;
1586 
1587   /* calibrate if needed */
1588   rv = init (scanner->fd);
1589   if (rv < 0) {
1590       DBG(1, "Can't talk on USB.\n");
1591       return SANE_STATUS_IO_ERROR;
1592   }
1593   if ((rv == 1)
1594       || !check_ogn_file ()
1595       || (scanner->flags & FLG_FORCE_CAL)) {
1596       plugin_cal (scanner);
1597       wait_for_return (scanner->fd);
1598   }
1599 
1600   /* scan */
1601   if ((status = scan (scanner)) != SANE_STATUS_GOOD)
1602     {
1603       CANON_finish_scan (scanner);
1604       return status;
1605     }
1606 
1607   /* read the temp file back out */
1608   scanner->fp = fopen (scanner->fname, "r");
1609   DBG (4, "reading %s\n", scanner->fname);
1610   if (!scanner->fp)
1611     {
1612       DBG (1, "open %s", scanner->fname);
1613       return SANE_STATUS_IO_ERROR;
1614     }
1615   return SANE_STATUS_GOOD;
1616 }
1617 
1618 
1619 static SANE_Status
CANON_read(CANON_Handle * scanner,SANE_Byte * data,SANE_Int max_length,SANE_Int * length)1620 CANON_read (CANON_Handle * scanner, SANE_Byte * data,
1621 	    SANE_Int max_length, SANE_Int * length)
1622 {
1623   SANE_Status status;
1624   int red_len;
1625 
1626   DBG (5, "CANON_read called\n");
1627   if (!scanner->fp)
1628     return SANE_STATUS_INVAL;
1629   red_len = fread (data, 1, max_length, scanner->fp);
1630   /* return some data */
1631   if (red_len > 0)
1632     {
1633       *length = red_len;
1634       DBG (5, "CANON_read returned (%d/%d)\n", *length, max_length);
1635       return SANE_STATUS_GOOD;
1636     }
1637 
1638   /* EOF or file err */
1639   *length = 0;
1640   if (feof (scanner->fp))
1641     {
1642       DBG (4, "EOF\n");
1643       status = SANE_STATUS_EOF;
1644     }
1645   else
1646     {
1647       DBG (4, "IO ERR\n");
1648       status = SANE_STATUS_IO_ERROR;
1649     }
1650 
1651   CANON_finish_scan (scanner);
1652   DBG (5, "CANON_read returned (%d/%d)\n", *length, max_length);
1653   return status;
1654 }
1655