• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
941       /* FIXME: we should be using fd, not discarding it, and also checking for error! */
942       int fd = mkstemp (s->fname);
943       close(fd);
944     }
945   s->width = 2551;
946   s->height = 75;
947   s->flags = FLG_PPM_HEADER | FLG_NO_INTERLEAVE;
948   CHK (do_scan (s));
949   compute_ogn (s->fname);
950   unlink (s->fname);
951 
952   write_byte (fd, STEP_PWM, 0x3f);
953   /* stepper home */
954   write_byte (fd, COMMAND, 0x02);
955 
956   /* discard the remaining data */
957   read_byte (fd, IMAGE_DATA_AVAIL, &result);	/* wants 42,4c */
958   if (result > 1)
959     {
960       read_bulk_size (fd, result, 0, 0, 0);
961       DBG (11, "read %dk extra\n", result);
962     }
963   read_byte (fd, 0x69, &result);	/* wants 02 */
964   write_byte (fd, 0x69, 0x0a);
965 
966   lights_out (fd);
967   init (fd);
968 
969 #if 0
970   /* Repeatedly send this every 1 second.  Button scan?  FIXME */
971   gl640ReadReq (fd, GL640_GPIO_READ, &result);	/* wants 00 */
972 #endif
973 
974   return 0;
975 }
976 
977 
978 /* The number of regions in the calibration strip (black & white). */
979 #define NREGIONS 2
980 
981 /* Compute the offset/gain table from the calibration strip.  This is
982    somewhat more complicated than necessary because I don't hard-code the
983    strip widths; I try to figure out the regions based on the scan data.
984    Theoretically, the region-finder should work for any number of distinct
985    regions (but there are only 2 on this scanner.)
986    This produces the CAL_FILE_OGN file, the final offset/gain table. */
987 static SANE_Status
compute_ogn(char * calfilename)988 compute_ogn (char *calfilename)
989 {
990   byte *linebuf, *oldline, *newline;
991   mode_t oldmask;
992   FILE *fp;
993   int width, height, nlines = 0, region = -1, i, transition = 1, badcnt;
994   int pct;
995   int reglines[NREGIONS];
996   float *avg;
997   float max_range[3], tmp1, tmp2;
998 
999   fp = fopen (calfilename, "r");
1000   if (!fp)
1001     {
1002       DBG (1, "open %s\n", calfilename);
1003       return SANE_STATUS_EOF;
1004     }
1005   fscanf (fp, "P6 %d %d %*d ", &width, &height);
1006   DBG (12, "cal file %s %dx%d\n", calfilename, width, height);
1007   width = width * 3;		/* 1 byte each of r, g, b */
1008   /* make a buffer holding 2 lines of data */
1009   linebuf = calloc (width * 2, sizeof (linebuf[0]));
1010   /* first line is data read buffer */
1011   newline = linebuf;
1012   /* second line is a temporary holding spot in case the next line read
1013      is the black/white transition, in which case we'll disregard this
1014      one. */
1015   oldline = linebuf + width;
1016   /* column averages per region */
1017   avg = calloc (width * NREGIONS, sizeof (avg[0]));
1018 
1019   while (nlines < height)
1020     {
1021       if (fread (newline, 1, width, fp) != (size_t) width)
1022 	break;
1023       nlines++;
1024       /* Check if new line is majorly different than old.
1025          Criteria is 10 pixels differing by more than 10%. */
1026       badcnt = 0;
1027       for (i = 0; i < width; i++)
1028 	{
1029 	  pct = newline[i] - oldline[i];
1030 	  /* Fix by M.Reinelt <reinelt@eunet.at>
1031 	   * do NOT use 10% (think of a dark area with
1032 	   * oldline=4 and newline=5, which is a change of 20% !!
1033 	   * Use an absolute difference of 10 as criteria
1034 	   */
1035 	  if (pct < -10 || pct > 10)
1036 	    {
1037 	      badcnt++;
1038 	      DBG (16, "pix%d[%d/%d] ", i, newline[i], oldline[i]);
1039 	    }
1040 	}
1041       DBG (13, "line %d changed %d\n", nlines, badcnt);
1042       if ((badcnt > 10) || (nlines == height))
1043 	{
1044 	  /* End of region.  Lines are different or end of data. */
1045 	  transition++;
1046 	  if (transition == 1)
1047 	    DBG (12, "Region %d lines %d-%d\n",
1048 		 region, nlines - reglines[region], nlines - 1);
1049 	}
1050       else
1051 	{
1052 	  /* Lines are similar, so still in region.  */
1053 	  if (transition)
1054 	    {
1055 	      /* There was just a transition, so this is the start of a
1056 	         new region. */
1057 	      region++;
1058 	      if (region >= NREGIONS)
1059 		/* Too many regions detected.  Err below. */
1060 		break;
1061 	      transition = 0;
1062 	      reglines[region] = 0;
1063 	    }
1064 	  /* Add oldline to the current region's average */
1065 	  for (i = 0; i < width; i++)
1066 	    avg[i + region * width] += oldline[i];
1067 	  reglines[region]++;
1068 	}
1069       /* And newline becomes old */
1070       memcpy (oldline, newline, width);
1071     }
1072   fclose (fp);
1073   free (linebuf);
1074   region++;			/* now call it number of regions instead of index */
1075   DBG (11, "read %d lines as %d regions\n", nlines, region);
1076 
1077   /* Check to see if we screwed up */
1078   if (region != NREGIONS)
1079     {
1080       DBG (1, "Warning: gain/offset compute failed.\n"
1081 	   "Found %d regions instead of %d.\n", region, NREGIONS);
1082       for (i = 0; i < region; i++)
1083 	DBG (1, "   Region %d: %d lines\n",
1084 	     i, (i >= NREGIONS) ? -1 : reglines[i]);
1085       free (avg);
1086       return SANE_STATUS_UNSUPPORTED;
1087     }
1088 
1089   /* Now we've got regions and sums.  Find averages and range. */
1090   max_range[0] = max_range[1] = max_range[2] = 0.0;
1091   for (i = 0; i < width; i++)
1092     {
1093       /* Convert sums to averages */
1094       /* black region */
1095       tmp1 = avg[i] /= reglines[0];
1096       /* white region */
1097       tmp2 = avg[i + width] /= reglines[1];
1098       /* Track largest range for each color.
1099          If image is interleaved, use 'i%3', if not, 'i/(width/3)' */
1100       if ((tmp2 - tmp1) > max_range[i / (width / 3)])
1101 	{
1102 	  max_range[i / (width / 3)] = tmp2 - tmp1;
1103 	  DBG (14, "max %d@%d %f-%f=%f\n",
1104 	       i / (width / 3), i, tmp2, tmp1, tmp2 - tmp1);
1105 	}
1106     }
1107   DBG (13, "max range r %f\n", max_range[0]);
1108   DBG (13, "max range g %f\n", max_range[1]);
1109   DBG (13, "max range b %f\n", max_range[2]);
1110 
1111   /* Set umask to world r/w so other users can overwrite common cal... */
1112   oldmask = umask (0);
1113   fp = fopen (CAL_FILE_OGN, "w");
1114   /* ... and set it back. */
1115   umask (oldmask);
1116   if (!fp)
1117     {
1118       DBG (1, "open " CAL_FILE_OGN);
1119       free (avg);
1120       return SANE_STATUS_IO_ERROR;
1121     }
1122 
1123   /* Finally, compute offset and gain */
1124   for (i = 0; i < width; i++)
1125     {
1126       int gain, offset;
1127       byte ogn[2];
1128 
1129       /* skip line termination flags */
1130       if (!((i + 1) % (width / 3)))
1131 	{
1132 	  DBG (13, "skip scanline EOL %d/%d\n", i, width);
1133 	  continue;
1134 	}
1135 
1136       /* Gain multiplier:
1137          255 : 1.5 times brighter
1138          511 : 2 times brighter
1139          1023: 3 times brighter */
1140 #if 1
1141       /* Original gain/offset */
1142       gain = 512 * ((max_range[i / (width / 3)] /
1143 		     (avg[i + width] - avg[i])) - 1);
1144       offset = avg[i];
1145 #else
1146       /* This doesn't work for some people.  For instance, a negative
1147          offset would be bad.  */
1148 
1149       /* Enhanced offset and gain calculation by M.Reinelt <reinelt@eunet.at>
1150        * These expressions were found by an iterative calibration process,
1151        * by changing gain and offset values for every pixel until the desired
1152        * values for black and white were reached, and finding an approximation
1153        * formula.
1154        * Note that offset is linear, but gain isn't!
1155        */
1156       offset = (double)3.53 * avg[i] - 125;
1157       gain = (double)3861.0 * exp(-0.0168 * (avg[i + width] - avg[i]));
1158 #endif
1159 
1160       DBG (14, "%d wht=%f blk=%f diff=%f gain=%d offset=%d\n", i,
1161 	   avg[i + width], avg[i], avg[i + width] - avg[i], gain, offset);
1162       /* 10-bit gain, 6-bit offset (subtractor) in two bytes */
1163       ogn[0] = (byte) (((offset << 2) + (gain >> 8)) & 0xFF);
1164       ogn[1] = (byte) (gain & 0xFF);
1165       fwrite (ogn, sizeof (byte), 2, fp);
1166       /* Annoyingly, we seem to use ogn data at 600dpi, while we scanned
1167          at 300, so double our file.  Much easier than doubling at the
1168          read. */
1169       fwrite (ogn, sizeof (byte), 2, fp);
1170     }
1171 
1172   fclose (fp);
1173   free (avg);
1174   return SANE_STATUS_GOOD;
1175 }
1176 
1177 static int
check_ogn_file(void)1178 check_ogn_file (void)
1179 {
1180   FILE *fp;
1181   fp = fopen (CAL_FILE_OGN, "r");
1182   if (fp)
1183     {
1184       fclose (fp);
1185       return 1;
1186     }
1187   return 0;
1188 }
1189 
1190 /* Load or fake the offset/gain table */
1191 static void
install_ogn(int fd)1192 install_ogn (int fd)
1193 {
1194   int temp;
1195   byte *buf;
1196   FILE *fp;
1197 
1198   /* 8.5in at 600dpi = 5104 pixels in scan head
1199      10-bit gain + 6-bit offset = 2 bytes per pixel, so 10208 bytes */
1200   buf = malloc (10208);
1201 
1202   fp = fopen (CAL_FILE_OGN, "r");
1203   if (fp)
1204     {
1205       fread (buf, 2, 5100, fp);
1206       /* screw the last 4 pixels */
1207     }
1208   else
1209     {
1210       /* Make up the gain/offset data. */
1211 #define GAIN 256		/* 1.5x */
1212 #define OFFSET 0
1213       for (temp = 0; temp < 10208; temp += 2)
1214 	{
1215 	  buf[temp] = (byte) ((OFFSET << 2) + (GAIN >> 8));
1216 	  buf[temp + 1] = (byte) (GAIN & 0xFF);
1217 	}
1218     }
1219   /* Gain/offset table (r,g,b) */
1220   write_byte (fd, DATAPORT_TARGET, DP_R | DP_OFFSET);
1221   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1222   write_bulk (fd, DATAPORT, buf, 10208);
1223   if (fp)
1224     fread (buf, 2, 5100, fp);
1225   write_byte (fd, DATAPORT_TARGET, DP_G | DP_OFFSET);
1226   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1227   write_bulk (fd, DATAPORT, buf, 10208);
1228   if (fp)
1229     {
1230       fread (buf, 2, 5100, fp);
1231       fclose (fp);
1232     }
1233   write_byte (fd, DATAPORT_TARGET, DP_B | DP_OFFSET);
1234   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1235   write_bulk (fd, DATAPORT, buf, 10208);
1236 
1237   free (buf);
1238   return;
1239 }
1240 
1241 
1242 /* Scan sequence */
1243 /* resolution is 75,150,300,600,1200
1244    scan coordinates in 600-dpi pixels */
1245 static SANE_Status
scan(CANON_Handle * opt)1246 scan (CANON_Handle * opt)
1247 {
1248   SANE_Status status;
1249   const int left_edge = 0x004b;	/* Just for my scanner, or is this
1250 				   universal?  Calibrate? */
1251   int temp;
1252   int fd = opt->fd;
1253   byte result;
1254   byte *buf;
1255 
1256   /* Check status. (not in w2k driver) */
1257   read_byte (fd, STATUS, &result);	/* wants 2f or 2d */
1258   if (!(result & STATUS_HOME) /*0x2d */ )
1259     return SANE_STATUS_DEVICE_BUSY;
1260   /* or force it to return?
1261      write_byte(fd, COMMAND, 0x02);
1262      wait_for_return(fd);
1263    */
1264 
1265   /* reserved? */
1266   read_byte (fd, 0x69, &result);	/* wants 0a */
1267 
1268   read_byte (fd, STATUS, &result);	/* wants 0e */
1269   read_byte (fd, PAPER_SENSOR, &result);	/* wants 2b */
1270   write_byte (fd, PAPER_SENSOR, 0x2b);
1271   /* Color mode:
1272      1-Channel Line Rate Color 0x15.
1273      1-Channel Grayscale 0x14 (and we skip some of these tables) */
1274   write_byte (fd, COLOR_MODE, 0x15);
1275 
1276   /* install the offset/gain table */
1277   install_ogn (fd);
1278 
1279   read_byte (fd, STATUS, &result);	/* wants 0e */
1280   /* move forward to "glass 0" */
1281   write_byte (fd, COMMAND, 0x01);
1282   read_byte (fd, STATUS, &result);	/* wants 0c */
1283 
1284   /* create gamma table */
1285   buf = malloc (0x400);
1286   for (temp = 0; temp < 0x0400; temp++)
1287     /* gamma calculation by M.Reinelt <reinelt@eunet.at> */
1288     buf[temp] = (double) 255.0 * exp(log((temp + 0.5) / 1023.0) / opt->gamma)
1289 	+ 0.5;
1290 
1291   /* Gamma R, write and verify */
1292   write_byte (fd, DATAPORT_TARGET, DP_R | DP_GAMMA);
1293   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1294   write_bulk (fd, DATAPORT, buf, 0x0400);
1295   write_byte (fd, DATAPORT_TARGET, DP_R | DP_GAMMA);
1296   write_word (fd, DATAPORT_ADDR, DP_READ);
1297   read_bulk (fd, DATAPORT, buf, 0x0400);
1298   /* Gamma G */
1299   write_byte (fd, DATAPORT_TARGET, DP_G | DP_GAMMA);
1300   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1301   write_bulk (fd, DATAPORT, buf, 0x0400);
1302   write_byte (fd, DATAPORT_TARGET, DP_G | DP_GAMMA);
1303   write_word (fd, DATAPORT_ADDR, DP_READ);
1304   read_bulk (fd, DATAPORT, buf, 0x0400);
1305   /* Gamma B */
1306   write_byte (fd, DATAPORT_TARGET, DP_B | DP_GAMMA);
1307   write_word (fd, DATAPORT_ADDR, DP_WRITE);
1308   write_bulk (fd, DATAPORT, buf, 0x0400);
1309   write_byte (fd, DATAPORT_TARGET, DP_B | DP_GAMMA);
1310   write_word (fd, DATAPORT_ADDR, DP_READ);
1311   read_bulk (fd, DATAPORT, buf, 0x0400);
1312   free (buf);
1313 
1314   write_byte (fd, CLOCK_DIV, 0x04);
1315   /* Resolution: dpi 75(ie) 100,150(1c) 200,300(1a) 600,1200(18) */
1316   switch (opt->resolution)
1317     {
1318     case 150:
1319       write_byte (fd, 0x09, 0x1c);
1320       break;
1321     case 300:
1322       write_byte (fd, 0x09, 0x1a);
1323       break;
1324     case 600:
1325     case 1200:
1326       /* actually 600 dpi horiz max */
1327       write_byte (fd, 0x09, 0x18);
1328       break;
1329     default:			/* 75 */
1330       write_byte (fd, 0x09, 0x1e);
1331       opt->resolution = 75;
1332     }
1333 
1334   write_word (fd, ACTIVE_PX_START, left_edge);
1335   /* Data pixel start.  Measured at 600dpi regardless of
1336      scan resolution.  0-position is 0x004b */
1337   write_word (fd, DATA_PX_START, left_edge + opt->x1);
1338   /* Data pixel end.  Measured at 600dpi regardless of scan
1339      resolution. */
1340   write_word (fd, DATA_PX_END, left_edge + opt->x2);
1341   /* greyscale has 14,03, different lights */
1342   write_byte (fd, COLOR_MODE, 0x15);
1343   write_byte (fd, 0x29, 0x02);
1344   /* Lights */
1345   write_word (fd, LAMP_R_ON, 0x0017);
1346   /* "Hi-low color" selection from windows driver.  low(1437) hi(1481) */
1347   write_word (fd, LAMP_R_OFF, 0x1437);
1348   write_word (fd, LAMP_G_ON, 0x0017);
1349   write_word (fd, LAMP_G_OFF, 0x094e);
1350   write_word (fd, LAMP_B_ON, 0x0017);
1351   write_word (fd, LAMP_B_OFF, 0x0543);
1352 
1353   /* Analog static offset R,G,B.  Greyscale has 0,0,0 */
1354   write_byte (fd, 0x38, 0x3f);
1355   write_byte (fd, 0x39, 0x3f);
1356   write_byte (fd, 0x3a, 0x3f);
1357   /* Analog static gain R,G,B (normally 0x01) */
1358   write_byte (fd, 0x3b, opt->gain);
1359   write_byte (fd, 0x3c, opt->gain);
1360   write_byte (fd, 0x3d, opt->gain);
1361   /* Digital gain/offset settings.  Greyscale has 0 */
1362   write_byte (fd, 0x3e, 0x1a);
1363 
1364   {
1365     /* Stepper motion setup. */
1366     int stepsize, faststep = 0x0104, reverse = 0x28, phase, pwm = 0x1f;
1367     switch (opt->resolution)
1368       {
1369       case 75:
1370 	stepsize = 0x0106;
1371 	faststep = 0x0106;
1372 	reverse = 0;
1373 	phase = 0x39a8;
1374 	pwm = 0x3f;
1375 	break;
1376       case 150:
1377 	stepsize = 0x020d;
1378 	phase = 0x3198;
1379 	break;
1380       case 300:
1381 	stepsize = 0x041a;
1382 	phase = 0x2184;
1383 	break;
1384       case 600:
1385 	stepsize = 0x0835;
1386 	phase = 0x0074;
1387 	break;
1388       case 1200:
1389 	/* 1200 dpi y only, x is 600 dpi */
1390 	stepsize = 0x106b;
1391 	phase = 0x41ac;
1392 	break;
1393       default:
1394 	DBG (1, "BAD RESOLUTION");
1395 	return SANE_STATUS_UNSUPPORTED;
1396       }
1397 
1398     write_word (fd, STEP_SIZE, stepsize);
1399     write_word (fd, FAST_STEP, faststep);
1400     /* There sounds like a weird step disjoint at the end of skipsteps
1401        at 75dpi, so I think that's why skipsteps=0 at 75dpi in the
1402        Windows driver.  It still works at the normal 0x017a though. */
1403     /* cal strip is 0x17a steps, plus 2 300dpi microsteps per pixel */
1404     write_word (fd, SKIP_STEPS, 0x017a /* cal strip */  + opt->y1 * 2);
1405     /* FIXME could be 0x57, why not? */
1406     write_byte (fd, BUFFER_LIMIT, 0x20);
1407     write_byte (fd, BUFFER_RESUME, 0x02);
1408     write_byte (fd, REVERSE_STEPS, reverse);
1409     /* motor resume phasing */
1410     write_word (fd, 0x52, phase);
1411     write_byte (fd, STEP_PWM, pwm);
1412   }
1413 
1414   read_byte (fd, PAPER_SENSOR, &result);	/* wants 2b */
1415   write_byte (fd, PAPER_SENSOR, 0x0b);
1416 
1417   opt->width = (opt->x2 - opt->x1) * opt->resolution / 600 + 1;
1418   opt->height = (opt->y2 - opt->y1) * opt->resolution / 600;
1419   opt->flags = 0;
1420   DBG (1, "width=%d height=%d dpi=%d\n", opt->width, opt->height,
1421        opt->resolution);
1422   CHK (do_scan (opt));
1423 
1424   read_byte (fd, PAPER_SENSOR, &result);	/* wants 0b */
1425   write_byte (fd, PAPER_SENSOR, 0x2b);
1426   write_byte (fd, STEP_PWM, 0x3f);
1427 
1428   lights_out (fd);
1429   /* home */
1430   write_byte (fd, COMMAND, 0x02);
1431 
1432   return status;
1433 }
1434 
1435 
1436 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)1437 CANON_set_scan_parameters (CANON_Handle * scan,
1438 			   const int forceCal,
1439 			   const int gray,
1440 			   const int left,
1441 			   const int top,
1442 			   const int right,
1443 			   const int bottom,
1444 			   const int res,
1445 			   const int gain,
1446 			   const double gamma)
1447 {
1448   DBG (2, "CANON_set_scan_parameters:\n");
1449   DBG (2, "cal   = %d\n", forceCal);
1450   DBG (2, "gray  = %d (ignored)\n", gray);
1451   DBG (2, "res   = %d\n", res);
1452   DBG (2, "gain  = %d\n", gain);
1453   DBG (2, "gamma = %f\n", gamma);
1454   DBG (2, "in 600dpi pixels:\n");
1455   DBG (2, "left  = %d, top    = %d\n", left, top);
1456   DBG (2, "right = %d, bottom = %d\n", right, bottom);
1457 
1458   /* Validate the input parameters */
1459   if ((left < 0) || (right > CANON_MAX_WIDTH))
1460     return SANE_STATUS_INVAL;
1461 
1462   if ((top < 0) || (bottom > CANON_MAX_HEIGHT))
1463     return SANE_STATUS_INVAL;
1464 
1465   if (((right - left) < 10) || ((bottom - top) < 10))
1466     return SANE_STATUS_INVAL;
1467 
1468   if ((res != 75) && (res != 150) && (res != 300)
1469       && (res != 600) && (res != 1200))
1470     return SANE_STATUS_INVAL;
1471 
1472   if ((gain < 0) || (gain > 64))
1473     return SANE_STATUS_INVAL;
1474 
1475   if (gamma <= 0.0)
1476     return SANE_STATUS_INVAL;
1477 
1478   /* Store params */
1479   scan->resolution = res;
1480   scan->x1 = left;
1481   scan->x2 = right - /* subtract 1 pixel */ 600 / scan->resolution;
1482   scan->y1 = top;
1483   scan->y2 = bottom;
1484   scan->gain = gain;
1485   scan->gamma = gamma;
1486   scan->flags = forceCal ? FLG_FORCE_CAL : 0;
1487 
1488   return SANE_STATUS_GOOD;
1489 }
1490 
1491 
1492 static SANE_Status
CANON_close_device(CANON_Handle * scan)1493 CANON_close_device (CANON_Handle * scan)
1494 {
1495   DBG (3, "CANON_close_device:\n");
1496   sanei_usb_close (scan->fd);
1497   return SANE_STATUS_GOOD;
1498 }
1499 
1500 
1501 static SANE_Status
CANON_open_device(CANON_Handle * scan,const char * dev)1502 CANON_open_device (CANON_Handle * scan, const char *dev)
1503 {
1504   SANE_Word vendor;
1505   SANE_Word product;
1506   SANE_Status res;
1507 
1508   DBG (3, "CANON_open_device: `%s'\n", dev);
1509 
1510   scan->fname = NULL;
1511   scan->fp = NULL;
1512   scan->flags = 0;
1513 
1514   res = sanei_usb_open (dev, &scan->fd);
1515   if (res != SANE_STATUS_GOOD)
1516     {
1517       DBG (1, "CANON_open_device: couldn't open device `%s': %s\n", dev,
1518 	   sane_strstatus (res));
1519       return res;
1520     }
1521 
1522 #ifndef NO_AUTODETECT
1523   /* We have opened the device. Check that it is a USB scanner. */
1524   if (sanei_usb_get_vendor_product (scan->fd, &vendor, &product) !=
1525       SANE_STATUS_GOOD)
1526     {
1527       DBG (1, "CANON_open_device: sanei_usb_get_vendor_product failed\n");
1528       /* This is not a USB scanner, or SANE or the OS doesn't support it. */
1529       sanei_usb_close (scan->fd);
1530       scan->fd = -1;
1531       return SANE_STATUS_UNSUPPORTED;
1532     }
1533 
1534   /* Make sure we have a CANON scanner */
1535   if ((vendor != 0x04a9) || (product != 0x2204))
1536     {
1537       DBG (1, "CANON_open_device: incorrect vendor/product (0x%x/0x%x)\n",
1538 	   vendor, product);
1539       sanei_usb_close (scan->fd);
1540       scan->fd = -1;
1541       return SANE_STATUS_UNSUPPORTED;
1542     }
1543 #endif
1544 
1545   return SANE_STATUS_GOOD;
1546 }
1547 
1548 
1549 static const char *
CANON_get_device_name(CANON_Handle * scanner)1550 CANON_get_device_name (CANON_Handle * scanner)
1551 {
1552   (void) scanner;		/* Eliminate warning about unused parameters */
1553   return "Canoscan FB630U";
1554 }
1555 
1556 
1557 static SANE_Status
CANON_finish_scan(CANON_Handle * scanner)1558 CANON_finish_scan (CANON_Handle * scanner)
1559 {
1560   DBG (3, "CANON_finish_scan:\n");
1561   if (scanner->fp)
1562     fclose (scanner->fp);
1563   scanner->fp = NULL;
1564 
1565   /* remove temp file */
1566   if (scanner->fname)
1567     {
1568       DBG (4, "removing temp file %s\n", scanner->fname);
1569       unlink (scanner->fname);
1570       free (scanner->fname);
1571     }
1572   scanner->fname = NULL;
1573 
1574   return SANE_STATUS_GOOD;
1575 }
1576 
1577 
1578 static SANE_Status
CANON_start_scan(CANON_Handle * scanner)1579 CANON_start_scan (CANON_Handle * scanner)
1580 {
1581   int rv;
1582   SANE_Status status;
1583   DBG (3, "CANON_start_scan called\n");
1584 
1585   /* choose a temp file name for scan data */
1586   scanner->fname = strdup ("/tmp/scan.XXXXXX");
1587 
1588   /* FIXME: we should be using fd, not discarding it! */
1589   int fd = mkstemp (scanner->fname);
1590   if (fd == -1)
1591     return SANE_STATUS_IO_ERROR;
1592   close(fd);
1593 
1594   /* calibrate if needed */
1595   rv = init (scanner->fd);
1596   if (rv < 0) {
1597       DBG(1, "Can't talk on USB.\n");
1598       return SANE_STATUS_IO_ERROR;
1599   }
1600   if ((rv == 1)
1601       || !check_ogn_file ()
1602       || (scanner->flags & FLG_FORCE_CAL)) {
1603       plugin_cal (scanner);
1604       wait_for_return (scanner->fd);
1605   }
1606 
1607   /* scan */
1608   if ((status = scan (scanner)) != SANE_STATUS_GOOD)
1609     {
1610       CANON_finish_scan (scanner);
1611       return status;
1612     }
1613 
1614   /* read the temp file back out */
1615   scanner->fp = fopen (scanner->fname, "r");
1616   DBG (4, "reading %s\n", scanner->fname);
1617   if (!scanner->fp)
1618     {
1619       DBG (1, "open %s", scanner->fname);
1620       return SANE_STATUS_IO_ERROR;
1621     }
1622   return SANE_STATUS_GOOD;
1623 }
1624 
1625 
1626 static SANE_Status
CANON_read(CANON_Handle * scanner,SANE_Byte * data,SANE_Int max_length,SANE_Int * length)1627 CANON_read (CANON_Handle * scanner, SANE_Byte * data,
1628 	    SANE_Int max_length, SANE_Int * length)
1629 {
1630   SANE_Status status;
1631   int red_len;
1632 
1633   DBG (5, "CANON_read called\n");
1634   if (!scanner->fp)
1635     return SANE_STATUS_INVAL;
1636   red_len = fread (data, 1, max_length, scanner->fp);
1637   /* return some data */
1638   if (red_len > 0)
1639     {
1640       *length = red_len;
1641       DBG (5, "CANON_read returned (%d/%d)\n", *length, max_length);
1642       return SANE_STATUS_GOOD;
1643     }
1644 
1645   /* EOF or file err */
1646   *length = 0;
1647   if (feof (scanner->fp))
1648     {
1649       DBG (4, "EOF\n");
1650       status = SANE_STATUS_EOF;
1651     }
1652   else
1653     {
1654       DBG (4, "IO ERR\n");
1655       status = SANE_STATUS_IO_ERROR;
1656     }
1657 
1658   CANON_finish_scan (scanner);
1659   DBG (5, "CANON_read returned (%d/%d)\n", *length, max_length);
1660   return status;
1661 }
1662