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