• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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