1 /* Please note! Although intended to support multiple camera types
2 * it's been tested with only cameras I have access to: the Kodak DC240
3 * and the Directory Browse "camera." I'm very interested
4 * in learning what it would take to support more cameras. In
5 * particular, the current incarnation will only support cameras
6 * that directly generate jpeg files.
7 *
8 * Please report successes or failures using this backend!
9 *
10 * However, having said that, I've already found it to be quite useful
11 * even in its current form - one reason is that gphoto2 provides access
12 * to the camera via USB which is not supported by the regular DC240
13 * backend and is dramatically faster than the serial port.
14 */
15
16 /***************************************************************************
17 * _S_A_N_E - Scanner Access Now Easy.
18
19 gphoto2.c
20
21 03/12/01 - Peter Fales
22
23 Based on the dc210 driver, (C) 1998 Brian J. Murrell (which is
24 based on dc25 driver (C) 1998 by Peter Fales)
25
26 This file (C) 2001 by Peter Fales
27
28 This file is part of the SANE package.
29
30 This program is free software; you can redistribute it and/or
31 modify it under the terms of the GNU General Public License as
32 published by the Free Software Foundation; either version 2 of the
33 License, or (at your option) any later version.
34
35 This program is distributed in the hope that it will be useful, but
36 WITHOUT ANY WARRANTY; without even the implied warranty of
37 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
38 General Public License for more details.
39
40 You should have received a copy of the GNU General Public License
41 along with this program. If not, see <https://www.gnu.org/licenses/>.
42
43 As a special exception, the authors of SANE give permission for
44 additional uses of the libraries contained in this release of SANE.
45
46 The exception is that, if you link a SANE library with other files
47 to produce an executable, this does not by itself cause the
48 resulting executable to be covered by the GNU General Public
49 License. Your use of that executable is in no way restricted on
50 account of linking the SANE library code into it.
51
52 This exception does not, however, invalidate any other reasons why
53 the executable file might be covered by the GNU General Public
54 License.
55
56 If you submit changes to SANE to the maintainers to be included in
57 a subsequent release, you agree by submitting the changes that
58 those changes may be distributed with this exception intact.
59
60 If you write modifications of your own for SANE, it is your choice
61 whether to permit this exception to apply to your modifications.
62 If you do not wish that, delete this exception notice.
63
64 ***************************************************************************
65
66 This file implements a SANE backend for digital cameras
67 supported by the gphoto2 libraries.
68
69 THIS IS EXTREMELY ALPHA CODE! USE AT YOUR OWN RISK!!
70
71 (feedback to: gphoto2-devel@fales-lorenz.net)
72
73 This backend is based somewhat on the dc25 backend included in this
74 package by Peter Fales, and the dc210 backend by Brian J. Murrell
75
76 ***************************************************************************/
77
78 #include "../include/sane/config.h"
79
80 #include <stdlib.h>
81 #include <string.h>
82 #include <stdio.h>
83 #include <unistd.h>
84 #include <fcntl.h>
85 #include <limits.h>
86 #include "../include/sane/sanei_jpeg.h"
87 #include <sys/ioctl.h>
88
89 #include "../include/sane/sane.h"
90 #include "../include/sane/sanei.h"
91 #include "../include/sane/saneopts.h"
92
93 #define BACKEND_NAME gphoto2
94 #include "../include/sane/sanei_backend.h"
95
96 /* PSF 1/12/02 - gphoto2.h does a #include of config.h. We don't have
97 * config.h by that name (we call it sane/config.h), so the #undef of
98 * HAVE_CONFIG_H will cause it to skip that.
99 */
100 #undef HAVE_CONFIG_H
101 #include "gphoto2.h"
102
103
104 #include <gphoto2-camera.h>
105 #include <gphoto2-port-log.h>
106
107 #define CHECK_RET(f) {int res = f; if (res < 0) {DBG (1,"ERROR: %s\n", gp_result_as_string (res)); return (SANE_STATUS_INVAL);}}
108
109 #ifndef PATH_MAX
110 # define PATH_MAX 1024
111 #endif
112
113 #define MAGIC (void *)0xab730324
114 #define GPHOTO2_CONFIG_FILE "gphoto2.conf"
115
116 static SANE_Bool is_open = 0;
117
118 /* Options selected by frontend: */
119 static SANE_Bool gphoto2_opt_thumbnails; /* Read thumbnails */
120 static SANE_Bool gphoto2_opt_snap; /* Take new picture */
121 static SANE_Bool gphoto2_opt_lowres; /* Set low resolution */
122 static SANE_Bool gphoto2_opt_erase; /* Erase after downloading */
123 static SANE_Bool gphoto2_opt_autoinc; /* Increment image number */
124 static SANE_Bool dumpinquiry; /* Dump status info */
125
126 /* Used for jpeg decompression */
127 static struct jpeg_decompress_struct cinfo;
128 static djpeg_dest_ptr dest_mgr = NULL;
129
130 static SANE_Int highres_height = 960, highres_width = 1280;
131 static SANE_Int thumb_height = 120, thumb_width = 160;
132 static SANE_String TopFolder; /* Fixed part of path strings */
133 static SANE_Int SubDirs = 1; /* Search for Sub directories */
134
135 static GPHOTO2 Cam_data; /* Other camera data */
136
137 static SANE_Range image_range = {
138 0,
139 0,
140 0
141 };
142
143 static SANE_String *folder_list;
144 static SANE_Int current_folder = 0;
145
146 static SANE_Option_Descriptor sod[] = {
147 {
148 SANE_NAME_NUM_OPTIONS,
149 SANE_TITLE_NUM_OPTIONS,
150 SANE_DESC_NUM_OPTIONS,
151 SANE_TYPE_INT,
152 SANE_UNIT_NONE,
153 sizeof (SANE_Word),
154 SANE_CAP_SOFT_DETECT,
155 SANE_CONSTRAINT_NONE,
156 {NULL}
157 }
158 ,
159
160 #define GPHOTO2_OPT_IMAGE_SELECTION 1
161 {
162 "",
163 "Image Selection",
164 "Selection of the image to load.",
165 SANE_TYPE_GROUP,
166 SANE_UNIT_NONE,
167 0,
168 0,
169 SANE_CONSTRAINT_NONE,
170 {NULL}
171 }
172 ,
173
174 #define GPHOTO2_OPT_FOLDER 2
175 {
176 "folder",
177 "Folder",
178 "Select folder within camera",
179 SANE_TYPE_STRING,
180 SANE_UNIT_NONE,
181 256,
182 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
183 SANE_CONSTRAINT_STRING_LIST,
184 {NULL}
185 }
186 ,
187
188 #define GPHOTO2_OPT_IMAGE_NUMBER 3
189 {
190 "image",
191 "Image Number",
192 "Select Image Number to load from camera",
193 SANE_TYPE_INT,
194 SANE_UNIT_NONE,
195 4,
196 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
197 SANE_CONSTRAINT_RANGE,
198 {(SANE_String_Const *) & image_range} /* this is ANSI conformant! */
199 }
200 ,
201
202 #define GPHOTO2_OPT_THUMBS 4
203 {
204 "thumbs",
205 "Load Thumbnail",
206 "Load the image as thumbnail.",
207 SANE_TYPE_BOOL,
208 SANE_UNIT_NONE,
209 sizeof (SANE_Word),
210 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
211 SANE_CONSTRAINT_NONE,
212 {NULL}
213 }
214 ,
215
216 #define GPHOTO2_OPT_SNAP 5
217 {
218 "snap",
219 "Snap new picture",
220 "Take new picture and download it",
221 SANE_TYPE_BOOL,
222 SANE_UNIT_NONE,
223 sizeof (SANE_Word),
224 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT /* | SANE_CAP_ADVANCED */ ,
225 SANE_CONSTRAINT_NONE,
226 {NULL}
227 }
228 ,
229
230 #define GPHOTO2_OPT_LOWRES 6
231 {
232 "lowres",
233 "Low Resolution",
234 "Resolution of new picture or selected image (must be manually specified)",
235 SANE_TYPE_BOOL,
236 SANE_UNIT_NONE,
237 sizeof (SANE_Word),
238 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE /* Until we figure out how to support it */
239 /* | SANE_CAP_ADVANCED */ ,
240 SANE_CONSTRAINT_NONE,
241 {NULL}
242 }
243 ,
244
245 #define GPHOTO2_OPT_ERASE 7
246 {
247 "erase",
248 "Erase",
249 "Erase the picture after downloading",
250 SANE_TYPE_BOOL,
251 SANE_UNIT_NONE,
252 sizeof (SANE_Word),
253 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
254 SANE_CONSTRAINT_NONE,
255 {NULL}
256 }
257 ,
258
259 #define GPHOTO2_OPT_DEFAULT 8
260 {
261 "default-enhancements",
262 "Defaults",
263 "Set default values for enhancement controls.",
264 SANE_TYPE_BUTTON,
265 SANE_UNIT_NONE,
266 0,
267 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
268 SANE_CONSTRAINT_NONE,
269 {NULL}
270 }
271 ,
272
273 #define GPHOTO2_OPT_INIT_GPHOTO2 9
274 {
275 "camera-init",
276 "Re-establish Communications",
277 "Re-establish communications with camera (in case of timeout, etc.)",
278 SANE_TYPE_BUTTON,
279 SANE_UNIT_NONE,
280 0,
281 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
282 SANE_CONSTRAINT_NONE,
283 {NULL}
284 }
285 ,
286
287 #define GPHOTO2_OPT_AUTOINC 10
288 {
289 "autoinc",
290 "Auto Increment",
291 "Increment image number after each scan",
292 SANE_TYPE_BOOL,
293 SANE_UNIT_NONE,
294 sizeof (SANE_Word),
295 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED,
296 SANE_CONSTRAINT_NONE,
297 {NULL}
298 }
299 ,
300
301
302 };
303
304 static SANE_Parameters parms = {
305 SANE_FRAME_RGB,
306 0,
307 0, /* Number of bytes returned per scan line: */
308 0, /* Number of pixels per scan line. */
309 0, /* Number of lines for the current scan. */
310 8, /* Number of bits per sample. */
311 };
312
313
314 CameraList *dir_list;
315 Camera *camera;
316
317 /* Buffer to hold line currently being processed by sane_read */
318 static SANE_Byte *linebuffer = NULL;
319 static SANE_Int linebuffer_size = 0;
320 static SANE_Int linebuffer_index = 0;
321
322 /* used for setting up commands */
323 static SANE_Char cmdbuf[256];
324
325 /* Structures used by gphoto2 API */
326 static CameraAbilities abilities;
327 static CameraFile *data_file;
328 static const unsigned char *data_ptr;
329 static unsigned long data_file_total_size, data_file_current_index;
330
331 static SANE_Int hack_fd;
332
333 #include <sys/time.h>
334 #include <unistd.h>
335
336 /* Device select/open/close */
337
338 static SANE_Device dev[] = {
339 {
340 "0",
341 "Gphoto2",
342 "Supported",
343 "still camera"},
344 };
345
346 static const SANE_Device *devlist[] = {
347 dev + 0, 0
348 };
349
350 /*
351 * debug_func - called for gphoto2 debugging output (if enabled)
352 */
353 static void
354 #ifdef GPLOGFUNC_NO_VARGS
debug_func(GPLogLevel level,const char * domain,const char * message,void __sane_unused__ * data)355 debug_func (GPLogLevel level, const char *domain, const char *message,
356 void __sane_unused__ * data)
357 #else
358 debug_func (GPLogLevel level, const char *domain, const char *format,
359 va_list args, void __sane_unused__ * data)
360 #endif
361 {
362 if (level == GP_LOG_ERROR)
363 DBG (0, "%s(ERROR): ", domain);
364 else
365 DBG (0, "%s(%i): ", domain, level);
366 #ifdef GPLOGFUNC_NO_VARGS
367 DBG (0, "%s", message);
368 #else
369 sanei_debug_msg (0, DBG_LEVEL, STRINGIFY (BACKEND_NAME), format, args);
370 #endif
371 DBG (0, "\n");
372 }
373
374 /*
375 * init_gphoto2() - Initialize interface to camera using gphoto2 API
376 */
377 static SANE_Int
init_gphoto2(void)378 init_gphoto2 (void)
379 {
380 CameraList *list;
381 GPPortInfoList *il;
382 GPPortInfo info;
383 SANE_Int n, m, port;
384 CameraAbilitiesList *al;
385
386 gp_log (GP_LOG_VERBOSE, "SANE", "Initializing\n");
387
388 if (!Cam_data.camera_name)
389 {
390 DBG (0, "init_gphoto2: Camera name not specified in config file\n");
391 return SANE_STATUS_INVAL;
392 }
393
394 if (camera)
395 {
396 /*
397 * We get here if re-initializing the camera: either because
398 * the user clicked the "re-establish" button, or we need to
399 * recalculate the number of photos after taking a picture.
400 * We must release the old camera before starting over.
401 */
402 CHECK_RET (gp_camera_unref (camera));
403 }
404
405 CHECK_RET (gp_camera_new (&camera));
406
407 CHECK_RET (gp_abilities_list_new (&al));
408 CHECK_RET (gp_abilities_list_load (al, NULL));
409 CHECK_RET (m =
410 gp_abilities_list_lookup_model (al,
411 (char *) Cam_data.camera_name));
412 CHECK_RET (gp_abilities_list_get_abilities (al, m, &abilities));
413 CHECK_RET (gp_abilities_list_free (al));
414 CHECK_RET (gp_camera_set_abilities (camera, abilities));
415
416 if (!Cam_data.port)
417 {
418 DBG (0, "init_gphoto2: Camera port not specified in config file\n");
419 return SANE_STATUS_INVAL;
420 }
421
422 CHECK_RET (gp_port_info_list_new (&il));
423 CHECK_RET (gp_port_info_list_load (il));
424
425
426 if (strcmp (Cam_data.port, "Browse") != 0)
427 {
428 CHECK_RET (port = gp_port_info_list_lookup_path (il, Cam_data.port));
429 CHECK_RET (gp_port_info_list_get_info (il, port, &info));
430 CHECK_RET (gp_camera_set_port_info (camera, info));
431 gp_port_info_list_free (il);
432 }
433
434 for (n = 0; abilities.speed[n]; n++)
435 {
436 if (abilities.speed[n] == Cam_data.speed)
437 {
438 break;
439 }
440 }
441
442 if (abilities.speed[n] == 0 && !strncmp (Cam_data.port, "serial:", 7))
443 {
444 DBG (0,
445 "%s: error: %d is not a valid speed for this camers. Use \"gphoto2 --camera \"%s\" --abilities\" for list.\n",
446 "init_gphoto2", Cam_data.speed, Cam_data.camera_name);
447 return SANE_STATUS_INVAL;
448 }
449
450 DBG (4, "init_gphoto2: about to initialize port\n");
451 /*
452 * Setting of speed only makes sense for serial ports. gphoto2
453 * knows that and will complain if we try to set the speed for
454 * ports other than serial ones. Because we are paranoid here and
455 * check every single error message returned by gphoto2, we need
456 * to make sure that we have a serial port.
457 */
458 if (Cam_data.speed && !strncmp (Cam_data.port, "serial:", 7))
459 {
460 /*
461 * Not sure why we need this hack. The API keeps opening/closing
462 * the port, and that seems to confuse the camera. Holding
463 * the port open seems to fix it.
464 */
465 if ((hack_fd = open (Cam_data.port + 7, O_RDONLY)) < 0)
466 {
467 return SANE_STATUS_INVAL;
468 }
469
470 #ifdef HAVE_USLEEP
471 usleep (200);
472 #else
473 sleep (1);
474 #endif
475 CHECK_RET (gp_camera_set_port_speed (camera, Cam_data.speed));
476 }
477
478 CHECK_RET (gp_camera_init (camera, NULL));
479
480 if (!(abilities.operations & GP_OPERATION_CAPTURE_IMAGE))
481 {
482 DBG (20, "init_gphoto2: Camera does not support image capture\n");
483 sod[GPHOTO2_OPT_SNAP].cap |= SANE_CAP_INACTIVE;
484 }
485
486 if (!(abilities.file_operations & GP_FILE_OPERATION_PREVIEW))
487 {
488 DBG (20, "init_gphoto2: Camera does not support image preview\n");
489 sod[GPHOTO2_OPT_THUMBS].cap |= SANE_CAP_INACTIVE;
490 }
491
492 if (!(abilities.file_operations & GP_FILE_OPERATION_DELETE))
493 {
494 DBG (20, "init_gphoto2: Camera does not support image deletion\n");
495 sod[GPHOTO2_OPT_ERASE].cap |= SANE_CAP_INACTIVE;
496 }
497
498
499 DBG (4, "init_gphoto2: about to get folders\n");
500
501 CHECK_RET (gp_list_new (&list));
502 CHECK_RET (gp_camera_folder_list_folders (camera, TopFolder, list, NULL));
503 n = gp_list_count (list);
504 if (n < 0)
505 {
506 DBG (0, "init_gphoto2: Unable to get file list\n");
507 return SANE_STATUS_INVAL;
508 }
509
510
511 return SANE_STATUS_GOOD;
512 }
513
514 /*
515 * close_gphoto2() - Shutdown camera interface
516 */
517 static void
close_gphoto2(void)518 close_gphoto2 (void)
519 {
520 /*
521 * Put the camera back to 9600 baud
522 */
523
524 if (gp_camera_unref (camera))
525 {
526 DBG (1, "close_gphoto2: error: could not close device\n");
527 }
528
529 camera = NULL;
530 close (hack_fd);
531 }
532
533 /*
534 * get_info() - Get overall information about camera: folder names,
535 * number of pictures, etc.
536 */
537 SANE_Int
get_info(void)538 get_info (void)
539 {
540 SANE_String_Const val;
541 SANE_Int n;
542
543 if (Cam_data.pic_taken == 0)
544 {
545 sod[GPHOTO2_OPT_IMAGE_NUMBER].cap |= SANE_CAP_INACTIVE;
546 image_range.min = 0;
547 image_range.max = 0;
548 }
549 else
550 {
551 sod[GPHOTO2_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE;
552 image_range.min = 1;
553 image_range.max = Cam_data.pic_taken;
554 }
555
556 if (SubDirs)
557 {
558 n = read_dir (TopFolder, 0);
559 }
560 else
561 {
562 n = 1;
563 }
564
565 /* If we've already got a folder_list, free it up before starting
566 * the new one
567 */
568 if (folder_list != NULL)
569 {
570 int tmp;
571 for (tmp = 0; folder_list[tmp]; tmp++)
572 {
573 free (folder_list[tmp]);
574 }
575 free (folder_list);
576 }
577
578 folder_list =
579 (SANE_String *) malloc ((n + 1) * sizeof (SANE_String_Const *));
580
581 if (SubDirs)
582 {
583 for (n = 0; n < gp_list_count (dir_list); n++)
584 {
585 gp_list_get_name (dir_list, n, &val);
586 folder_list[n] = strdup (val);
587 if (strchr ((const char *) folder_list[n], ' '))
588 {
589 *strchr ((const char *) folder_list[n], ' ') = '\0';
590 }
591 }
592 if (n == 0)
593 {
594 folder_list[n++] = (SANE_String) strdup ("");
595 }
596 }
597 else
598 {
599 n = 0;
600 folder_list[n++] = "N/A";
601 }
602
603 folder_list[n] = NULL;
604 sod[GPHOTO2_OPT_FOLDER].constraint.string_list =
605 (SANE_String_Const *) folder_list;
606
607 Cam_data.pic_taken = 0;
608 Cam_data.pic_left = 1; /* Just a guess! */
609
610 return SANE_STATUS_GOOD;
611
612 }
613
614 /*
615 * erase() - erase file from camera corresponding to
616 * current picture number. Does not update any of the other
617 * backend data structures.
618 */
619 static SANE_Int
erase(void)620 erase (void)
621 {
622 SANE_String_Const filename;
623
624 if (SubDirs)
625 {
626 sprintf (cmdbuf, "%s/%s", (char *) TopFolder,
627 (const char *) folder_list[current_folder]);
628 }
629 else
630 {
631 strcpy (cmdbuf, TopFolder);
632 }
633
634 CHECK_RET (gp_list_get_name
635 (dir_list, Cam_data.current_picture_number - 1, &filename));
636
637 CHECK_RET (gp_camera_file_delete (camera, cmdbuf, filename, NULL));
638
639 return SANE_STATUS_GOOD;
640 }
641
642 /*
643 * change_res() - FIXME: Would like to set resolution, but haven't figure
644 * out how to control that yet.
645 */
646 static SANE_Int
change_res(SANE_Byte res)647 change_res (SANE_Byte res)
648 {
649
650 return (res - res);
651
652 }
653
654 /*
655 * sane_init() - Initialization function from SANE API. Initialize some
656 * data structures, verify that all the necessary config information
657 * is present, and initialize gphoto2
658 */
659 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback __sane_unused__ authorize)660 sane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize)
661 {
662 SANE_Int n, entries;
663 SANE_Char f[] = "sane_init";
664 SANE_Char dev_name[PATH_MAX], *p;
665 SANE_Char buf[256];
666 CameraAbilitiesList *al;
667 size_t len;
668 FILE *fp;
669
670 DBG_INIT ();
671
672 DBG (1, "GPHOTO2 Backend\n");
673
674 if (getenv ("GP_DEBUG"))
675 {
676 gp_log_add_func (atoi (getenv ("GP_DEBUG")), debug_func, NULL);
677 }
678
679 if (version_code)
680 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
681
682 fp = sanei_config_open (GPHOTO2_CONFIG_FILE);
683
684 if (!fp)
685 {
686 /* Earlier versions why would try to keep going with compiled in
687 * defaults if the config file is missing. But, now we have so
688 * options and combinations of options, that success without a config
689 * file is unlikely. So, give and return failure
690 */
691 DBG (0, "warning: %s: missing config file '%s'\n"
692 "If you aren't using gphoto2, you should disable it in dll.conf.\n"
693 "If you do want to use gphoto2, you'll need to install the config\n"
694 "file in %s.\n", f, GPHOTO2_CONFIG_FILE, GPHOTO2_CONFIG_FILE);
695
696 return SANE_STATUS_INVAL;
697 }
698 else
699 {
700 while (sanei_config_read (dev_name, sizeof (dev_name), fp))
701 {
702 dev_name[sizeof (dev_name) - 1] = '\0';
703 DBG (20, "%s: config- %s\n", f, dev_name);
704
705 if (dev_name[0] == '#')
706 continue; /* ignore line comments */
707 len = strlen (dev_name);
708 if (!len)
709 continue; /* ignore empty lines */
710 if (strncmp (dev_name, "port=", 5) == 0)
711 {
712 GPPortInfoList *list;
713 GPPortInfo info;
714 int result;
715
716 p = dev_name + 5;
717 if (p)
718 Cam_data.port = strdup (p);
719 DBG (20, "Config file port=%s\n", Cam_data.port);
720
721 /* Validate port */
722 CHECK_RET (gp_port_info_list_new (&list));
723 result = gp_port_info_list_load (list);
724 if (result < 0)
725 {
726 gp_port_info_list_free (list);
727 return SANE_STATUS_INVAL;
728 }
729 entries = gp_port_info_list_count (list);
730 if (entries < 0)
731 {
732 gp_port_info_list_free (list);
733 return SANE_STATUS_INVAL;
734 }
735 for (n = 0; n < entries; n++)
736 {
737 #ifdef HAVE_GP_PORT_INFO_GET_PATH
738 char *info_path = NULL;
739 #endif
740 result = gp_port_info_list_get_info (list, n, &info);
741 if (result < 0)
742 {
743 gp_port_info_list_free (list);
744 return SANE_STATUS_INVAL;
745 }
746 #ifdef HAVE_GP_PORT_INFO_GET_PATH
747 gp_port_info_get_path (info, &info_path);
748 if (strcmp (Cam_data.port, info_path) == 0)
749 #else
750 if (strcmp (Cam_data.port, info.path) == 0)
751 #endif
752 {
753 break;
754 }
755 }
756 if (n == entries)
757 {
758 DBG (0,
759 "%s: error: %s is not a valid gphoto2 port. Use \"gphoto2 --list-ports\" for list.\n",
760 "init_gphoto2", Cam_data.port);
761 return SANE_STATUS_INVAL;
762 }
763 }
764 else if (strncmp (dev_name, "camera=", 7) == 0)
765 {
766 Cam_data.camera_name = strdup (dev_name + 7);
767 DBG (20, "Config file camera=%s\n", Cam_data.camera_name);
768 sprintf (buf, "Image selection - %s", Cam_data.camera_name);
769
770 CHECK_RET (gp_abilities_list_new (&al));
771 CHECK_RET (gp_abilities_list_load (al, NULL));
772 CHECK_RET (entries = gp_abilities_list_count (al));
773
774 for (n = 0; n < entries; n++)
775 {
776 CHECK_RET (gp_abilities_list_get_abilities
777 (al, n, &abilities));
778 if (strcmp (Cam_data.camera_name, abilities.model) == 0)
779 {
780 break;
781 }
782 }
783 if (n == entries)
784 {
785 DBG (0,
786 "%s: error: %s is not a valid camera type. Use \"gphoto2 --list-cameras\" for list.\n",
787 f, Cam_data.camera_name);
788 return SANE_STATUS_INVAL;
789 }
790
791 /* Special case: Force port to special value for the
792 * "Directory Browse" camera - overriding anything in
793 * the config file - or more likely when not specified
794 * in the config file.
795 */
796
797 if (strcmp (Cam_data.camera_name, "Directory Browse") == 0)
798 {
799 Cam_data.port = "Browse";
800 }
801
802 sod[GPHOTO2_OPT_IMAGE_SELECTION].title = strdup (buf);
803 }
804 else if (strcmp (dev_name, "dumpinquiry") == 0)
805 {
806 dumpinquiry = SANE_TRUE;
807 }
808 else if (strncmp (dev_name, "speed=", 6) == 0)
809 {
810 sscanf (&dev_name[6], "%d", &Cam_data.speed);
811
812 DBG (20, "Config file speed=%u\n", Cam_data.speed);
813
814 }
815 else if (strncmp (dev_name, "resolution=", 11) == 0)
816 {
817 sscanf (&dev_name[11], "%dx%d", &highres_width,
818 &highres_height);
819 DBG (20, "Config file resolution=%ux%u\n", highres_width,
820 highres_height);
821 }
822 else if (strncmp (dev_name, "thumb_resolution=", 17) == 0)
823 {
824 sscanf (&dev_name[17], "%dx%d", &thumb_width, &thumb_height);
825 DBG (20, "Config file thumb_resolution=%ux%u\n", thumb_width,
826 thumb_height);
827 }
828 else if (strncmp (dev_name, "topfolder=", 10) == 0)
829 {
830 /* Make sure TopFolder is non-null */
831 if (strlen (dev_name) > 10)
832 {
833 TopFolder = strdup (&dev_name[10]);
834 DBG (20, "Config file topfolder=%s\n", TopFolder);
835 }
836 }
837 else if (strncmp (dev_name, "subdirs=", 8) == 0)
838 {
839 SubDirs = atoi (&dev_name[8]);
840 if (SubDirs == 0)
841 {
842 sod[GPHOTO2_OPT_FOLDER].cap |= SANE_CAP_INACTIVE;
843 }
844 DBG (20, "Config file subdirs=%d\n", SubDirs);
845 }
846 }
847 fclose (fp);
848 }
849
850 DBG (3, "sane_init: about to init_gphoto2\n");
851
852 if (init_gphoto2 () != SANE_STATUS_GOOD)
853 return SANE_STATUS_INVAL;
854
855 dev[0].name = strdup (Cam_data.port);
856
857 DBG (3, "sane_init: about to get_info\n");
858 if (get_info () != SANE_STATUS_GOOD)
859 {
860 DBG (1, "error: could not get info\n");
861 close_gphoto2 ();
862 return SANE_STATUS_INVAL;
863 }
864
865 /* load the current images array */
866 DBG (3, "sane_init: about to get_pictures_info\n");
867 get_pictures_info ();
868
869 if (Cam_data.pic_taken == 0)
870 {
871 Cam_data.current_picture_number = 0;
872 parms.bytes_per_line = 0;
873 parms.pixels_per_line = 0;
874 parms.lines = 0;
875 }
876 else
877 {
878 Cam_data.current_picture_number = 1;
879 /* OLD:
880 set_res (Cam_data.Pictures[Cam_data.current_picture_number - 1].low_res);
881 */
882 set_res (gphoto2_opt_lowres);
883 }
884
885 if (dumpinquiry)
886 {
887 SANE_Int x = 0;
888 DBG (0, "\nCamera information:\n~~~~~~~~~~~~~~~~~\n\n");
889 DBG (0, "Model : %s\n", abilities.model);
890 DBG (0, "Pictures : %d\n", Cam_data.pic_taken);
891 DBG (0, "Serial port support : %s\n",
892 (abilities.port & GP_PORT_SERIAL) ? "yes" : "no");
893 DBG (0, "USB support : %s\n",
894 (abilities.port & GP_PORT_USB) ? "yes" : "no");
895
896 if (abilities.speed[0] != 0)
897 {
898 DBG (0, "Transfer speeds supported :\n");
899 do
900 {
901 DBG (0, " : %i\n",
902 abilities.speed[x]);
903 x++;
904 }
905 while (abilities.speed[x] != 0);
906 }
907 DBG (0, "Capture choices :\n");
908 if (abilities.operations & GP_OPERATION_CAPTURE_IMAGE)
909 DBG (0, " : Image\n");
910 if (abilities.operations & GP_OPERATION_CAPTURE_VIDEO)
911 DBG (0, " : Video\n");
912 if (abilities.operations & GP_OPERATION_CAPTURE_AUDIO)
913 DBG (0, " : Audio\n");
914 if (abilities.operations & GP_OPERATION_CAPTURE_PREVIEW)
915 DBG (0, " : Preview\n");
916 DBG (0, "Configuration support : %s\n",
917 abilities.operations & GP_OPERATION_CONFIG ? "yes" : "no");
918
919 DBG (0, "Delete files on camera support : %s\n",
920 abilities.
921 file_operations & GP_FILE_OPERATION_DELETE ? "yes" : "no");
922 DBG (0, "File preview (thumbnail) support : %s\n",
923 abilities.
924 file_operations & GP_FILE_OPERATION_PREVIEW ? "yes" : "no");
925 DBG (0, "File upload support : %s\n",
926 abilities.
927 folder_operations & GP_FOLDER_OPERATION_PUT_FILE ? "yes" : "no");
928
929
930 }
931
932 return SANE_STATUS_GOOD;
933 }
934
935 /*
936 * sane_exit() - Required by SANE API.
937 */
938 void
sane_exit(void)939 sane_exit (void)
940 {
941 close_gphoto2 ();
942 }
943
944 /*
945 * sane_get_devices() - From SANE API
946 */
947 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool __sane_unused__ local_only)948 sane_get_devices (const SANE_Device *** device_list, SANE_Bool
949 __sane_unused__ local_only)
950 {
951 DBG (127, "sane_get_devices called\n");
952
953 *device_list = devlist;
954 return SANE_STATUS_GOOD;
955 }
956
957 /*
958 * sane_open() - From SANE API
959 */
960
961 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)962 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
963 {
964 SANE_Int i;
965
966 DBG (127, "sane_open for device %s\n", devicename);
967 if (!devicename[0])
968 {
969 i = 0;
970 }
971 else
972 {
973 for (i = 0; i < NELEMS (dev); ++i)
974 {
975 if (strcmp (devicename, dev[i].name) == 0)
976 {
977 break;
978 }
979 }
980 }
981
982 if (i >= NELEMS (dev))
983 {
984 return SANE_STATUS_INVAL;
985 }
986
987 if (is_open)
988 {
989 return SANE_STATUS_DEVICE_BUSY;
990 }
991
992 is_open = 1;
993 *handle = MAGIC;
994
995 DBG (4, "sane_open: pictures taken=%d\n", Cam_data.pic_taken);
996
997 return SANE_STATUS_GOOD;
998 }
999
1000 /*
1001 * sane_close() - From SANE API
1002 */
1003
1004 void
sane_close(SANE_Handle handle)1005 sane_close (SANE_Handle handle)
1006 {
1007 DBG (127, "sane_close called\n");
1008 if (handle == MAGIC)
1009 is_open = 0;
1010
1011 DBG (127, "sane_close returning\n");
1012 }
1013
1014 /*
1015 * sane_get_option_descriptor() - From SANE API
1016 */
1017
1018 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)1019 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
1020 {
1021 if (handle != MAGIC || !is_open)
1022 return NULL; /* wrong device */
1023 if (option < 0 || option >= NELEMS (sod))
1024 return NULL;
1025 return &sod[option];
1026 }
1027
1028 static SANE_Int myinfo = 0;
1029
1030 /*
1031 * sane_control_option() - From SANE API
1032 */
1033
1034 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * value,SANE_Int * info)1035 sane_control_option (SANE_Handle handle, SANE_Int option,
1036 SANE_Action action, void *value, SANE_Int * info)
1037 {
1038 SANE_Status status;
1039
1040 if (option < 0 || option >= NELEMS (sod))
1041 return SANE_STATUS_INVAL; /* Unknown option ... */
1042
1043 /* Need to put this DBG line after the range check on option */
1044 DBG (127, "control_option(handle=%p,opt=%s,act=%s,val=%p,info=%p)\n",
1045 handle, sod[option].title,
1046 (action ==
1047 SANE_ACTION_SET_VALUE ? "SET" : (action ==
1048 SANE_ACTION_GET_VALUE ? "GET" :
1049 "SETAUTO")), value, (void *) info);
1050
1051 if (handle != MAGIC || !is_open)
1052 return SANE_STATUS_INVAL; /* Unknown handle ... */
1053
1054 if (option < 0 || option >= NELEMS (sod))
1055 return SANE_STATUS_INVAL; /* Unknown option ... */
1056
1057 switch (action)
1058 {
1059 case SANE_ACTION_SET_VALUE:
1060
1061 /* Can't set disabled options */
1062 if (!SANE_OPTION_IS_ACTIVE (sod[option].cap))
1063 {
1064 return (SANE_STATUS_INVAL);
1065 }
1066
1067 /* initialize info to zero - we'll OR in various values later */
1068 if (info)
1069 *info = 0;
1070
1071 status = sanei_constrain_value (sod + option, value, &myinfo);
1072 if (status != SANE_STATUS_GOOD)
1073 {
1074 DBG (2, "Constraint error in control_option\n");
1075 return status;
1076 }
1077
1078 switch (option)
1079 {
1080 case GPHOTO2_OPT_IMAGE_NUMBER:
1081 if (*(SANE_Word *) value <= Cam_data.pic_taken)
1082 Cam_data.current_picture_number = *(SANE_Word *) value;
1083 else
1084 Cam_data.current_picture_number = Cam_data.pic_taken;
1085
1086 /*
1087 * Setting a new image number could change image size (if
1088 * we supported that - which we hope to do someday!
1089 */
1090 myinfo |= SANE_INFO_RELOAD_PARAMS;
1091
1092 /* get the image's resolution, unless the camera has no
1093 * pictures yet
1094 */
1095 if (Cam_data.pic_taken != 0)
1096 {
1097 /* OLD:
1098 set_res (Cam_data.
1099 Pictures[Cam_data.current_picture_number - 1].low_res);
1100 */
1101 set_res (gphoto2_opt_lowres);
1102 }
1103 break;
1104
1105 case GPHOTO2_OPT_THUMBS:
1106 gphoto2_opt_thumbnails = !!*(SANE_Word *) value;
1107
1108 /* Thumbnail forces an image size change: */
1109 myinfo |= SANE_INFO_RELOAD_PARAMS;
1110
1111 if (Cam_data.pic_taken != 0)
1112 {
1113 /* OLD:
1114 set_res (Cam_data.
1115 Pictures[Cam_data.current_picture_number - 1].low_res);
1116 */
1117 set_res (gphoto2_opt_lowres);
1118 }
1119 break;
1120
1121 case GPHOTO2_OPT_SNAP:
1122 switch (*(SANE_Bool *) value)
1123 {
1124 case SANE_TRUE:
1125 gphoto2_opt_snap = SANE_TRUE;
1126 break;
1127 case SANE_FALSE:
1128 gphoto2_opt_snap = SANE_FALSE;
1129 break;
1130 default:
1131 return SANE_STATUS_INVAL;
1132 }
1133
1134 /* Snap forces new image size and changes image range */
1135
1136 myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1137 /* if we are snapping a new one */
1138 if (gphoto2_opt_snap)
1139 {
1140 /* activate the resolution setting */
1141 /* Until we figure out how to do this
1142 sod[GPHOTO2_OPT_LOWRES].cap &= ~SANE_CAP_INACTIVE;
1143 */
1144 /* and de-activate the image number selector */
1145 sod[GPHOTO2_OPT_IMAGE_NUMBER].cap |= SANE_CAP_INACTIVE;
1146 }
1147 else
1148 {
1149 /* deactivate the resolution setting */
1150 sod[GPHOTO2_OPT_LOWRES].cap |= SANE_CAP_INACTIVE;
1151 /* and activate the image number selector, if there are
1152 * pictures available */
1153 if (Cam_data.current_picture_number)
1154 {
1155 sod[GPHOTO2_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE;
1156 }
1157 }
1158 /* set params according to resolution settings */
1159 set_res (gphoto2_opt_lowres);
1160
1161 break;
1162
1163 case GPHOTO2_OPT_LOWRES:
1164 gphoto2_opt_lowres = !!*(SANE_Word *) value;
1165
1166 /* Lowres potentially changes image size */
1167 myinfo |= SANE_INFO_RELOAD_PARAMS;
1168
1169 /* FIXME - change the number of pictures left depending on resolution
1170 perhaps just call get_info again?
1171 */
1172 set_res (gphoto2_opt_lowres);
1173
1174 break;
1175
1176 case GPHOTO2_OPT_ERASE:
1177 gphoto2_opt_erase = !!*(SANE_Word *) value;
1178 break;
1179
1180 case GPHOTO2_OPT_AUTOINC:
1181 gphoto2_opt_autoinc = !!*(SANE_Word *) value;
1182 break;
1183
1184 case GPHOTO2_OPT_FOLDER:
1185 DBG (1, "FIXME set folder not implemented yet\n");
1186 break;
1187
1188 case GPHOTO2_OPT_DEFAULT:
1189 gphoto2_opt_thumbnails = 0;
1190 gphoto2_opt_snap = 0;
1191
1192 /* deactivate the resolution setting */
1193 sod[GPHOTO2_OPT_LOWRES].cap |= SANE_CAP_INACTIVE;
1194 /* and activate the image number selector */
1195 sod[GPHOTO2_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE;
1196
1197 myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1198
1199 DBG (1, "FIXME: Set all defaults here!\n");
1200 break;
1201
1202 case GPHOTO2_OPT_INIT_GPHOTO2:
1203 if (init_gphoto2 () != SANE_STATUS_GOOD)
1204 {
1205 return SANE_STATUS_INVAL;
1206 }
1207 if (get_info () != SANE_STATUS_GOOD)
1208 {
1209 DBG (1, "error: could not get info\n");
1210 close_gphoto2 ();
1211 return SANE_STATUS_INVAL;
1212 }
1213
1214 /* load the current images array */
1215 get_pictures_info ();
1216
1217 myinfo |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1218 break;
1219
1220 default:
1221 return SANE_STATUS_INVAL;
1222 }
1223 break;
1224
1225 case SANE_ACTION_GET_VALUE:
1226
1227 /* Can't return status for disabled options */
1228 if (!SANE_OPTION_IS_ACTIVE (sod[option].cap))
1229 {
1230 return (SANE_STATUS_INVAL);
1231 }
1232
1233 switch (option)
1234 {
1235 case 0:
1236 *(SANE_Word *) value = NELEMS (sod);
1237 break;
1238
1239 case GPHOTO2_OPT_IMAGE_NUMBER:
1240 *(SANE_Word *) value = Cam_data.current_picture_number;
1241 break;
1242
1243 case GPHOTO2_OPT_THUMBS:
1244 *(SANE_Word *) value = gphoto2_opt_thumbnails;
1245 break;
1246
1247 case GPHOTO2_OPT_SNAP:
1248 *(SANE_Word *) value = gphoto2_opt_snap;
1249 break;
1250
1251 case GPHOTO2_OPT_LOWRES:
1252 *(SANE_Word *) value = gphoto2_opt_lowres;
1253 break;
1254
1255 case GPHOTO2_OPT_ERASE:
1256 *(SANE_Word *) value = gphoto2_opt_erase;
1257 break;
1258
1259 case GPHOTO2_OPT_AUTOINC:
1260 *(SANE_Word *) value = gphoto2_opt_autoinc;
1261 break;
1262
1263 case GPHOTO2_OPT_FOLDER:
1264 if (folder_list == NULL)
1265 {
1266 return SANE_STATUS_INVAL;
1267 }
1268 strncpy ((char *) value, (const char *) folder_list[current_folder],
1269 256);
1270 break;
1271
1272
1273 default:
1274 return SANE_STATUS_INVAL;
1275 }
1276 break;
1277
1278 case SANE_ACTION_SET_AUTO:
1279 switch (option)
1280 {
1281 default:
1282 return SANE_STATUS_UNSUPPORTED; /* We are DUMB */
1283 }
1284 }
1285
1286 if (info && action == SANE_ACTION_SET_VALUE)
1287 {
1288 *info = myinfo;
1289 myinfo = 0;
1290 }
1291 return SANE_STATUS_GOOD;
1292 }
1293
1294 /*
1295 * sane_get_parameters() - From SANE API
1296 */
1297 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)1298 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
1299 {
1300 SANE_Int rc = SANE_STATUS_GOOD;
1301
1302 DBG (127, "sane_get_params called, wid=%d,height=%d\n",
1303 parms.pixels_per_line, parms.lines);
1304
1305 if (handle != MAGIC || !is_open)
1306 rc = SANE_STATUS_INVAL; /* Unknown handle ... */
1307
1308 parms.last_frame = SANE_TRUE; /* Have no idea what this does */
1309 *params = parms;
1310 DBG (127, "sane_get_params return %d\n", rc);
1311 return rc;
1312 }
1313
1314 typedef struct
1315 {
1316 struct jpeg_source_mgr pub;
1317 JOCTET *buffer;
1318 }
1319 my_source_mgr;
1320 typedef my_source_mgr *my_src_ptr;
1321
1322 METHODDEF (void)
jpeg_init_source(j_decompress_ptr __sane_unused__ cinfo)1323 jpeg_init_source (j_decompress_ptr __sane_unused__ cinfo)
1324 {
1325 /* nothing to do */
1326 }
1327
jpeg_fill_input_buffer(j_decompress_ptr cinfo)1328 METHODDEF (boolean) jpeg_fill_input_buffer (j_decompress_ptr cinfo)
1329 {
1330 int n;
1331
1332 my_src_ptr src = (my_src_ptr) cinfo->src;
1333
1334 if (data_file_current_index + 512 > data_file_total_size)
1335 {
1336 n = data_file_total_size - data_file_current_index;
1337 }
1338 else
1339 {
1340 n = 512;
1341 }
1342
1343 memcpy (src->buffer, data_ptr + data_file_current_index, n);
1344 data_file_current_index += n;
1345
1346 src->pub.next_input_byte = src->buffer;
1347 src->pub.bytes_in_buffer = n;
1348
1349 return TRUE;
1350 }
1351
jpeg_skip_input_data(j_decompress_ptr cinfo,long num_bytes)1352 METHODDEF (void) jpeg_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
1353 {
1354
1355 my_src_ptr src = (my_src_ptr) cinfo->src;
1356
1357 if (num_bytes > 0)
1358 {
1359 while (num_bytes > (long) src->pub.bytes_in_buffer)
1360 {
1361 num_bytes -= (long) src->pub.bytes_in_buffer;
1362 (void) jpeg_fill_input_buffer (cinfo);
1363 }
1364 }
1365 src->pub.next_input_byte += (size_t) num_bytes;
1366 src->pub.bytes_in_buffer -= (size_t) num_bytes;
1367 }
1368
1369 METHODDEF (void)
jpeg_term_source(j_decompress_ptr __sane_unused__ cinfo)1370 jpeg_term_source (j_decompress_ptr __sane_unused__ cinfo)
1371 {
1372 /* no work necessary here */
1373 }
1374
1375 /*
1376 * sane_start() - From SANE API
1377 */
1378 SANE_Status
sane_start(SANE_Handle handle)1379 sane_start (SANE_Handle handle)
1380 {
1381 SANE_String_Const filename, mime_type;
1382
1383 DBG (127, "sane_start called\n");
1384 if (handle != MAGIC || !is_open ||
1385 (Cam_data.current_picture_number == 0
1386 && gphoto2_opt_snap == SANE_FALSE))
1387 return SANE_STATUS_INVAL; /* Unknown handle ... */
1388
1389 if (Cam_data.scanning)
1390 return SANE_STATUS_EOF;
1391
1392 /*
1393 * This shouldn't normally happen, but we allow it as a special case
1394 * when batch/autoinc are in effect. The first illegal picture number
1395 * terminates the scan
1396 */
1397 if (Cam_data.current_picture_number > Cam_data.pic_taken)
1398 {
1399 return SANE_STATUS_INVAL;
1400 }
1401
1402 if (gphoto2_opt_snap)
1403 {
1404 /*
1405 * Don't allow picture unless there is room in the
1406 * camera.
1407 */
1408 if (Cam_data.pic_left == 0)
1409 {
1410 DBG (3, "No room to store new picture\n");
1411 return SANE_STATUS_INVAL;
1412 }
1413
1414
1415 if (snap_pic () == SANE_STATUS_INVAL)
1416 {
1417 DBG (1, "Failed to snap new picture\n");
1418 return SANE_STATUS_INVAL;
1419 }
1420 }
1421
1422 DBG (4, "sane_start: about to get file\n");
1423
1424 CHECK_RET (gp_file_new (&data_file));
1425
1426 if (SubDirs)
1427 {
1428 sprintf (cmdbuf, "%s/%s", (char *) TopFolder,
1429 (const char *) folder_list[current_folder]);
1430 }
1431 else
1432 {
1433 strcpy (cmdbuf, TopFolder);
1434 }
1435
1436 CHECK_RET (gp_list_get_name
1437 (dir_list, Cam_data.current_picture_number - 1, &filename));
1438
1439 CHECK_RET (gp_camera_file_get (camera, cmdbuf, filename,
1440 gphoto2_opt_thumbnails ? GP_FILE_TYPE_PREVIEW
1441 : GP_FILE_TYPE_NORMAL, data_file, NULL));
1442
1443 CHECK_RET (gp_file_get_mime_type (data_file, &mime_type));
1444 if (strcmp (GP_MIME_JPEG, mime_type) != 0)
1445 {
1446 DBG (0,
1447 "FIXME - Only jpeg files currently supported, can't do %s for file %s/%s\n",
1448 mime_type, cmdbuf, filename);
1449 return SANE_STATUS_INVAL;
1450 }
1451
1452 CHECK_RET (gp_file_get_data_and_size
1453 (data_file, (const char **)&data_ptr, &data_file_total_size));
1454
1455 if ( converter_init (handle) != SANE_STATUS_GOOD )
1456 return SANE_STATUS_INVAL;
1457
1458 /* Check if a linebuffer has been allocated. If we had one
1459 * previously, free it up and allocate one for (possibly) new
1460 * size. parms.bytes_per_line is set by converter_init()
1461 */
1462 if (linebuffer == NULL)
1463 {
1464 linebuffer = malloc (parms.bytes_per_line);
1465 }
1466 else
1467 {
1468 free (linebuffer);
1469 linebuffer = malloc (parms.bytes_per_line);
1470 }
1471 if (linebuffer == NULL)
1472 {
1473 return SANE_STATUS_INVAL;
1474 }
1475
1476 Cam_data.scanning = SANE_TRUE; /* don't overlap scan requests */
1477
1478 return SANE_STATUS_GOOD;
1479 }
1480
1481 /*
1482 * sane_read() - From SANE API
1483 */
1484 SANE_Status
sane_read(SANE_Handle __sane_unused__ handle,SANE_Byte * data,SANE_Int max_length,SANE_Int * length)1485 sane_read (SANE_Handle __sane_unused__ handle, SANE_Byte * data,
1486 SANE_Int max_length, SANE_Int * length)
1487 {
1488 if (Cam_data.scanning == SANE_FALSE)
1489 {
1490 return SANE_STATUS_INVAL;
1491 }
1492
1493 /* If there is anything in the buffer, satisfy the read from there */
1494 if (linebuffer_size && linebuffer_index < linebuffer_size)
1495 {
1496 *length = linebuffer_size - linebuffer_index;
1497
1498 if (*length > max_length)
1499 {
1500 *length = max_length;
1501 }
1502 memcpy (data, linebuffer + linebuffer_index, *length);
1503 linebuffer_index += *length;
1504
1505 return SANE_STATUS_GOOD;
1506 }
1507
1508 if (converter_scan_complete ())
1509 {
1510 SANE_Status retval;
1511
1512 *length = 0;
1513 retval = converter_do_scan_complete_cleanup ();
1514
1515 if (retval != SANE_STATUS_GOOD)
1516 {
1517 return retval;
1518 }
1519 }
1520
1521 *length = converter_fill_buffer ();
1522 linebuffer_size = *length;
1523 linebuffer_index = 0;
1524
1525 if (*length > max_length)
1526 {
1527 *length = max_length;
1528 }
1529 memcpy (data, linebuffer + linebuffer_index, *length);
1530 linebuffer_index += *length;
1531
1532 return SANE_STATUS_GOOD;
1533 }
1534
1535 /*
1536 * sane_cancel() - From SANE API
1537 */
1538 void
sane_cancel(SANE_Handle __sane_unused__ handle)1539 sane_cancel (SANE_Handle __sane_unused__ handle)
1540 {
1541 if (Cam_data.scanning)
1542 {
1543 Cam_data.scanning = SANE_FALSE; /* done with scan */
1544 }
1545 else
1546 DBG (4, "sane_cancel: not scanning - nothing to do\n");
1547 }
1548
1549 /*
1550 * sane_set_io_mode() - From SANE API
1551 */
1552 SANE_Status
sane_set_io_mode(SANE_Handle __sane_unused__ handle,SANE_Bool __sane_unused__ non_blocking)1553 sane_set_io_mode (SANE_Handle __sane_unused__ handle, SANE_Bool
1554 __sane_unused__ non_blocking)
1555 {
1556 /* sane_set_io_mode() is only valid during a scan */
1557 if (Cam_data.scanning)
1558 {
1559 if (non_blocking == SANE_FALSE)
1560 {
1561 return SANE_STATUS_GOOD;
1562 }
1563 else
1564 {
1565 return SANE_STATUS_UNSUPPORTED;
1566 }
1567 }
1568 else
1569 {
1570 /* We aren't currently scanning */
1571 return SANE_STATUS_INVAL;
1572 }
1573 }
1574
1575 /*
1576 * sane_get_select_fd() - From SANE API
1577 */
1578 SANE_Status
sane_get_select_fd(SANE_Handle __sane_unused__ handle,SANE_Int __sane_unused__ * fd)1579 sane_get_select_fd (SANE_Handle __sane_unused__ handle, SANE_Int __sane_unused__ * fd)
1580 {
1581 return SANE_STATUS_UNSUPPORTED;
1582 }
1583
1584 /*
1585 * get_pictures_info - load information about all pictures currently in
1586 * camera: Mainly the mapping of picture number
1587 * to picture name. We'ld like to get other
1588 * information such as image size, but the API
1589 * doesn't provide any support for that.
1590 */
1591 static PictureInfo *
get_pictures_info(void)1592 get_pictures_info (void)
1593 {
1594 SANE_Char f[] = "get_pictures_info";
1595 SANE_Char path[256];
1596 SANE_Int num_pictures;
1597 SANE_Int p;
1598 PictureInfo *pics;
1599
1600 if (Cam_data.Pictures)
1601 {
1602 free (Cam_data.Pictures);
1603 Cam_data.Pictures = NULL;
1604 }
1605
1606 strcpy (path, TopFolder);
1607 if (SubDirs)
1608 {
1609 if (folder_list[current_folder] != NULL)
1610 {
1611 strcat (path, "/");
1612 strcat (path, (const char *) folder_list[current_folder]);
1613 }
1614 }
1615 num_pictures = read_dir (path, 1);
1616 Cam_data.pic_taken = num_pictures;
1617 if (num_pictures > 0)
1618 {
1619 sod[GPHOTO2_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE;
1620 image_range.min = 1;
1621 image_range.max = num_pictures;
1622 }
1623
1624 if ((pics = (PictureInfo *) malloc (Cam_data.pic_taken *
1625 sizeof (PictureInfo))) == NULL)
1626 {
1627 DBG (1, "%s: error: allocate memory for pictures array\n", f);
1628 return NULL;
1629 }
1630
1631 for (p = 0; p < Cam_data.pic_taken; p++)
1632 {
1633 if (get_picture_info (pics + p, p) == -1)
1634 {
1635 free (pics);
1636 return NULL;
1637 }
1638 }
1639
1640 Cam_data.Pictures = pics;
1641 return pics;
1642 }
1643
1644 /*
1645 * get_picture_info() - get info about picture p. Currently we have no
1646 * way to get information about a picture beyond it's name.
1647 */
1648 static SANE_Int
get_picture_info(PictureInfo * pic,SANE_Int p)1649 get_picture_info (PictureInfo * pic, SANE_Int p)
1650 {
1651
1652 SANE_Char f[] = "get_picture_info";
1653 const char *name;
1654
1655 DBG (4, "%s: info for pic #%d\n", f, p);
1656
1657 gp_list_get_name (dir_list, p, &name);
1658 DBG (4, "Name is %s\n", name);
1659
1660 read_info (name);
1661
1662 pic->low_res = SANE_FALSE;
1663
1664 return 0;
1665 }
1666
1667 /*
1668 * snap_pic - take a picture (and call get_pictures_info to re-create
1669 * the directory related data structures)
1670 */
1671 static SANE_Status
snap_pic(void)1672 snap_pic (void)
1673 {
1674 SANE_Char f[] = "snap_pic";
1675 CameraFilePath path;
1676
1677 /* make sure camera is set to our settings state */
1678 if (change_res (gphoto2_opt_lowres) == -1)
1679 {
1680 DBG (1, "%s: Failed to set resolution\n", f);
1681 return SANE_STATUS_INVAL;
1682 }
1683
1684 /*
1685 * This is needed when the camera has no files and the first picture
1686 * is taken. I guess it's because a folder needs to be created and
1687 * the filesystem doesn't know about it.
1688 */
1689 if (Cam_data.pic_taken == 0)
1690 {
1691 gp_filesystem_reset (camera->fs);
1692 }
1693
1694 CHECK_RET (gp_camera_capture (camera, GP_CAPTURE_IMAGE, &path, NULL));
1695
1696 /* Can't just increment picture count, because if the camera has
1697 * zero pictures we may not know the folder name. Start over
1698 * with get_info and get_pictures_info. (We didn't have the call
1699 * to init_gphoto2() here before, but that was causing us to not
1700 * see the new image - need to use a biggger hammer to get it to
1701 * re-read the camera directory
1702 */
1703
1704 if (init_gphoto2 () != SANE_STATUS_GOOD)
1705 {
1706 return SANE_STATUS_INVAL;
1707 }
1708
1709 if (get_info () != SANE_STATUS_GOOD)
1710 {
1711 DBG (1, "error: could not get info\n");
1712 close_gphoto2 ();
1713 return SANE_STATUS_INVAL;
1714 }
1715
1716 if (get_pictures_info () == NULL)
1717 {
1718 DBG (1, "%s: Failed to get new picture info\n", f);
1719 /* FIXME - I guess we should try to erase the image here */
1720 return SANE_STATUS_INVAL;
1721 }
1722
1723 sod[GPHOTO2_OPT_IMAGE_NUMBER].cap |= SANE_CAP_INACTIVE;
1724 Cam_data.current_picture_number = Cam_data.pic_taken;
1725 myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1726
1727 return SANE_STATUS_GOOD;
1728 }
1729
1730 /*
1731 * read_dir - read a list of file names from the specified directory
1732 * and create a linked list of file name entries in
1733 * alphabetical order. The first entry in the list will
1734 * be "picture #1", etc.
1735 */
1736 static SANE_Int
read_dir(SANE_String dir,SANE_Bool read_files)1737 read_dir (SANE_String dir, SANE_Bool read_files)
1738 {
1739 SANE_Int retval = 0;
1740 SANE_Char f[] = "read_dir";
1741
1742 /* Free up current list */
1743 if (dir_list != NULL)
1744 {
1745 if (gp_list_free (dir_list) < 0)
1746 {
1747 DBG (0, "%s: error: gp_list_free failed\n", f);
1748 }
1749 dir_list = NULL;
1750 }
1751 if (gp_list_new (&dir_list) < 0)
1752 {
1753 DBG (0, "%s: error: gp_list_new failed\n", f);
1754 }
1755
1756 if (read_files)
1757 {
1758 CHECK_RET (gp_camera_folder_list_files (camera, dir, dir_list, NULL));
1759 }
1760 else
1761 {
1762 CHECK_RET (gp_camera_folder_list_folders (camera, dir, dir_list, NULL));
1763 }
1764
1765 retval = gp_list_count (dir_list);
1766
1767 return retval;
1768 }
1769
1770 /*
1771 * read_info - read the info block from camera for the specified file
1772 * NOT YET SUPPORTED - If it were we could use it to do things
1773 * like update the image size parameters displayed by the GUI
1774 */
1775 static SANE_Int
read_info(SANE_String_Const fname)1776 read_info (SANE_String_Const fname)
1777 {
1778 SANE_Char path[256];
1779
1780 strcpy (path, "\\DCIM\\");
1781 strcat (path, (const char *) folder_list[current_folder]);
1782 strcat (path, "\\");
1783 strcat (path, fname);
1784
1785 return 0;
1786 }
1787
1788 /*
1789 * set_res - set picture size depending on resolution settings
1790 */
1791 static void
set_res(SANE_Int __sane_unused__ lowres)1792 set_res (SANE_Int __sane_unused__ lowres)
1793 {
1794 if (gphoto2_opt_thumbnails)
1795 {
1796 parms.bytes_per_line = THUMB_WIDTH * 3;
1797 parms.pixels_per_line = THUMB_WIDTH;
1798 parms.lines = THUMB_HEIGHT;
1799 }
1800 else
1801 {
1802 parms.bytes_per_line = HIGHRES_WIDTH * 3;
1803 parms.pixels_per_line = HIGHRES_WIDTH;
1804 parms.lines = HIGHRES_HEIGHT;
1805 }
1806 }
1807
1808 /*
1809 * converter_do_scan_complete_cleanup - do everything that needs to be
1810 * once a "scan" has been completed: Unref the file, Erase the image,
1811 * and increment image number to point to next picture.
1812 */
1813 static SANE_Status
converter_do_scan_complete_cleanup(void)1814 converter_do_scan_complete_cleanup (void)
1815 {
1816 CameraList *tmp_list;
1817 SANE_Int i;
1818 SANE_String_Const filename;
1819
1820 gp_file_unref (data_file);
1821
1822 if (gphoto2_opt_erase)
1823 {
1824 DBG (127, "sane_read bp%d, erase image\n", __LINE__);
1825 if (erase () == -1)
1826 {
1827 DBG (1, "Failed to erase memory\n");
1828 return SANE_STATUS_INVAL;
1829 }
1830
1831
1832 if (SubDirs)
1833 {
1834 sprintf (cmdbuf, "%s/%s", (char *) TopFolder,
1835 (const char *) folder_list[current_folder]);
1836 }
1837 else
1838 {
1839 strcpy (cmdbuf, TopFolder);
1840 }
1841
1842 CHECK_RET (gp_list_get_name
1843 (dir_list, Cam_data.current_picture_number - 1, &filename));
1844
1845 Cam_data.pic_taken--;
1846 Cam_data.pic_left++;
1847 if (Cam_data.current_picture_number > Cam_data.pic_taken)
1848 {
1849 Cam_data.current_picture_number = Cam_data.pic_taken;
1850 }
1851 image_range.max--;
1852 if (image_range.max == 0)
1853 {
1854 sod[GPHOTO2_OPT_IMAGE_NUMBER].cap |= SANE_CAP_INACTIVE;
1855 }
1856 myinfo |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1857
1858 /* Too bad we don't have an API function for deleting a
1859 * list item. Instead, we copy all the entries in the
1860 * current list, skipping over the deleted entry, and then
1861 * replace the current list with the new list.
1862 */
1863 gp_list_new (&tmp_list);
1864
1865 for (i = 0; i < gp_list_count (dir_list); i++)
1866 {
1867 SANE_String_Const tfilename;
1868
1869 CHECK_RET (gp_list_get_name (dir_list, i, &tfilename));
1870 /* If not the one to delete, copy to the new list */
1871 if (strcmp (tfilename, filename) != 0)
1872 {
1873 CHECK_RET (gp_list_append (tmp_list, tfilename, NULL));
1874 }
1875 }
1876 gp_list_free (dir_list);
1877 dir_list = tmp_list;
1878
1879 }
1880 if (gphoto2_opt_autoinc)
1881 {
1882 if (Cam_data.current_picture_number <= Cam_data.pic_taken)
1883 {
1884 Cam_data.current_picture_number++;
1885
1886 myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1887
1888 /* get the image's resolution */
1889 /* OLD:
1890 set_res (Cam_data.Pictures[Cam_data.current_picture_number - 1].
1891 low_res);
1892 */
1893 set_res (gphoto2_opt_lowres);
1894 }
1895 DBG (4, "Increment count to %d (total %d)\n",
1896 Cam_data.current_picture_number, Cam_data.pic_taken);
1897 }
1898 return SANE_STATUS_EOF;
1899 }
1900
1901 /*
1902 * converter_fill_buffer - Fill line buffer with next input line from image.
1903 * Currently assumes jpeg, but this is where we would put the switch
1904 * to handle other image types.
1905 */
1906 static SANE_Int
converter_fill_buffer(void)1907 converter_fill_buffer (void)
1908 {
1909
1910 /*
1911 * FIXME: Current implementation reads one scan line at a time. Part
1912 * of the reason for this is in the original code is to give the frontend
1913 * a chance to update * the progress marker periodically. Since the gphoto2
1914 * driver sucks in the whole image before decoding it, perhaps we could
1915 * come up with a simpler implementation.
1916 */
1917
1918 SANE_Int lines = 1;
1919
1920 (void) jpeg_read_scanlines (&cinfo, dest_mgr->buffer, lines);
1921 (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, lines, (char *) linebuffer);
1922
1923 return cinfo.output_width * cinfo.output_components * lines;
1924 }
1925
1926 /*
1927 * converter_scan_complete - Check if all the data for the image has been read.
1928 * Currently assumes jpeg, but this is where we would put the
1929 * switch to handle other image types.
1930 */
1931 static SANE_Bool
converter_scan_complete(void)1932 converter_scan_complete (void)
1933 {
1934 if (cinfo.output_scanline >= cinfo.output_height)
1935 {
1936 return SANE_TRUE;
1937 }
1938 else
1939 {
1940 return SANE_FALSE;
1941 }
1942 }
1943
1944 /*
1945 * converter_init - Initialize image conversion data.
1946 * Currently assumes jpeg, but this is where we would put the
1947 * switch to handle other image types.
1948 */
1949 static SANE_Status
converter_init(SANE_Handle handle)1950 converter_init (SANE_Handle handle)
1951 {
1952 struct jpeg_error_mgr jerr;
1953 my_src_ptr src;
1954
1955 data_file_current_index = 0;
1956
1957 /* Basic check to see if this is really a jpeg file */
1958 if ( data_ptr[0] != 0xff || data_ptr[1] != 0xd8 ) {
1959 sane_cancel(handle);
1960 exit(1);
1961 return SANE_STATUS_INVAL;
1962 }
1963
1964 cinfo.err = jpeg_std_error (&jerr);
1965 jpeg_create_decompress (&cinfo);
1966
1967 cinfo.src =
1968 (struct jpeg_source_mgr *) (*cinfo.mem->
1969 alloc_small) ((j_common_ptr) & cinfo,
1970 JPOOL_PERMANENT,
1971 sizeof (my_source_mgr));
1972 src = (my_src_ptr) cinfo.src;
1973
1974 src->buffer = (JOCTET *) (*cinfo.mem->alloc_small) ((j_common_ptr) &
1975 cinfo,
1976 JPOOL_PERMANENT,
1977 1024 * sizeof (JOCTET));
1978 src->pub.init_source = jpeg_init_source;
1979 src->pub.fill_input_buffer = jpeg_fill_input_buffer;
1980 src->pub.skip_input_data = jpeg_skip_input_data;
1981 src->pub.resync_to_restart = jpeg_resync_to_restart; /* default */
1982 src->pub.term_source = jpeg_term_source;
1983 src->pub.bytes_in_buffer = 0;
1984 src->pub.next_input_byte = NULL;
1985
1986 (void) jpeg_read_header (&cinfo, TRUE);
1987 dest_mgr = sanei_jpeg_jinit_write_ppm (&cinfo);
1988 (void) jpeg_start_decompress (&cinfo);
1989
1990 parms.bytes_per_line = cinfo.output_width * 3; /* 3 colors */
1991 parms.pixels_per_line = cinfo.output_width;
1992 parms.lines = cinfo.output_height;
1993
1994 linebuffer_size = 0;
1995 linebuffer_index = 0;
1996
1997 return(SANE_STATUS_GOOD);
1998 }
1999