xref: /third_party/backends/backend/gphoto2.c (revision 141cc406)
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
116static SANE_Bool is_open = 0;
117
118/* Options selected by frontend: */
119static SANE_Bool gphoto2_opt_thumbnails;	/* Read thumbnails */
120static SANE_Bool gphoto2_opt_snap;	/* Take new picture */
121static SANE_Bool gphoto2_opt_lowres;	/* Set low resolution */
122static SANE_Bool gphoto2_opt_erase;	/* Erase after downloading */
123static SANE_Bool gphoto2_opt_autoinc;	/* Increment image number */
124static SANE_Bool dumpinquiry;	/* Dump status info */
125
126/* Used for jpeg decompression */
127static struct jpeg_decompress_struct cinfo;
128static djpeg_dest_ptr dest_mgr = NULL;
129
130static SANE_Int highres_height = 960, highres_width = 1280;
131static SANE_Int thumb_height = 120, thumb_width = 160;
132static SANE_String TopFolder;	/* Fixed part of path strings */
133static SANE_Int SubDirs = 1;	/* Search for Sub directories */
134
135static GPHOTO2 Cam_data;	/* Other camera data */
136
137static SANE_Range image_range = {
138  0,
139  0,
140  0
141};
142
143static SANE_String *folder_list;
144static SANE_Int current_folder = 0;
145
146static 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
304static 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
314CameraList *dir_list;
315Camera *camera;
316
317/* Buffer to hold line currently being processed by sane_read */
318static SANE_Byte *linebuffer = NULL;
319static SANE_Int linebuffer_size = 0;
320static SANE_Int linebuffer_index = 0;
321
322/* used for setting up commands */
323static SANE_Char cmdbuf[256];
324
325/* Structures used by gphoto2 API */
326static CameraAbilities abilities;
327static CameraFile *data_file;
328static const unsigned char *data_ptr;
329static unsigned long data_file_total_size, data_file_current_index;
330
331static SANE_Int hack_fd;
332
333#include <sys/time.h>
334#include <unistd.h>
335
336/* Device select/open/close */
337
338static SANE_Device dev[] = {
339  {
340   "0",
341   "Gphoto2",
342   "Supported",
343   "still camera"},
344};
345
346static const SANE_Device *devlist[] = {
347  dev + 0, 0
348};
349
350/*
351 * debug_func - called for gphoto2 debugging output (if enabled)
352 */
353static void
354#ifdef GPLOGFUNC_NO_VARGS
355debug_func (GPLogLevel level, const char *domain, const char *message,
356            void __sane_unused__ * data)
357#else
358debug_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 */
377static SANE_Int
378init_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 */
517static void
518close_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 */
537SANE_Int
538get_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 */
619static SANE_Int
620erase (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 */
646static SANE_Int
647change_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 */
659SANE_Status
660sane_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 */
938void
939sane_exit (void)
940{
941  close_gphoto2 ();
942}
943
944/*
945 * sane_get_devices() - From SANE API
946 */
947SANE_Status
948sane_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
961SANE_Status
962sane_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
1004void
1005sane_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
1018const SANE_Option_Descriptor *
1019sane_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
1028static SANE_Int myinfo = 0;
1029
1030/*
1031 * sane_control_option() - From SANE API
1032 */
1033
1034SANE_Status
1035sane_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 */
1297SANE_Status
1298sane_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
1314typedef struct
1315{
1316  struct jpeg_source_mgr pub;
1317  JOCTET *buffer;
1318}
1319my_source_mgr;
1320typedef my_source_mgr *my_src_ptr;
1321
1322METHODDEF (void)
1323jpeg_init_source (j_decompress_ptr __sane_unused__ cinfo)
1324{
1325  /* nothing to do */
1326}
1327
1328METHODDEF (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
1352METHODDEF (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
1369METHODDEF (void)
1370jpeg_term_source (j_decompress_ptr __sane_unused__ cinfo)
1371{
1372  /* no work necessary here */
1373}
1374
1375/*
1376 * sane_start() - From SANE API
1377 */
1378SANE_Status
1379sane_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 */
1484SANE_Status
1485sane_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 */
1538void
1539sane_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 */
1552SANE_Status
1553sane_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 */
1578SANE_Status
1579sane_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 */
1591static PictureInfo *
1592get_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 */
1648static SANE_Int
1649get_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 */
1671static SANE_Status
1672snap_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 */
1736static SANE_Int
1737read_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 */
1775static SANE_Int
1776read_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 */
1791static void
1792set_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 */
1813static SANE_Status
1814converter_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 */
1906static SANE_Int
1907converter_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 */
1931static SANE_Bool
1932converter_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 */
1949static SANE_Status
1950converter_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);
1960exit(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