1 /***************************************************************************
2  * _S_A_N_E - Scanner Access Now Easy.
3 
4    dc240.c
5 
6    03/12/01 - Peter Fales
7 
8    Based on the dc210 driver, (C) 1998 Brian J. Murrell (which is
9 	based on dc25 driver (C) 1998 by Peter Fales)
10 
11    This file (C) 2001 by Peter Fales
12 
13    This file is part of the SANE package.
14 
15    This program is free software; you can redistribute it and/or
16    modify it under the terms of the GNU General Public License as
17    published by the Free Software Foundation; either version 2 of the
18    License, or (at your option) any later version.
19 
20    This program is distributed in the hope that it will be useful, but
21    WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23    General Public License for more details.
24 
25    You should have received a copy of the GNU General Public License
26    along with this program.  If not, see <https://www.gnu.org/licenses/>.
27 
28    As a special exception, the authors of SANE give permission for
29    additional uses of the libraries contained in this release of SANE.
30 
31    The exception is that, if you link a SANE library with other files
32    to produce an executable, this does not by itself cause the
33    resulting executable to be covered by the GNU General Public
34    License.  Your use of that executable is in no way restricted on
35    account of linking the SANE library code into it.
36 
37    This exception does not, however, invalidate any other reasons why
38    the executable file might be covered by the GNU General Public
39    License.
40 
41    If you submit changes to SANE to the maintainers to be included in
42    a subsequent release, you agree by submitting the changes that
43    those changes may be distributed with this exception intact.
44 
45    If you write modifications of your own for SANE, it is your choice
46    whether to permit this exception to apply to your modifications.
47    If you do not wish that, delete this exception notice.
48 
49  ***************************************************************************
50 
51    This file implements a SANE backend for the Kodak DC-240
52    digital camera.  THIS IS EXTREMELY ALPHA CODE!  USE AT YOUR OWN RISK!!
53 
54    (feedback to:  dc240-devel@fales-lorenz.net)
55 
56    This backend is based somewhat on the dc25 backend included in this
57    package by Peter Fales, and the dc210 backend by Brian J. Murrell
58 
59  ***************************************************************************/
60 
61 #include "../include/sane/config.h"
62 
63 #include <stdlib.h>
64 #include <string.h>
65 #include <stdio.h>
66 #include <unistd.h>
67 #include <fcntl.h>
68 #include <limits.h>
69 #include "../include/sane/sanei_jpeg.h"
70 #include <sys/ioctl.h>
71 
72 #include "../include/sane/sane.h"
73 #include "../include/sane/sanei.h"
74 #include "../include/sane/saneopts.h"
75 
76 #define BACKEND_NAME	dc240
77 #include "../include/sane/sanei_backend.h"
78 
79 #include "dc240.h"
80 
81 #ifndef PATH_MAX
82 # define PATH_MAX	1024
83 #endif
84 
85 #define MAGIC			(void *)0xab730324
86 #define DC240_CONFIG_FILE 	"dc240.conf"
87 #define THUMBSIZE		20736
88 
89 #ifdef B115200
90 # define DEFAULT_BAUD_RATE	B115200
91 #else
92 # define DEFAULT_BAUD_RATE	B38400
93 #endif
94 
95 #if defined (__sgi)
96 # define DEFAULT_TTY		"/dev/ttyd1"	/* Irix */
97 #elif defined (__sun)
98 # define DEFAULT_TTY		"/dev/term/a"	/* Solaris */
99 #elif defined (hpux)
100 # define DEFAULT_TTY		"/dev/tty1d0"	/* HP-UX */
101 #elif defined (__osf__)
102 # define DEFAULT_TTY		"/dev/tty00"	/* Digital UNIX */
103 #else
104 # define DEFAULT_TTY		"/dev/ttyS0"	/* Linux */
105 #endif
106 
107 static SANE_Bool is_open = 0;
108 
109 static SANE_Bool dc240_opt_thumbnails;
110 static SANE_Bool dc240_opt_snap;
111 static SANE_Bool dc240_opt_lowres;
112 static SANE_Bool dc240_opt_erase;
113 static SANE_Bool dc240_opt_autoinc;
114 static SANE_Bool dumpinquiry;
115 
116 static struct jpeg_decompress_struct cinfo;
117 static djpeg_dest_ptr dest_mgr = NULL;
118 
119 static unsigned long cmdrespause = 250000UL;	/* pause after sending cmd */
120 static unsigned long breakpause = 1000000UL;	/* pause after sending break */
121 
122 static DC240 Camera;
123 
124 static SANE_Range image_range = {
125   0,
126   0,
127   0
128 };
129 
130 static SANE_String **folder_list;
131 static SANE_Int current_folder = 0;
132 
133 static SANE_Option_Descriptor sod[] = {
134   {
135    SANE_NAME_NUM_OPTIONS,
136    SANE_TITLE_NUM_OPTIONS,
137    SANE_DESC_NUM_OPTIONS,
138    SANE_TYPE_INT,
139    SANE_UNIT_NONE,
140    sizeof (SANE_Word),
141    SANE_CAP_SOFT_DETECT,
142    SANE_CONSTRAINT_NONE,
143    {NULL}
144    }
145   ,
146 
147 #define DC240_OPT_IMAGE_SELECTION 1
148   {
149    "",
150    "Image Selection",
151    "Selection of the image to load.",
152    SANE_TYPE_GROUP,
153    SANE_UNIT_NONE,
154    0,
155    0,
156    SANE_CONSTRAINT_NONE,
157    {NULL}
158    }
159   ,
160 
161 #define DC240_OPT_FOLDER 2
162   {
163    "folder",
164    "Folder",
165    "Select folder within camera",
166    SANE_TYPE_STRING,
167    SANE_UNIT_NONE,
168    256,
169    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
170    SANE_CONSTRAINT_STRING_LIST,
171    {NULL}
172    }
173   ,
174 
175 #define DC240_OPT_IMAGE_NUMBER 3
176   {
177    "image",
178    "Image Number",
179    "Select Image Number to load from camera",
180    SANE_TYPE_INT,
181    SANE_UNIT_NONE,
182    4,
183    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
184    SANE_CONSTRAINT_RANGE,
185    {(SANE_String_Const *) & image_range}	/* this is ANSI conformant! */
186    }
187   ,
188 
189 #define DC240_OPT_THUMBS 4
190   {
191    "thumbs",
192    "Load Thumbnail",
193    "Load the image as thumbnail.",
194    SANE_TYPE_BOOL,
195    SANE_UNIT_NONE,
196    sizeof (SANE_Word),
197    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
198    SANE_CONSTRAINT_NONE,
199    {NULL}
200    }
201   ,
202 #define DC240_OPT_SNAP 5
203   {
204    "snap",
205    "Snap new picture",
206    "Take new picture and download it",
207    SANE_TYPE_BOOL,
208    SANE_UNIT_NONE,
209    sizeof (SANE_Word),
210    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT /* | SANE_CAP_ADVANCED */ ,
211    SANE_CONSTRAINT_NONE,
212    {NULL}
213    }
214   ,
215 #define DC240_OPT_LOWRES 6
216   {
217    "lowres",
218    "Low Resolution",
219    "Resolution of new pictures",
220    SANE_TYPE_BOOL,
221    SANE_UNIT_NONE,
222    sizeof (SANE_Word),
223    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE
224    /* | SANE_CAP_ADVANCED */ ,
225    SANE_CONSTRAINT_NONE,
226    {NULL}
227    }
228   ,
229 
230 #define DC240_OPT_ERASE 7
231   {
232    "erase",
233    "Erase",
234    "Erase the picture after downloading",
235    SANE_TYPE_BOOL,
236    SANE_UNIT_NONE,
237    sizeof (SANE_Word),
238    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
239    SANE_CONSTRAINT_NONE,
240    {NULL}
241    }
242   ,
243 
244 #define DC240_OPT_DEFAULT 8
245   {
246    "default-enhancements",
247    "Defaults",
248    "Set default values for enhancement controls.",
249    SANE_TYPE_BUTTON,
250    SANE_UNIT_NONE,
251    0,
252    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
253    SANE_CONSTRAINT_NONE,
254    {NULL}
255    }
256   ,
257 
258 #define DC240_OPT_INIT_DC240 9
259   {
260    "camera-init",
261    "Re-establish Communications",
262    "Re-establish communications with camera (in case of timeout, etc.)",
263    SANE_TYPE_BUTTON,
264    SANE_UNIT_NONE,
265    0,
266    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
267    SANE_CONSTRAINT_NONE,
268    {NULL}
269    }
270   ,
271 
272 #define DC240_OPT_AUTOINC 10
273   {
274    "autoinc",
275    "Auto Increment",
276    "Increment image number after each scan",
277    SANE_TYPE_BOOL,
278    SANE_UNIT_NONE,
279    sizeof (SANE_Word),
280    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED,
281    SANE_CONSTRAINT_NONE,
282    {NULL}
283    }
284   ,
285 
286 };
287 
288 static SANE_Parameters parms = {
289   SANE_FRAME_RGB,
290   0,
291   0,				/* Number of bytes returned per scan line: */
292   0,				/* Number of pixels per scan line.  */
293   0,				/* Number of lines for the current scan.  */
294   8,				/* Number of bits per sample. */
295 };
296 
297 
298 
299 
300 static SANE_Byte shoot_pck[] = SHOOT_PCK;
301 static SANE_Byte init_pck[] = INIT_PCK;
302 static SANE_Byte thumb_pck[] = THUMBS_PCK;
303 static SANE_Byte pic_pck[] = PICS_PCK;
304 static SANE_Byte pic_info_pck[] = PICS_INFO_PCK;
305 static SANE_Byte info_pck[] = INFO_PCK;
306 static SANE_Byte erase_pck[] = ERASE_PCK;
307 static SANE_Byte res_pck[] = RES_PCK;
308 static SANE_Byte open_card_pck[] = OPEN_CARD_PCK;
309 static SANE_Byte read_dir_pck[] = READ_DIR_PCK;
310 
311 static struct pkt_speed speeds[] = SPEEDS;
312 static struct termios tty_orig;
313 
314 SANE_Byte dir_buf2[2 + CAMDIRENTRYSIZE * DIRENTRIES];
315 
316 static struct cam_dirlist *dir_head = NULL;
317 
318 static SANE_Byte info_buf[256];
319 static SANE_Byte name_buf[60];
320 
321 #include <sys/time.h>
322 #include <unistd.h>
323 
324 static SANE_Int
send_pck(SANE_Int fd, SANE_Byte * pck)325 send_pck (SANE_Int fd, SANE_Byte * pck)
326 {
327   SANE_Int n;
328   SANE_Byte r = 0xf0;		/* prime the loop with a "camera busy" */
329 
330   DBG (127, "send_pck<%x %x %x %x %x %x %x %x>\n",
331        pck[0], pck[1], pck[2], pck[3], pck[4], pck[5], pck[6], pck[7]);
332 
333   /* keep trying if camera says it's busy */
334   while (r == 0xf0)
335     {
336       if (write (fd, (char *) pck, 8) != 8)
337 	{
338 	  DBG (1, "send_pck: error: write returned -1\n");
339 	  return -1;
340 	}
341       /* need to wait before we read command result */
342       usleep (cmdrespause);
343 
344       if ((n = read (fd, (char *) &r, 1)) != 1)
345 	{
346 	  DBG (1, "send_pck: error: read returned -1\n");
347 	  return -1;
348 	}
349     }
350   DBG (127, "send_pck: read one byte result from camera =  %x\n", r);
351   return (r == 0xd1) ? 0 : -1;
352 }
353 
354 static SANE_Int
init_dc240(DC240 * camera)355 init_dc240 (DC240 * camera)
356 {
357   struct termios tty_new;
358   SANE_Int speed_index;
359   SANE_Char buf[5], n;
360 
361   DBG (1, "DC-240 Backend 05/16/01\n");
362 
363   for (speed_index = 0; speed_index < NELEMS (speeds); speed_index++)
364     {
365       if (speeds[speed_index].baud == camera->baud)
366 	{
367 	  init_pck[2] = speeds[speed_index].pkt_code[0];
368 	  init_pck[3] = speeds[speed_index].pkt_code[1];
369 	  break;
370 	}
371     }
372 
373   if (init_pck[2] == 0)
374     {
375       DBG (1, "unsupported baud rate.\n");
376       return -1;
377     }
378 
379   /*
380      Open device file.
381    */
382   if ((camera->fd = open (camera->tty_name, O_RDWR)) == -1)
383     {
384       DBG (1, "init_dc240: error: could not open %s for read/write\n",
385 	   camera->tty_name);
386       return -1;
387     }
388   /*
389      Save old device information to restore when we are done.
390    */
391   if (tcgetattr (camera->fd, &tty_orig) == -1)
392     {
393       DBG (1, "init_dc240: error: could not get attributes\n");
394       return -1;
395     }
396 
397   memcpy ((char *) &tty_new, (char *) &tty_orig, sizeof (struct termios));
398   /*
399      We need the device to be raw. 8 bits even parity on 9600 baud to start.
400    */
401 #ifdef HAVE_CFMAKERAW
402   cfmakeraw (&tty_new);
403 #else
404   /* Modified to set the port REALLY as required (9600, 8b, 1sb, NO parity).
405      Code inspired by the gPhoto2 serial port setup */
406 
407   /* input control settings */
408   tty_new.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC |
409                       IXANY | IXON | IXOFF | INPCK | ISTRIP);
410   tty_new.c_iflag |= (BRKINT | IGNPAR);
411   /* output control settings */
412   tty_new.c_oflag &= ~OPOST;
413   /* hardware control settings */
414   tty_new.c_cflag = (tty_new.c_cflag & ~CSIZE) | CS8;
415   tty_new.c_cflag &= ~(PARENB | PARODD | CSTOPB);
416 # if defined(__sgi)
417   tty_new.c_cflag &= ~CNEW_RTSCTS;
418 # else
419 /* OS/2 doesn't have CRTSCTS - will this work for them? */
420 #  ifdef CRTSCTS
421   tty_new.c_cflag &= ~CRTSCTS;
422 #  endif
423 # endif
424   tty_new.c_cflag |= CLOCAL | CREAD;
425 #endif
426   /* line discipline settings */
427   tty_new.c_lflag &= ~(ICANON | ISIG | ECHO | ECHONL | ECHOE |
428                        ECHOK | IEXTEN);
429   tty_new.c_cc[VMIN] = 0;
430   tty_new.c_cc[VTIME] = 5;
431   cfsetospeed (&tty_new, B9600);
432   cfsetispeed (&tty_new, B9600);
433 
434   if (tcsetattr (camera->fd, TCSANOW, &tty_new) == -1)
435     {
436       DBG (1, "init_dc240: error: could not set attributes\n");
437       return -1;
438     }
439 
440   /* send a break to get it back to a known state */
441   /* Used to supply a non-zero argument to tcsendbreak(), TCSBRK,
442    * and TCSBRKP, but that is system dependent.  e.g. on irix a non-zero
443    * value does a drain instead of a break.  A zero value is universally
444    * used to send a break.
445    */
446 
447 #ifdef HAVE_TCSENDBREAK
448   tcsendbreak (camera->fd, 0);
449 # if defined(__sgi)
450   tcdrain (camera->fd);
451 # endif
452 # elif defined(TCSBRKP)
453   ioctl (camera->fd, TCSBRKP, 0);
454 # elif defined(TCSBRK)
455   ioctl (camera->fd, TCSBRK, 0);
456 #endif
457 
458   /* and wait for it to recover from the break */
459 
460 #ifdef HAVE_USLEEP
461   usleep (breakpause);
462 #else
463   sleep (1);
464 #endif
465 
466   /* We seem to get some garbage following the break, so
467    * read anything pending */
468 
469   n = read (camera->fd, buf, 5);
470 
471   DBG (127, "init_dc240 flushed %d bytes: %x %x %x %x %x\n", n, buf[0],
472        buf[1], buf[2], buf[3], buf[4]);
473 
474   if (send_pck (camera->fd, init_pck) == -1)
475     {
476       /*
477        *    The camera always powers up at 9600, so we try
478        *      that first.  However, it may be already set to
479        *      a different speed.  Try the entries in the table:
480        */
481 
482       tcsetattr (camera->fd, TCSANOW, &tty_orig);
483       DBG (1, "init_dc240: error: no response from camera\n");
484       return -1;
485     }
486 
487   n = read (camera->fd, buf, 5);
488   DBG (127, "init_dc240 flushed %d bytes: %x %x %x %x %x\n", n, buf[0],
489        buf[1], buf[2], buf[3], buf[4]);
490 
491   /*
492      Set speed to requested speed.
493    */
494   cfsetospeed (&tty_new, Camera.baud);
495   cfsetispeed (&tty_new, Camera.baud);
496 
497   if (tcsetattr (camera->fd, TCSANOW, &tty_new) == -1)
498     {
499       DBG (1, "init_dc240: error: could not set attributes\n");
500       return -1;
501     }
502 
503 
504   if (send_pck (camera->fd, open_card_pck) == -1)
505     {
506       DBG (1, "init_dc240: error: send_pck returned -1\n");
507       return -1;
508     }
509 
510   if (end_of_data (camera->fd) == -1)
511     {
512       DBG (1, "init_dc240: error: end_of_data returned -1\n");
513       return -1;
514     }
515 
516   return camera->fd;
517 
518 }
519 
520 static void
close_dc240(SANE_Int fd)521 close_dc240 (SANE_Int fd)
522 {
523   /*
524    *    Put the camera back to 9600 baud
525    */
526 
527   if (close (fd) == -1)
528     {
529       DBG (1, "close_dc240: error: could not close device\n");
530     }
531 }
532 
533 int
get_info(DC240 * camera)534 get_info (DC240 * camera)
535 {
536 
537   SANE_Char f[] = "get_info";
538   SANE_Byte buf[256];
539   SANE_Int n;
540   struct cam_dirlist *e;
541 
542   if (send_pck (camera->fd, info_pck) == -1)
543     {
544       DBG (1, "%s: error: send_pck returned -1\n", f);
545       return -1;
546     }
547 
548   DBG (9, "%s: read info packet\n", f);
549 
550   if (read_data (camera->fd, buf, 256) == -1)
551     {
552       DBG (1, "%s: error: read_data returned -1\n", f);
553       return -1;
554     }
555 
556   if (end_of_data (camera->fd) == -1)
557     {
558       DBG (1, "%s: error: end_of_data returned -1\n", f);
559       return -1;
560     }
561 
562   camera->model = buf[1];
563 
564   if (camera->model != 0x5)
565     {
566       DBG (0,
567 	   "Camera model (%d) is not DC-240 (5).  "
568 	   "Only the DC-240 is supported by this driver.\n", camera->model);
569     }
570 
571   camera->ver_major = buf[2];
572   camera->ver_minor = buf[3];
573   camera->pic_taken = buf[14] << 8 | buf[15];
574   DBG (4, "pic_taken=%d\n", camera->pic_taken);
575   camera->pic_left = buf[64] << 8 | buf[65];
576   DBG (4, "pictures left (at current res)=%d\n", camera->pic_left);
577   camera->flags.low_batt = buf[8];
578   DBG (4, "battery=%d (0=OK, 1=weak, 2=empty)\n", camera->flags.low_batt);
579   DBG (4, "AC adapter status=%d\n", buf[9]);
580   dc240_opt_lowres = !buf[79];
581 
582   if (Camera.pic_taken == 0)
583     {
584       sod[DC240_OPT_IMAGE_NUMBER].cap |= SANE_CAP_INACTIVE;
585       image_range.min = 0;
586       image_range.max = 0;
587     }
588   else
589     {
590       sod[DC240_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE;
591       image_range.min = 1;
592       image_range.max = Camera.pic_taken;
593     }
594 
595   n = read_dir ("\\PCCARD\\DCIM\\*.*");
596 
597   /* If we've already got a folder_list, free it up before starting
598    * the new one
599    */
600   if (folder_list != NULL)
601     {
602       int tmp;
603       for (tmp = 0; folder_list[tmp]; tmp++)
604 	{
605 	  free (folder_list[tmp]);
606 	}
607       free (folder_list);
608     }
609 
610   folder_list = (SANE_String * *)malloc ((n + 1) * sizeof (SANE_String *));
611   for (e = dir_head, n = 0; e; e = e->next, n++)
612     {
613       folder_list[n] = (SANE_String *) strdup (e->name);
614       if (strchr ((char *) folder_list[n], ' '))
615 	{
616 	  *strchr ((char *) folder_list[n], ' ') = '\0';
617 	}
618     }
619   folder_list[n] = NULL;
620   sod[DC240_OPT_FOLDER].constraint.string_list =
621     (SANE_String_Const *) folder_list;
622 
623   return 0;
624 
625 }
626 
627 /* NEW */
628 static SANE_Int
read_data(SANE_Int fd, SANE_Byte * buf, SANE_Int sz)629 read_data (SANE_Int fd, SANE_Byte * buf, SANE_Int sz)
630 {
631   SANE_Byte ccsum;
632   SANE_Byte rcsum;
633   SANE_Byte c;
634   SANE_Int retries = 0;
635   SANE_Int n;
636   SANE_Int r = 0;
637   SANE_Int i;
638 
639   while (retries++ < 5)
640     {
641 
642       /*
643        * If this is not the first time through, then it must be
644        * a retry - signal the camera that we didn't like what
645        * we got.  In either case, start filling the packet
646        */
647       if (retries != 1)
648 	{
649 
650 	  DBG (2, "Attempt retry %d\n", retries);
651 	  c = 0xe3;
652 	  if (write (fd, (char *) &c, 1) != 1)
653 	    {
654 	      DBG (1, "read_data: error: write ack\n");
655 	      return -1;
656 	    }
657 
658 	}
659 
660       /* read the control byte */
661       if (read (fd, &c, 1) != 1)
662 	{
663 	  DBG (3,
664 	       "read_data: error: "
665 	       "read for packet control byte returned bad stat!us\n");
666 	  return -1;
667 	}
668       if (c != 1 && c != 0)
669 	{
670 	  DBG (1, "read_data: error: incorrect packet control byte: %02x\n",
671 	       c);
672 	  return -1;
673 	}
674 
675       for (n = 0; n < sz && (r = read (fd, (char *) &buf[n], sz - n)) > 0;
676 	   n += r);
677 
678       if (r <= 0)
679 	{
680 	  DBG (2, "read_data: warning: read returned -1\n");
681 	  continue;
682 	}
683 
684       if (n < sz || read (fd, &rcsum, 1) != 1)
685 	{
686 	  DBG (2, "read_data: warning: buffer underrun or no checksum\n");
687 	  continue;
688 	}
689 
690       for (i = 0, ccsum = 0; i < n; i++)
691 	ccsum ^= buf[i];
692 
693       if (ccsum != rcsum)
694 	{
695 	  DBG (2,
696 	       "read_data: warning: "
697 	       "bad checksum (got %02x != expected %02x)\n", rcsum, ccsum);
698 	  continue;
699 	}
700 
701       /* If we got this far, then the packet is OK */
702       break;
703 
704 
705     }
706 
707   c = 0xd2;
708 
709   if (write (fd, (char *) &c, 1) != 1)
710     {
711       DBG (1, "read_data: error: write ack\n");
712       return -1;
713     }
714 
715   return 0;
716 }
717 
718 static SANE_Int
end_of_data(SANE_Int fd)719 end_of_data (SANE_Int fd)
720 {
721   SANE_Int n;
722   SANE_Byte c;
723 
724   do
725     {				/* loop until the camera isn't busy */
726       if ((n = read (fd, &c, 1)) == -1)
727 	{
728 	  DBG (1, "end_of_data: error: read returned -1\n");
729 	  return -1;
730 	}
731       if (n == 1 && c == 0)	/* got successful end of data */
732 	return 0;		/* return success */
733       if (n == 1)
734 	{
735 	  DBG (127, "end_of_data: got %x while waiting\n", c);
736 	}
737       else
738 	{
739 	  DBG (127, "end_of_data: waiting...\n");
740 	}
741       sleep (1);		/* not too fast */
742     }
743 /* It's not documented, but we see a d1 after snapping a picture */
744   while (c == 0xf0 || c == 0xd1);
745 
746   /* Accck!  Not busy, but not a good end of data either */
747   if (c != 0)
748     {
749       DBG (1, "end_of_data: error: bad EOD from camera (%02x)\n",
750 	   (unsigned) c);
751       return -1;
752     }
753   return 0;			/* should never get here but shut gcc -Wall up */
754 }
755 
756 static SANE_Int
erase(SANE_Int fd)757 erase (SANE_Int fd)
758 {
759   if (send_pck (fd, erase_pck) == -1)
760     {
761       DBG (1, "erase: error: send_pck returned -1\n");
762       return -1;
763     }
764 
765   if (send_data (name_buf) == -1)
766     {
767       DBG (1, "erase: error: send_data returned -1\n");
768       return SANE_STATUS_INVAL;
769     }
770 
771   if (end_of_data (fd) == -1)
772     {
773       DBG (1, "erase: error: end_of_data returned -1\n");
774       return -1;
775     }
776 
777   return 0;
778 }
779 
780 static SANE_Int
change_res(SANE_Int fd, SANE_Byte res)781 change_res (SANE_Int fd, SANE_Byte res)
782 {
783   SANE_Char f[] = "change_res";
784 
785   DBG (127, "%s called, low_res=%d\n", f, res);
786 
787   if (res != 0 && res != 1)
788     {
789       DBG (1, "%s: error: unsupported resolution\n", f);
790       return -1;
791     }
792 
793   /* cameras resolution semantics are opposite of ours */
794   res = !res;
795   DBG (127, "%s: setting res to %d\n", f, res);
796   res_pck[2] = res;
797 
798   if (send_pck (fd, res_pck) == -1)
799     {
800       DBG (1, "%s: error: send_pck returned -1\n", f);
801     }
802 
803   if (end_of_data (fd) == -1)
804     {
805       DBG (1, "%s: error: end_of_data returned -1\n", f);
806     }
807   return 0;
808 }
809 
810 SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize)811 sane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize)
812 {
813 
814   SANE_Char f[] = "sane_init";
815   SANE_Char dev_name[PATH_MAX], *p;
816   size_t len;
817   FILE *fp;
818   SANE_Int baud;
819 
820   DBG_INIT ();
821 
822   if (version_code)
823     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
824 
825   fp = sanei_config_open (DC240_CONFIG_FILE);
826 
827   /* defaults */
828   Camera.baud = DEFAULT_BAUD_RATE;
829   Camera.tty_name = DEFAULT_TTY;
830 
831   if (!fp)
832     {
833       /* default to /dev/whatever instead of insisting on config file */
834       DBG (1, "%s:  missing config file '%s'\n", f, DC240_CONFIG_FILE);
835     }
836   else
837     {
838       while (sanei_config_read (dev_name, sizeof (dev_name), fp))
839 	{
840 	  dev_name[sizeof (dev_name) - 1] = '\0';
841 	  DBG (20, "%s:  config- %s\n", f, dev_name);
842 
843 	  if (dev_name[0] == '#')
844 	    continue;		/* ignore line comments */
845 	  len = strlen (dev_name);
846 	  if (!len)
847 	    continue;		/* ignore empty lines */
848 	  if (strncmp (dev_name, "port=", 5) == 0)
849 	    {
850 	      p = strchr (dev_name, '/');
851 	      if (p)
852 		Camera.tty_name = strdup (p);
853 	      DBG (20, "Config file port=%s\n", Camera.tty_name);
854 	    }
855 	  else if (strncmp (dev_name, "baud=", 5) == 0)
856 	    {
857 	      baud = atoi (&dev_name[5]);
858 	      switch (baud)
859 		{
860 		case 9600:
861 		  Camera.baud = B9600;
862 		  break;
863 		case 19200:
864 		  Camera.baud = B19200;
865 		  break;
866 		case 38400:
867 		  Camera.baud = B38400;
868 		  break;
869 #ifdef B57600
870 		case 57600:
871 		  Camera.baud = B57600;
872 		  break;
873 #endif
874 #ifdef B115200
875 		case 115200:
876 		  Camera.baud = B115200;
877 		  break;
878 #endif
879 		}
880 	      DBG (20, "Config file baud=%d\n", Camera.baud);
881 	    }
882 	  else if (strcmp (dev_name, "dumpinquiry") == 0)
883 	    {
884 	      dumpinquiry = SANE_TRUE;
885 	    }
886 	  else if (strncmp (dev_name, "cmdrespause=", 12) == 0)
887 	    {
888 	      cmdrespause = atoi (&dev_name[12]);
889 	      DBG (20, "Config file cmdrespause=%lu\n", cmdrespause);
890 	    }
891 	  else if (strncmp (dev_name, "breakpause=", 11) == 0)
892 	    {
893 	      breakpause = atoi (&dev_name[11]);
894 	      DBG (20, "Config file breakpause=%lu\n", breakpause);
895 	    }
896 	}
897       fclose (fp);
898     }
899 
900   if (init_dc240 (&Camera) == -1)
901     return SANE_STATUS_INVAL;
902 
903   if (get_info (&Camera) == -1)
904     {
905       DBG (1, "error: could not get info\n");
906       close_dc240 (Camera.fd);
907       return SANE_STATUS_INVAL;
908     }
909 
910   /* load the current images array */
911   get_pictures_info ();
912 
913   if (Camera.pic_taken == 0)
914     {
915       Camera.current_picture_number = 0;
916       parms.bytes_per_line = 0;
917       parms.pixels_per_line = 0;
918       parms.lines = 0;
919     }
920   else
921     {
922       Camera.current_picture_number = 1;
923       set_res (Camera.Pictures[Camera.current_picture_number - 1].low_res);
924     }
925 
926   if (dumpinquiry)
927     {
928       DBG (0, "\nCamera information:\n~~~~~~~~~~~~~~~~~\n\n");
929       DBG (0, "Model...........: DC%s\n", "240");
930       DBG (0, "Firmware version: %d.%d\n", Camera.ver_major,
931 	   Camera.ver_minor);
932       DBG (0, "Pictures........: %d/%d\n", Camera.pic_taken,
933 	   Camera.pic_taken + Camera.pic_left);
934       DBG (0, "Battery state...: %s\n",
935 	   Camera.flags.low_batt == 0 ? "good" : (Camera.flags.low_batt ==
936 						  1 ? "weak" : "empty"));
937     }
938 
939   return SANE_STATUS_GOOD;
940 }
941 
942 void
sane_exit(void)943 sane_exit (void)
944 {
945 }
946 
947 /* Device select/open/close */
948 
949 static const SANE_Device dev[] = {
950   {
951    "0",
952    "Kodak",
953    "DC-240",
954    "still camera"},
955 };
956 
957 static const SANE_Device *devlist[] = {
958   dev + 0, 0
959 };
960 
961 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool __sane_unused__ local_only)962 sane_get_devices (const SANE_Device *** device_list, SANE_Bool
963 		  __sane_unused__ local_only)
964 {
965 
966   DBG (127, "sane_get_devices called\n");
967 
968   *device_list = devlist;
969   return SANE_STATUS_GOOD;
970 }
971 
972 SANE_Status
sane_open(SANE_String_Const devicename, SANE_Handle * handle)973 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
974 {
975   SANE_Int i;
976 
977   DBG (127, "sane_open for device %s\n", devicename);
978   if (!devicename[0])
979     {
980       i = 0;
981     }
982   else
983     {
984       for (i = 0; i < NELEMS (dev); ++i)
985 	{
986 	  if (strcmp (devicename, dev[i].name) == 0)
987 	    {
988 	      break;
989 	    }
990 	}
991     }
992 
993   if (i >= NELEMS (dev))
994     {
995       return SANE_STATUS_INVAL;
996     }
997 
998   if (is_open)
999     {
1000       return SANE_STATUS_DEVICE_BUSY;
1001     }
1002 
1003   is_open = 1;
1004   *handle = MAGIC;
1005 
1006   DBG (4, "sane_open: pictures taken=%d\n", Camera.pic_taken);
1007 
1008   return SANE_STATUS_GOOD;
1009 }
1010 
1011 void
sane_close(SANE_Handle handle)1012 sane_close (SANE_Handle handle)
1013 {
1014   DBG (127, "sane_close called\n");
1015   if (handle == MAGIC)
1016     is_open = 0;
1017 
1018   DBG (127, "sane_close returning\n");
1019 }
1020 
1021 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)1022 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
1023 {
1024   if (handle != MAGIC || !is_open)
1025     return NULL;		/* wrong device */
1026   if (option < 0 || option >= NELEMS (sod))
1027     return NULL;
1028   return &sod[option];
1029 }
1030 
1031 static SANE_Int myinfo = 0;
1032 
1033 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *value, SANE_Int * info)1034 sane_control_option (SANE_Handle handle, SANE_Int option,
1035 		     SANE_Action action, void *value, SANE_Int * info)
1036 {
1037   SANE_Status status;
1038 
1039   if (option < 0 || option >= NELEMS (sod))
1040     return SANE_STATUS_INVAL;	/* Unknown option ... */
1041 
1042   /* Need to put this DBG line after the range check on option */
1043   DBG (127, "control_option(handle=%p,opt=%s,act=%s,val=%p,info=%p)\n",
1044        handle, sod[option].title,
1045        (action ==
1046 	SANE_ACTION_SET_VALUE ? "SET" : (action ==
1047 					 SANE_ACTION_GET_VALUE ? "GET" :
1048 					 "SETAUTO")), value, (void *) info);
1049 
1050   if (handle != MAGIC || !is_open)
1051     return SANE_STATUS_INVAL;	/* Unknown handle ... */
1052 
1053   switch (action)
1054     {
1055     case SANE_ACTION_SET_VALUE:
1056 
1057       /* Can't set disabled options */
1058       if (!SANE_OPTION_IS_ACTIVE (sod[option].cap))
1059 	{
1060 	  return (SANE_STATUS_INVAL);
1061 	}
1062 
1063       /* initialize info to zero - we'll OR in various values later */
1064       if (info)
1065 	*info = 0;
1066 
1067       status = sanei_constrain_value (sod + option, value, &myinfo);
1068       if (status != SANE_STATUS_GOOD)
1069 	{
1070 	  DBG (2, "Constraint error in control_option\n");
1071 	  return status;
1072 	}
1073 
1074       switch (option)
1075 	{
1076 	case DC240_OPT_IMAGE_NUMBER:
1077 	  if (*(SANE_Word *) value <= Camera.pic_taken)
1078 	    Camera.current_picture_number = *(SANE_Word *) value;
1079 	  else
1080 	    Camera.current_picture_number = Camera.pic_taken;
1081 
1082 	  myinfo |= SANE_INFO_RELOAD_PARAMS;
1083 
1084 	  /* get the image's resolution, unless the camera has no
1085 	   * pictures yet
1086 	   */
1087 	  if (Camera.pic_taken != 0)
1088 	    {
1089 	      set_res (Camera.
1090 		       Pictures[Camera.current_picture_number - 1].low_res);
1091 	    }
1092 	  break;
1093 
1094 	case DC240_OPT_THUMBS:
1095 	  dc240_opt_thumbnails = !!*(SANE_Word *) value;
1096 
1097 	  /* Thumbnail forces an image size change: */
1098 	  myinfo |= SANE_INFO_RELOAD_PARAMS;
1099 
1100 	  if (Camera.pic_taken != 0)
1101 	    {
1102 	      set_res (Camera.
1103 		       Pictures[Camera.current_picture_number - 1].low_res);
1104 	    }
1105 	  break;
1106 
1107 	case DC240_OPT_SNAP:
1108 	  switch (*(SANE_Bool *) value)
1109 	    {
1110 	    case SANE_TRUE:
1111 	      dc240_opt_snap = SANE_TRUE;
1112 	      break;
1113 	    case SANE_FALSE:
1114 	      dc240_opt_snap = SANE_FALSE;
1115 	      break;
1116 	    default:
1117 	      return SANE_STATUS_INVAL;
1118 	    }
1119 
1120 	  /* Snap forces new image size and changes image range */
1121 
1122 	  myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1123 	  /* if we are snapping a new one */
1124 	  if (dc240_opt_snap)
1125 	    {
1126 	      /* activate the resolution setting */
1127 	      sod[DC240_OPT_LOWRES].cap &= ~SANE_CAP_INACTIVE;
1128 	      /* and de-activate the image number selector */
1129 	      sod[DC240_OPT_IMAGE_NUMBER].cap |= SANE_CAP_INACTIVE;
1130 	    }
1131 	  else
1132 	    {
1133 	      /* deactivate the resolution setting */
1134 	      sod[DC240_OPT_LOWRES].cap |= SANE_CAP_INACTIVE;
1135 	      /* and activate the image number selector */
1136 	      sod[DC240_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE;
1137 	    }
1138 	  /* set params according to resolution settings */
1139 	  set_res (dc240_opt_lowres);
1140 
1141 	  break;
1142 
1143 	case DC240_OPT_LOWRES:
1144 	  dc240_opt_lowres = !!*(SANE_Word *) value;
1145 	  myinfo |= SANE_INFO_RELOAD_PARAMS;
1146 
1147 /* XXX - change the number of pictures left depending on resolution
1148    perhaps just call get_info again?
1149 */
1150 	  set_res (dc240_opt_lowres);
1151 
1152 	  break;
1153 
1154 	case DC240_OPT_ERASE:
1155 	  dc240_opt_erase = !!*(SANE_Word *) value;
1156 	  break;
1157 
1158 	case DC240_OPT_AUTOINC:
1159 	  dc240_opt_autoinc = !!*(SANE_Word *) value;
1160 	  break;
1161 
1162 	case DC240_OPT_FOLDER:
1163 	  DBG (1, "FIXME set folder not implemented yet\n");
1164 	  break;
1165 
1166 	case DC240_OPT_DEFAULT:
1167 	  dc240_opt_thumbnails = 0;
1168 	  dc240_opt_snap = 0;
1169 
1170 	  /* deactivate the resolution setting */
1171 	  sod[DC240_OPT_LOWRES].cap |= SANE_CAP_INACTIVE;
1172 	  /* and activate the image number selector */
1173 	  sod[DC240_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE;
1174 
1175 	  myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1176 
1177 	  DBG (1, "Fixme: Set all defaults here!\n");
1178 	  break;
1179 
1180 	case DC240_OPT_INIT_DC240:
1181 	  if ((Camera.fd = init_dc240 (&Camera)) == -1)
1182 	    {
1183 	      return SANE_STATUS_INVAL;
1184 	    }
1185 	  if (get_info (&Camera) == -1)
1186 	    {
1187 	      DBG (1, "error: could not get info\n");
1188 	      close_dc240 (Camera.fd);
1189 	      return SANE_STATUS_INVAL;
1190 	    }
1191 
1192 	  /* load the current images array */
1193 	  get_pictures_info ();
1194 
1195 	  myinfo |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1196 	  break;
1197 
1198 	default:
1199 	  return SANE_STATUS_INVAL;
1200 	}
1201       break;
1202 
1203     case SANE_ACTION_GET_VALUE:
1204       /* Can't return status for disabled options */
1205       if (!SANE_OPTION_IS_ACTIVE (sod[option].cap))
1206 	{
1207 	  return (SANE_STATUS_INVAL);
1208 	}
1209 
1210       switch (option)
1211 	{
1212 	case 0:
1213 	  *(SANE_Word *) value = NELEMS (sod);
1214 	  break;
1215 
1216 	case DC240_OPT_IMAGE_NUMBER:
1217 	  *(SANE_Word *) value = Camera.current_picture_number;
1218 	  break;
1219 
1220 	case DC240_OPT_THUMBS:
1221 	  *(SANE_Word *) value = dc240_opt_thumbnails;
1222 	  break;
1223 
1224 	case DC240_OPT_SNAP:
1225 	  *(SANE_Word *) value = dc240_opt_snap;
1226 	  break;
1227 
1228 	case DC240_OPT_LOWRES:
1229 	  *(SANE_Word *) value = dc240_opt_lowres;
1230 	  break;
1231 
1232 	case DC240_OPT_ERASE:
1233 	  *(SANE_Word *) value = dc240_opt_erase;
1234 	  break;
1235 
1236 	case DC240_OPT_AUTOINC:
1237 	  *(SANE_Word *) value = dc240_opt_autoinc;
1238 	  break;
1239 
1240 	case DC240_OPT_FOLDER:
1241 	  strcpy ((char *) value, (char *) folder_list[current_folder]);
1242 	  break;
1243 
1244 	default:
1245 	  return SANE_STATUS_INVAL;
1246 	}
1247       break;
1248 
1249     case SANE_ACTION_SET_AUTO:
1250       switch (option)
1251 	{
1252 	default:
1253 	  return SANE_STATUS_UNSUPPORTED;	/* We are DUMB */
1254 	}
1255     }
1256 
1257   if (info && action == SANE_ACTION_SET_VALUE)
1258     {
1259       *info = myinfo;
1260       myinfo = 0;
1261     }
1262   return SANE_STATUS_GOOD;
1263 }
1264 
1265 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)1266 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
1267 {
1268   SANE_Int rc = SANE_STATUS_GOOD;
1269 
1270   DBG (127, "sane_get_params called, wid=%d,height=%d\n",
1271        parms.pixels_per_line, parms.lines);
1272 
1273   if (handle != MAGIC || !is_open)
1274     rc = SANE_STATUS_INVAL;	/* Unknown handle ... */
1275 
1276   parms.last_frame = SANE_TRUE;	/* Have no idea what this does */
1277   *params = parms;
1278   DBG (127, "sane_get_params return %d\n", rc);
1279   return rc;
1280 }
1281 
1282 typedef struct
1283 {
1284   struct jpeg_source_mgr pub;
1285   JOCTET *buffer;
1286 }
1287 my_source_mgr;
1288 typedef my_source_mgr *my_src_ptr;
1289 
1290 METHODDEF (void)
jpeg_init_source(j_decompress_ptr __sane_unused__ cinfo)1291 jpeg_init_source (j_decompress_ptr __sane_unused__ cinfo)
1292 {
1293   /* nothing to do */
1294 }
1295 
METHODDEFnull1296 METHODDEF (boolean) jpeg_fill_input_buffer (j_decompress_ptr cinfo)
1297 {
1298 
1299   my_src_ptr src = (my_src_ptr) cinfo->src;
1300 
1301   if (read_data (Camera.fd, src->buffer, 512) == -1)
1302     {
1303       DBG (5, "sane_start: read_data failed\n");
1304       src->buffer[0] = (JOCTET) 0xFF;
1305       src->buffer[1] = (JOCTET) JPEG_EOI;
1306       return FALSE;
1307     }
1308   src->pub.next_input_byte = src->buffer;
1309   src->pub.bytes_in_buffer = 512;
1310 
1311   return TRUE;
1312 }
1313 
jpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)1314 METHODDEF (void) jpeg_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
1315 {
1316 
1317   my_src_ptr src = (my_src_ptr) cinfo->src;
1318 
1319   if (num_bytes > 0)
1320     {
1321       while (num_bytes > (long) src->pub.bytes_in_buffer)
1322 	{
1323 	  num_bytes -= (long) src->pub.bytes_in_buffer;
1324 	  (void) jpeg_fill_input_buffer (cinfo);
1325 	}
1326     }
1327   src->pub.next_input_byte += (size_t) num_bytes;
1328   src->pub.bytes_in_buffer -= (size_t) num_bytes;
1329 }
1330 
1331 static SANE_Byte linebuffer[HIGHRES_WIDTH * 3];
1332 static SANE_Int linebuffer_size = 0;
1333 static SANE_Int linebuffer_index = 0;
1334 
1335 
1336 METHODDEF (void)
jpeg_term_source(j_decompress_ptr __sane_unused__ cinfo)1337 jpeg_term_source (j_decompress_ptr __sane_unused__ cinfo)
1338 {
1339   /* no work necessary here */
1340 }
1341 
1342 SANE_Status
sane_start(SANE_Handle handle)1343 sane_start (SANE_Handle handle)
1344 {
1345   SANE_Int i;
1346 
1347   DBG (127, "sane_start called\n");
1348   if (handle != MAGIC || !is_open ||
1349       (Camera.current_picture_number == 0 && dc240_opt_snap == SANE_FALSE))
1350     return SANE_STATUS_INVAL;	/* Unknown handle ... */
1351 
1352   if (Camera.scanning)
1353     return SANE_STATUS_EOF;
1354 
1355 /*
1356  * This shouldn't normally happen, but we allow it as a special case
1357  * when batch/autoinc are in effect.  The first illegal picture number
1358  * terminates the scan
1359  */
1360   if (Camera.current_picture_number > Camera.pic_taken)
1361     {
1362       return SANE_STATUS_INVAL;
1363     }
1364 
1365   if (dc240_opt_snap)
1366     {
1367       /*
1368        * Don't allow picture unless there is room in the
1369        * camera.
1370        */
1371       if (Camera.pic_left == 0)
1372 	{
1373 	  DBG (3, "No room to store new picture\n");
1374 	  return SANE_STATUS_INVAL;
1375 	}
1376 
1377 
1378       if (snap_pic (Camera.fd) == SANE_STATUS_INVAL)
1379 	{
1380 	  DBG (1, "Failed to snap new picture\n");
1381 	  return SANE_STATUS_INVAL;
1382 	}
1383     }
1384 
1385   if (dc240_opt_thumbnails)
1386     {
1387 
1388       if (send_pck (Camera.fd, thumb_pck) == -1)
1389 	{
1390 	  DBG (1, "sane_start: error: send_pck returned -1\n");
1391 	  return SANE_STATUS_INVAL;
1392 	}
1393 
1394       /* Picture size should have been set when thumbnails were
1395        * selected.  But, check just in case
1396        */
1397 
1398       if (parms.pixels_per_line != 160 ||
1399 	  parms.bytes_per_line != 160 * 3 || parms.lines != 120)
1400 	{
1401 	  DBG (1, "sane_start: fixme! thumbnail image size is wrong\n");
1402 	  return SANE_STATUS_INVAL;
1403 	}
1404     }
1405   else
1406     {
1407       if (send_pck (Camera.fd, pic_pck) == -1)
1408 	{
1409 	  DBG (1, "sane_start: error: send_pck returned -1\n");
1410 	  return SANE_STATUS_INVAL;
1411 	}
1412 
1413     }
1414   {
1415     my_src_ptr src;
1416 
1417     struct jpeg_error_mgr jerr;
1418     SANE_Int n;
1419     SANE_Char f[] = "sane_start";
1420     SANE_Char path[256];
1421     struct cam_dirlist *e;
1422     name_buf[0] = 0x80;
1423 
1424     for (n = 1, e = dir_head; e; n++, e = e->next)
1425       {
1426 	if (n == Camera.current_picture_number)
1427 	  break;
1428       }
1429 
1430     strcpy (path, "\\PCCARD\\DCIM\\");
1431     strcat (path, (char *) folder_list[current_folder]);
1432     strcat (path, "\\");
1433     strcat (path, e->name);
1434     path[strlen (path) - 3] = '\0';
1435     strcat (path, ".JPG");
1436 
1437     DBG (9, "%s: pic to read is %d name is %s\n", f, n, path);
1438 
1439     strcpy ((char *) &name_buf[1], path);
1440     for (i = 49; i <= 56; i++)
1441       {
1442 	name_buf[i] = 0xff;
1443       }
1444 
1445     if (send_data (name_buf) == -1)
1446       {
1447 	DBG (1, "%s: error: send_data returned -1\n", f);
1448 	return SANE_STATUS_INVAL;
1449       }
1450 
1451     cinfo.err = jpeg_std_error (&jerr);
1452     jpeg_create_decompress (&cinfo);
1453 
1454     cinfo.src =
1455       (struct jpeg_source_mgr *) (*cinfo.mem->
1456 				  alloc_small) ((j_common_ptr) & cinfo,
1457 						JPOOL_PERMANENT,
1458 						sizeof (my_source_mgr));
1459     src = (my_src_ptr) cinfo.src;
1460 
1461     src->buffer = (JOCTET *) (*cinfo.mem->alloc_small) ((j_common_ptr) &
1462 							cinfo,
1463 							JPOOL_PERMANENT,
1464 							1024 *
1465 							sizeof (JOCTET));
1466     src->pub.init_source = jpeg_init_source;
1467     src->pub.fill_input_buffer = jpeg_fill_input_buffer;
1468     src->pub.skip_input_data = jpeg_skip_input_data;
1469     src->pub.resync_to_restart = jpeg_resync_to_restart;	/* default */
1470     src->pub.term_source = jpeg_term_source;
1471     src->pub.bytes_in_buffer = 0;
1472     src->pub.next_input_byte = NULL;
1473 
1474     (void) jpeg_read_header (&cinfo, TRUE);
1475     dest_mgr = sanei_jpeg_jinit_write_ppm (&cinfo);
1476     (void) jpeg_start_decompress (&cinfo);
1477 
1478     linebuffer_size = 0;
1479     linebuffer_index = 0;
1480   }
1481 
1482   Camera.scanning = SANE_TRUE;	/* don't overlap scan requests */
1483 
1484   return SANE_STATUS_GOOD;
1485 }
1486 
1487 SANE_Status
sane_read(SANE_Handle __sane_unused__ handle, SANE_Byte * data, SANE_Int max_length, SANE_Int * length)1488 sane_read (SANE_Handle __sane_unused__ handle, SANE_Byte * data,
1489 	   SANE_Int max_length, SANE_Int * length)
1490 {
1491   SANE_Int lines = 0;
1492   SANE_Char filename_buf[256];
1493 
1494   if (Camera.scanning == SANE_FALSE)
1495     {
1496       return SANE_STATUS_INVAL;
1497     }
1498 
1499   /* If there is anything in the buffer, satisfy the read from there */
1500   if (linebuffer_size && linebuffer_index < linebuffer_size)
1501     {
1502       *length = linebuffer_size - linebuffer_index;
1503 
1504       if (*length > max_length)
1505 	{
1506 	  *length = max_length;
1507 	}
1508       memcpy (data, linebuffer + linebuffer_index, *length);
1509       linebuffer_index += *length;
1510 
1511       return SANE_STATUS_GOOD;
1512     }
1513 
1514   if (cinfo.output_scanline >= cinfo.output_height)
1515     {
1516       *length = 0;
1517 
1518       /* clean up comms with the camera */
1519       if (end_of_data (Camera.fd) == -1)
1520 	{
1521 	  DBG (1, "sane_read: error: end_of_data returned -1\n");
1522 	  return SANE_STATUS_INVAL;
1523 	}
1524       if (dc240_opt_erase)
1525 	{
1526 	  DBG (127, "sane_read bp%d, erase image\n", __LINE__);
1527 	  if (erase (Camera.fd) == -1)
1528 	    {
1529 	      DBG (1, "Failed to erase memory\n");
1530 	      return SANE_STATUS_INVAL;
1531 	    }
1532 	  Camera.pic_taken--;
1533 	  Camera.pic_left++;
1534 	  Camera.current_picture_number = Camera.pic_taken;
1535 	  image_range.max--;
1536 
1537 	  myinfo |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1538 	  strcpy ((char *) filename_buf,
1539 		  strrchr ((char *) name_buf + 1, '\\') + 1);
1540 	  strcpy (strrchr ((char *) filename_buf, '.'), "JPG");
1541 	  dir_delete ((SANE_String) filename_buf);
1542 
1543 	}
1544       if (dc240_opt_autoinc)
1545 	{
1546 	  if (Camera.current_picture_number <= Camera.pic_taken)
1547 	    {
1548 	      Camera.current_picture_number++;
1549 
1550 	      myinfo |= SANE_INFO_RELOAD_PARAMS;
1551 
1552 	      /* get the image's resolution */
1553 	      set_res (Camera.Pictures[Camera.current_picture_number - 1].
1554 		       low_res);
1555 	    }
1556 	  DBG (4, "Increment count to %d (total %d)\n",
1557 	       Camera.current_picture_number, Camera.pic_taken);
1558 	}
1559       return SANE_STATUS_EOF;
1560     }
1561 
1562 /* XXX - we should read more than 1 line at a time here */
1563   lines = 1;
1564   (void) jpeg_read_scanlines (&cinfo, dest_mgr->buffer, lines);
1565   (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, lines, (char *) linebuffer);
1566 
1567   *length = cinfo.output_width * cinfo.output_components * lines;
1568   linebuffer_size = *length;
1569   linebuffer_index = 0;
1570 
1571   if (*length > max_length)
1572     {
1573       *length = max_length;
1574     }
1575   memcpy (data, linebuffer + linebuffer_index, *length);
1576   linebuffer_index += *length;
1577 
1578   return SANE_STATUS_GOOD;
1579 }
1580 
1581 void
sane_cancel(SANE_Handle __sane_unused__ handle)1582 sane_cancel (SANE_Handle __sane_unused__ handle)
1583 {
1584   unsigned char cancel_byte[] = { 0xe4 };
1585 
1586   if (Camera.scanning)
1587     {
1588 
1589       /* Flush any pending data from the camera before continuing */
1590       {
1591 	SANE_Int n;
1592 	SANE_Char flush[1024];
1593 	do
1594 	  {
1595 	    sleep (1);
1596 	    n = read (Camera.fd, flush, 1024);
1597 	    if (n > 0)
1598 	      {
1599 		DBG (127, "%s: flushed %d bytes\n", "sane_cancel", n);
1600 	      }
1601 	    else
1602 	      {
1603 		DBG (127, "%s: nothing to flush\n", "sane_cancel");
1604 	      }
1605 	  }
1606 	while (n > 0);
1607       }
1608 
1609       if (cinfo.output_scanline < cinfo.output_height)
1610 	{
1611 	  write (Camera.fd, cancel_byte, 1);
1612 	}
1613 
1614       Camera.scanning = SANE_FALSE;	/* done with scan */
1615     }
1616   else
1617     DBG (4, "sane_cancel: not scanning - nothing to do\n");
1618 }
1619 
1620 SANE_Status
sane_set_io_mode(SANE_Handle __sane_unused__ handle, SANE_Bool __sane_unused__ non_blocking)1621 sane_set_io_mode (SANE_Handle __sane_unused__ handle, SANE_Bool
1622 		  __sane_unused__ non_blocking)
1623 {
1624   /* sane_set_io_mode() is only valid during a scan */
1625   if (Camera.scanning)
1626     {
1627       if (non_blocking == SANE_FALSE)
1628 	{
1629 	  return SANE_STATUS_GOOD;
1630 	}
1631       else
1632 	{
1633 	  return SANE_STATUS_UNSUPPORTED;
1634 	}
1635     }
1636   else
1637     {
1638       /* We aren't currently scanning */
1639       return SANE_STATUS_INVAL;
1640     }
1641 }
1642 
1643 SANE_Status
sane_get_select_fd(SANE_Handle __sane_unused__ handle, SANE_Int __sane_unused__ * fd)1644 sane_get_select_fd (SANE_Handle __sane_unused__ handle, SANE_Int __sane_unused__ * fd)
1645 {
1646   return SANE_STATUS_UNSUPPORTED;
1647 }
1648 
1649 /*
1650  * get_pictures_info - load information about all pictures currently in
1651  *			camera:  Mainly the mapping of picture number
1652  *			to picture name, and the resolution of each picture.
1653  */
1654 static PictureInfo *
get_pictures_info(void)1655 get_pictures_info (void)
1656 {
1657   SANE_Char f[] = "get_pictures_info";
1658   SANE_Char path[256];
1659   SANE_Int num_pictures;
1660   SANE_Int p;
1661   PictureInfo *pics;
1662 
1663   if (Camera.Pictures)
1664     {
1665       free (Camera.Pictures);
1666       Camera.Pictures = NULL;
1667     }
1668 
1669   strcpy (path, "\\PCCARD\\DCIM\\");
1670   strcat (path, (char *) folder_list[current_folder]);
1671   strcat (path, "\\*.*");
1672 
1673   num_pictures = read_dir (path);
1674   if (num_pictures != Camera.pic_taken)
1675     {
1676       DBG (2,
1677 	   "%s: warning: Number of pictures in directory (%d) doesn't match camera status table (%d).  Using directory count\n",
1678 	   f, num_pictures, Camera.pic_taken);
1679       Camera.pic_taken = num_pictures;
1680       image_range.max = num_pictures;
1681     }
1682 
1683   if ((pics = (PictureInfo *) malloc (Camera.pic_taken *
1684 				      sizeof (PictureInfo))) == NULL)
1685     {
1686       DBG (1, "%s: error: allocate memory for pictures array\n", f);
1687       return NULL;
1688     }
1689 
1690   for (p = 0; p < Camera.pic_taken; p++)
1691     {
1692       if (get_picture_info (pics + p, p) == -1)
1693 	{
1694 	  free (pics);
1695 	  return NULL;
1696 	}
1697     }
1698 
1699   Camera.Pictures = pics;
1700   return pics;
1701 }
1702 
1703 static SANE_Int
get_picture_info(PictureInfo * pic, SANE_Int p)1704 get_picture_info (PictureInfo * pic, SANE_Int p)
1705 {
1706 
1707   SANE_Char f[] = "get_picture_info";
1708   SANE_Int n;
1709   struct cam_dirlist *e;
1710 
1711   DBG (4, "%s: info for pic #%d\n", f, p);
1712 
1713   for (n = 0, e = dir_head; e && n < p; n++, e = e->next)
1714     ;
1715 
1716   DBG (4, "Name is %s\n", e->name);
1717 
1718   read_info (e->name);
1719 
1720   /* Validate picture info
1721    * byte 0 - 1 == picture info
1722    * byte 1 - 5 == DC240 Camera
1723    * byte 2 - 3 == JFIF file
1724    * byte 6 - 0 == Image is complete
1725    */
1726   if (info_buf[0] != 1 || info_buf[1] != 5 || info_buf[2] != 3
1727       || info_buf[6] != 0)
1728     {
1729 
1730       DBG (1, "%s: error: Image %s does not come from a DC-240.\n", f,
1731 	   e->name);
1732       return -1;
1733     }
1734 
1735   pic->low_res = info_buf[3] == 0 ? SANE_TRUE : SANE_FALSE;
1736 
1737   /*
1738    * byte 12 - Year MSB
1739    * byte 13 - Year LSB
1740    * byte 14 - Month
1741    * byte 15 - Day
1742    * byte 16 - Hour
1743    * byte 17 - Minute
1744    * byte 18 - Second
1745    */
1746   DBG (1, "Picture %d taken %02d/%02d/%02d %02d:%02d:%02d\n",
1747        p, info_buf[14],
1748        info_buf[15], (info_buf[12] << 8) + info_buf[13],
1749        info_buf[16], info_buf[17], info_buf[18]);
1750 
1751   return 0;
1752 }
1753 
1754 /*
1755  * snap_pic - take a picture (and call get_pictures_info to re-create
1756  *		the directory related data structures)
1757  */
1758 static SANE_Status
snap_pic(SANE_Int fd)1759 snap_pic (SANE_Int fd)
1760 {
1761 
1762   SANE_Char f[] = "snap_pic";
1763 
1764 #if 0
1765 /* Just checking... It looks like after snapping the picture, we
1766  * get two "d1" ACK responses back, even though the documentation seems
1767  * to say that there should only be one.  I thought the first one could
1768  * have been an unread response from an earlier command, so I
1769  * I tried flushing any data here.  Still seeing the multiple
1770  * d1 bytes, however...
1771  */
1772   {
1773     SANE_Int n;
1774     SANE_Char flush[10];
1775     n = read (Camera.fd, flush, 10);
1776     if (n > 0)
1777       {
1778 	DBG (127, "%s: flushed %d bytes\n", f, n);
1779       }
1780     else
1781       {
1782 	DBG (127, "%s: nothing to flush\n", f);
1783       }
1784   }
1785 #endif
1786 
1787   /* make sure camera is set to our settings state */
1788   if (change_res (Camera.fd, dc240_opt_lowres) == -1)
1789     {
1790       DBG (1, "%s: Failed to set resolution\n", f);
1791       return SANE_STATUS_INVAL;
1792     }
1793 
1794   /* take the picture */
1795   if (send_pck (fd, shoot_pck) == -1)
1796     {
1797       DBG (1, "%s: error: send_pck returned -1\n", f);
1798       return SANE_STATUS_INVAL;
1799     }
1800   else
1801     {
1802       if (end_of_data (Camera.fd) == -1)
1803 	{
1804 	  DBG (1, "%s: error: end_of_data returned -1\n", f);
1805 	  return SANE_STATUS_INVAL;
1806 	}
1807     }
1808   Camera.pic_taken++;
1809   Camera.pic_left--;
1810   Camera.current_picture_number = Camera.pic_taken;
1811   image_range.max++;
1812   sod[DC240_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE;
1813 
1814   /* add this one to the Pictures array */
1815 
1816   if (get_pictures_info () == NULL)
1817     {
1818       DBG (1, "%s: Failed to get new picture info\n", f);
1819       /* XXX - I guess we should try to erase the image here */
1820       return SANE_STATUS_INVAL;
1821     }
1822 
1823   return SANE_STATUS_GOOD;
1824 }
1825 
1826 /*
1827  * read_dir - read a list of file names from the specified directory
1828  * 		and create a linked list of file name entries in
1829  *		alphabetical order.  The first entry in the list will
1830  *		be "picture #1", etc.
1831  */
1832 static SANE_Int
read_dir(SANE_String dir)1833 read_dir (SANE_String dir)
1834 {
1835   SANE_Int retval = 0;
1836   SANE_Byte buf[256];
1837   SANE_Byte *next_buf;
1838   SANE_Int i, entries;
1839   SANE_Byte r = 0xf0;		/* prime the loop with a "camera busy" */
1840   SANE_Char f[] = "read_dir";
1841   struct cam_dirlist *e, *next;
1842 
1843   /* Free up current list */
1844   for (e = dir_head; e; e = next)
1845     {
1846       DBG (127, "%s: free entry %s\n", f, e->name);
1847       next = e->next;
1848       free (e);
1849     }
1850   dir_head = NULL;
1851 
1852   if (send_pck (Camera.fd, read_dir_pck) == -1)
1853     {
1854       DBG (1, "%s: error: send_pck returned -1\n", f);
1855       return -1;
1856     }
1857 
1858   buf[0] = 0x80;
1859   strcpy ((char *) &buf[1], dir);
1860   for (i = 49; i <= 56; i++)
1861     {
1862       buf[i] = 0xff;
1863     }
1864 
1865   if (send_data (buf) == -1)
1866     {
1867       DBG (1, "%s: error: send_data returned -1\n", f);
1868       return -1;
1869     }
1870 
1871 
1872   if (read_data (Camera.fd, (SANE_Byte *) & dir_buf2, 256) == -1)
1873     {
1874       DBG (1, "%s: error: read_data returned -1\n", f);
1875       return -1;
1876     }
1877 
1878   entries = (dir_buf2[0] << 8) + dir_buf2[1];
1879   DBG (127, "%s: result of dir read is %x, number of entries=%d\n", f, r,
1880        entries);
1881 
1882   if (entries > 1001)
1883     {
1884       DBG (1, "%s: error: more than 999 pictures not supported yet\n", f);
1885       return -1;
1886     }
1887 
1888   /* Determine if it's time to read another 256 byte buffer from the camera */
1889 
1890   next_buf = ((SANE_Byte *) & dir_buf2) + 256;
1891   while (dir_buf2 + 2 + CAMDIRENTRYSIZE * entries >= (SANE_Byte *) next_buf)
1892     {
1893 
1894       DBG (127, "%s: reading additional directory buffer\n", f);
1895       if (read_data (Camera.fd, next_buf, 256) == -1)
1896 	{
1897 	  DBG (1, "%s: error: read_data returned -1\n", f);
1898 	  return -1;
1899 	}
1900       next_buf += 256;
1901     }
1902 
1903   for (i = 0; i < entries; i++)
1904 
1905     {
1906       /* Hack: I don't know what attr is used for, so setting it
1907        * to zero is a convenient way to put in the null terminator
1908        */
1909       get_attr (i) = 0;
1910       DBG (127, "%s: entry=%s\n", f, get_name (i));
1911 
1912       if ((get_name (i))[0] == '.')
1913 	{
1914 	  continue;
1915 	}
1916 
1917       if (dir_insert
1918 	  ((struct cam_dirent *) &dir_buf2[2 + CAMDIRENTRYSIZE * i]) != 0)
1919 	{
1920 	  DBG (1, "%s: error: failed to insert dir entry\n", f);
1921 	  return -1;
1922 	}
1923       retval++;
1924     }
1925 
1926   if (end_of_data (Camera.fd) == -1)
1927     {
1928       DBG (1, "%s: error: end_of_data returned -1\n", f);
1929       return -1;
1930     }
1931 
1932   return retval;
1933 }
1934 
1935 /*
1936  * read_info - read the info block from camera for the specified file
1937  */
1938 static SANE_Int
read_info(SANE_String fname)1939 read_info (SANE_String fname)
1940 {
1941   SANE_Byte buf[256];
1942   SANE_Int i;
1943   SANE_Char f[] = "read_info";
1944   SANE_Char path[256];
1945 
1946   strcpy (path, "\\PCCARD\\DCIM\\");
1947   strcat (path, (char *) folder_list[current_folder]);
1948   strcat (path, "\\");
1949   strcat (path, fname);
1950   path[strlen (path) - 3] = '\0';
1951   strcat (path, ".JPG");
1952 
1953   if (send_pck (Camera.fd, pic_info_pck) == -1)
1954     {
1955       DBG (1, "%s: error: send_pck returned -1\n", f);
1956       return SANE_STATUS_INVAL;
1957     }
1958 
1959   buf[0] = 0x80;
1960   strcpy ((char *) &buf[1], path);
1961   for (i = 49; i <= 56; i++)
1962     {
1963       buf[i] = 0xff;
1964     }
1965 
1966   if (send_data (buf) == -1)
1967     {
1968       DBG (1, "%s: error: send_data returned -1\n", f);
1969       return SANE_STATUS_INVAL;
1970     }
1971 
1972   if (read_data (Camera.fd, info_buf, 256) != 0)
1973     {
1974       DBG (1, "%s: error: Failed in read_data\n", f);
1975       return -1;
1976     }
1977 
1978   DBG (9, "%s: data type=%d, cam type=%d, file type=%d\n", f,
1979        info_buf[0], info_buf[1], info_buf[2]);
1980 
1981   if (end_of_data (Camera.fd) == -1)
1982     {
1983       DBG (1, "%s: error: end_of_data returned -1\n", f);
1984       return -1;
1985     }
1986 
1987   return 0;
1988 }
1989 
1990 
1991 /*
1992  * send_data - Send a data block - assumes all data blocks to camera
1993  *		are 60 bytes long
1994  */
1995 
1996 static SANE_Int
send_data(SANE_Byte * buf)1997 send_data (SANE_Byte * buf)
1998 {
1999   SANE_Byte r = 0xf0;		/* prime the loop with a "camera busy" */
2000   SANE_Int i, n;
2001   SANE_Byte csum;
2002   SANE_Char f[] = "send_data";
2003 
2004   for (i = 1, csum = 0; i < 59; i++)
2005     {
2006       csum ^= buf[i];
2007     }
2008   buf[59] = csum;
2009   DBG (127, "%s: about to send data block\n", f);
2010 
2011   /* keep trying if camera says it's busy */
2012   while (r == 0xf0)
2013     {
2014       if (write (Camera.fd, (char *) buf, 60) != 60)
2015 	{
2016 	  DBG (1, "%s: error: write returned -1\n", f);
2017 	  return -1;
2018 	}
2019 
2020       /* need to wait before we read command result */
2021 #ifdef HAVE_USLEEP
2022       usleep (cmdrespause);
2023 #else
2024       sleep (1);
2025 #endif
2026 
2027       if ((n = read (Camera.fd, (char *) &r, 1)) != 1)
2028 	{
2029 	  DBG (1, "%s: error: read returned -1\n", f);
2030 	  return -1;
2031 	}
2032     }
2033 
2034   if (r != 0xd2)
2035     {
2036       DBG (1, "%s: error: bad response to send_data (%d)\n", f, r);
2037       return -1;
2038     }
2039 
2040   return 0;
2041 }
2042 
2043 /*
2044  * dir_insert - Add (in alphabetical order) a directory entry to the
2045  * 		current list of entries.
2046  */
2047 static SANE_Int
dir_insert(struct cam_dirent *entry)2048 dir_insert (struct cam_dirent *entry)
2049 {
2050   struct cam_dirlist *cur, *e;
2051 
2052   cur = (struct cam_dirlist *) malloc (sizeof (struct cam_dirlist));
2053   if (cur == NULL)
2054     {
2055       DBG (1, "dir_insert: error: could not malloc entry\n");
2056       return -1;
2057     }
2058 
2059   strcpy (cur->name, entry->name);
2060   DBG (127, "dir_insert: name is %s\n", cur->name);
2061 
2062   cur->next = NULL;
2063 
2064   if (dir_head == NULL)
2065     {
2066       dir_head = cur;
2067     }
2068   else if (strcmp (cur->name, dir_head->name) < 0)
2069     {
2070       cur->next = dir_head;
2071       dir_head = cur;
2072       return 0;
2073     }
2074   else
2075     {
2076       for (e = dir_head; e->next; e = e->next)
2077 	{
2078 	  if (strcmp (e->next->name, cur->name) > 0)
2079 	    {
2080 	      cur->next = e->next;
2081 	      e->next = cur;
2082 	      return 0;
2083 	    }
2084 	}
2085       e->next = cur;
2086     }
2087   return 0;
2088 }
2089 
2090 /*
2091  *  dir_delete - Delete a directory entry from the linked list of file
2092  * 		names
2093  */
2094 static SANE_Int
dir_delete(SANE_String fname)2095 dir_delete (SANE_String fname)
2096 {
2097   struct cam_dirlist *cur, *e;
2098 
2099   DBG (127, "dir_delete:  %s\n", fname);
2100 
2101   if (strcmp (fname, dir_head->name) == 0)
2102     {
2103       cur = dir_head;
2104       dir_head = dir_head->next;
2105       free (cur);
2106       return 0;
2107     }
2108 
2109   for (e = dir_head; e->next; e = e->next)
2110     {
2111       if (strcmp (fname, e->next->name) == 0)
2112 	{
2113 	  cur = e->next;
2114 	  e->next = e->next->next;
2115 	  free (cur);
2116 	  return (0);
2117 	}
2118     }
2119   DBG (1, "dir_delete: Couldn't find entry %s in dir list\n", fname);
2120   return -1;
2121 }
2122 
2123 /*
2124  *  set_res - set picture size depending on resolution settings
2125  */
2126 static void
set_res(SANE_Int lowres)2127 set_res (SANE_Int lowres)
2128 {
2129   if (dc240_opt_thumbnails)
2130     {
2131       parms.bytes_per_line = 160 * 3;
2132       parms.pixels_per_line = 160;
2133       parms.lines = 120;
2134     }
2135   else if (lowres)
2136     {
2137       parms.bytes_per_line = LOWRES_WIDTH * 3;
2138       parms.pixels_per_line = LOWRES_WIDTH;
2139       parms.lines = LOWRES_HEIGHT;
2140     }
2141   else
2142     {
2143       parms.bytes_per_line = HIGHRES_WIDTH * 3;
2144       parms.pixels_per_line = HIGHRES_WIDTH;
2145       parms.lines = HIGHRES_HEIGHT;
2146     }
2147 }
2148