Cleanup and changes to support gphoto2 API changes

DEVEL_2_0_BRANCH-1
Peter Fales 2001-09-25 00:33:07 +00:00
rodzic d4e68a7a4c
commit 222a47fa6c
1 zmienionych plików z 261 dodań i 108 usunięć

Wyświetl plik

@ -65,8 +65,10 @@
*************************************************************************** ***************************************************************************
This file implements a SANE backend for the Kodak DC-240 This file implements a SANE backend for digital cameras
digital camera. THIS IS EXTREMELY ALPHA CODE! USE AT YOUR OWN RISK!! supported by the gphoto2 libraries.
THIS IS EXTREMELY ALPHA CODE! USE AT YOUR OWN RISK!!
(feedback to: peter@fales.com (feedback to: peter@fales.com
@ -97,8 +99,10 @@
#include <gphoto2-core.h> #include <gphoto2-core.h>
#include <gphoto2-camera.h> #include <gphoto2-camera.h>
#include <gphoto2-debug.h>
#define CHECK(f) {int res = f; if (res < 0) {DBG (0,"ERROR: %s\n", gp_result_as_string (res)); exit (1);}} #define CHECK_EXIT(f) {int res = f; if (res < 0) {DBG (0,"ERROR: %s\n", gp_result_as_string (res)); exit (1);}}
#define CHECK_RET(f) {int res = f; if (res < 0) {DBG (0,"ERROR: %s\n", gp_result_as_string (res)); return (SANE_STATUS_INVAL);}}
#ifndef PATH_MAX #ifndef PATH_MAX
# define PATH_MAX 1024 # define PATH_MAX 1024
@ -107,27 +111,25 @@
#define MAGIC (void *)0xab730324 #define MAGIC (void *)0xab730324
#define GPHOTO2_CONFIG_FILE "gphoto2.conf" #define GPHOTO2_CONFIG_FILE "gphoto2.conf"
# define DEFAULT_TTY "usb:"
static SANE_Bool is_open = 0; static SANE_Bool is_open = 0;
static SANE_Bool gphoto2_opt_thumbnails; /* Options selected by frontend: */
static SANE_Bool gphoto2_opt_snap; static SANE_Bool gphoto2_opt_thumbnails; /* Read thumbnails */
static SANE_Bool gphoto2_opt_lowres; static SANE_Bool gphoto2_opt_snap; /* Take new picture */
static SANE_Bool gphoto2_opt_erase; static SANE_Bool gphoto2_opt_lowres; /* Set low resolution */
static SANE_Bool gphoto2_opt_autoinc; static SANE_Bool gphoto2_opt_erase; /* Erase after downloading */
static SANE_Bool dumpinquiry; static SANE_Bool gphoto2_opt_autoinc; /* Increment image number */
static SANE_Bool dumpinquiry; /* Dump status info */
/* Used for jpeg decompression */
static struct jpeg_decompress_struct cinfo; static struct jpeg_decompress_struct cinfo;
static djpeg_dest_ptr dest_mgr = NULL; static djpeg_dest_ptr dest_mgr = NULL;
static SANE_Int highres_height = 960, highres_width = 1280; static SANE_Int highres_height = 960, highres_width = 1280;
static SANE_Int lowres_height = 480, lowres_width = 640;
static SANE_Int thumb_height = 120, thumb_width = 160; static SANE_Int thumb_height = 120, thumb_width = 160;
static SANE_String TopFolder; static SANE_String TopFolder; /* Fixed part of path strings */
static SANE_String Gphoto2Path = "gphoto2";
static GPHOTO2 Cam_data; static GPHOTO2 Cam_data; /* Other camera data */
static SANE_Range image_range = { static SANE_Range image_range = {
0, 0,
@ -317,6 +319,8 @@ static SANE_Int linebuffer_index = 0;
/* used for setting up commands */ /* used for setting up commands */
static SANE_Char cmdbuf[256]; static SANE_Char cmdbuf[256];
/* Structures used by gphoto2 API */
static CameraAbilities *abilities;
static CameraFile *data_file; static CameraFile *data_file;
static const char *data_ptr; static const char *data_ptr;
static long data_size, data_cur; static long data_size, data_cur;
@ -324,42 +328,96 @@ static long data_size, data_cur;
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
/*
* init_gphoto2() - Initialize interface to camera using gphoto2 API
*/
static SANE_Int static SANE_Int
init_gphoto2 (void) init_gphoto2 (void)
{ {
SANE_Int n; SANE_Int n, entries;
CameraList *list; CameraList *list;
DBG (1, "GPHOTO2 Backend 05/16/01\n"); DBG (1, "GPHOTO2 Backend 05/16/01\n");
CHECK (gp_camera_new (&camera)); CHECK_RET (gp_camera_new (&camera));
CHECK (gp_camera_set_model (camera, (char *) Cam_data.camera_name));
CHECK (gp_camera_set_port_path (camera, (char *) Cam_data.tty_name)); if (!Cam_data.camera_name)
CHECK (gp_camera_init (camera)); {
CHECK (gp_list_new (&list)); DBG (0, "Camera name not specified in config file\n");
CHECK (gp_camera_folder_list_folders (camera, "/PCCARD/DCIM", list)); exit (1);
}
CHECK_RET (gp_camera_set_model (camera, (char *) Cam_data.camera_name));
if (!Cam_data.port)
{
DBG (0, "Camera port not specified in config file\n");
exit (1);
}
CHECK_RET (gp_camera_set_port_path (camera, (char *) Cam_data.port));
if (Cam_data.speed)
{
CHECK_RET (gp_camera_set_port_speed (camera, Cam_data.speed));
}
CHECK_RET (gp_camera_init (camera));
CHECK_RET (gp_list_new (&list));
CHECK_RET (gp_abilities_new (&abilities));
CHECK_RET (gp_camera_abilities_by_name (Cam_data.camera_name, abilities));
if (!(abilities->operations & GP_OPERATION_CAPTURE_IMAGE))
{
DBG (0, "Camera does not support image capture\n");
return SANE_STATUS_INVAL;
}
for (n = 0; abilities->speed[n]; n++)
{
if (abilities->speed[n] == Cam_data.speed)
{
break;
}
if (abilities->speed[n] == 0)
{
DBG (0,
"%s: error: %d is not a valid speed for this camers. Use \"gphoto2 --camera \"%s\" --abilities\" for list.\n",
"init_gphoto2", Cam_data.camera_name, Cam_data.speed);
return SANE_STATUS_INVAL;
}
}
CHECK_RET (gp_camera_folder_list_folders (camera, "/PCCARD/DCIM", list));
n = gp_list_count (list); n = gp_list_count (list);
if (n < 0) if (n < 0)
{ {
return -1; DBG (0, "Unable to get file list\n");
return SANE_STATUS_INVAL;
} }
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
/*
* close_gphoto2() - Shutdown camera interface
*/
static void static void
close_gphoto2 (SANE_Int fd) close_gphoto2 (void)
{ {
/* /*
* Put the camera back to 9600 baud * Put the camera back to 9600 baud
*/ */
if (close (fd) == -1) if (gp_camera_unref (camera))
{ {
DBG (1, "close_gphoto2: error: could not close device\n"); DBG (1, "close_gphoto2: error: could not close device\n");
} }
} }
int /*
* get_info() - Get overall information about camera: folder names,
* number of pictures, etc.
*/
SANE_Int
get_info (void) get_info (void)
{ {
SANE_String_Const val; SANE_String_Const val;
@ -416,10 +474,15 @@ get_info (void)
Cam_data.pic_taken = 0; Cam_data.pic_taken = 0;
Cam_data.pic_left = 1; /* Just a guess! */ Cam_data.pic_left = 1; /* Just a guess! */
return 0; return SANE_STATUS_GOOD;
} }
/*
* erase() - erase file from camera corresponding to
* current picture number. Does not update any of the other
* backend data structures.
*/
static SANE_Int static SANE_Int
erase (void) erase (void)
{ {
@ -427,14 +490,18 @@ erase (void)
sprintf (cmdbuf, "%s/%s", (char *) TopFolder, sprintf (cmdbuf, "%s/%s", (char *) TopFolder,
(const char *) folder_list[current_folder]); (const char *) folder_list[current_folder]);
CHECK (gp_list_get_name CHECK_RET (gp_list_get_name
(dir_list, Cam_data.current_picture_number - 1, &filename)); (dir_list, Cam_data.current_picture_number - 1, &filename));
CHECK (gp_camera_file_delete (camera, cmdbuf, filename)); CHECK_RET (gp_camera_file_delete (camera, cmdbuf, filename));
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
/*
* change_res() - FIXME: Would like to set resolution, but haven't figure
* out how to control that yet.
*/
static SANE_Int static SANE_Int
change_res (SANE_Byte res) change_res (SANE_Byte res)
{ {
@ -443,10 +510,15 @@ change_res (SANE_Byte res)
} }
/*
* sane_init() - Initialization function from SANE API. Initialize some
* data structures, verify that all the necessary config information
* is present, and initialize gphoto2
*/
SANE_Status SANE_Status
sane_init (SANE_Int * version_code, SANE_Auth_Callback UNUSEDARG authorize) sane_init (SANE_Int * version_code, SANE_Auth_Callback UNUSEDARG authorize)
{ {
SANE_Int n, entries;
SANE_Char f[] = "sane_init"; SANE_Char f[] = "sane_init";
SANE_Char dev_name[PATH_MAX], *p; SANE_Char dev_name[PATH_MAX], *p;
SANE_Char buf[256]; SANE_Char buf[256];
@ -457,21 +529,21 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback UNUSEDARG authorize)
if (getenv ("GP_DEBUG")) if (getenv ("GP_DEBUG"))
{ {
CHECK (gp_init (atoi (getenv ("GP_DEBUG")))); gp_debug_set_level (atoi (getenv ("GP_DEBUG")));
} }
else else
{ {
CHECK (gp_init (GP_DEBUG_NONE)); /* NOTE: One side effect of gp_debug_set_level() is that
* it initializes the gphoto2 library, so we need it even
* when the level is 0.
*/
gp_debug_set_level (0);
} }
if (version_code) if (version_code)
*version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, 0); *version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, 0);
fp = sanei_config_open (GPHOTO2_CONFIG_FILE); fp = sanei_config_open (GPHOTO2_CONFIG_FILE);
/* defaults */
Cam_data.tty_name = DEFAULT_TTY;
if (!fp) if (!fp)
{ {
/* default to /dev/whatever instead of insisting on config file */ /* default to /dev/whatever instead of insisting on config file */
@ -492,19 +564,18 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback UNUSEDARG authorize)
continue; /* ignore empty lines */ continue; /* ignore empty lines */
if (strncmp (dev_name, "port=", 5) == 0) if (strncmp (dev_name, "port=", 5) == 0)
{ {
SANE_Int n, entries;
p = dev_name + 5; p = dev_name + 5;
if (p) if (p)
Cam_data.tty_name = strdup (p); Cam_data.port = strdup (p);
DBG (20, "Config file port=%s\n", Cam_data.tty_name); DBG (20, "Config file port=%s\n", Cam_data.port);
CHECK (entries = gp_port_count_get ()); /* Validate port */
CHECK_RET (entries = gp_port_count_get ());
for (n = 0; n < entries; n++) for (n = 0; n < entries; n++)
{ {
gp_port_info info; gp_port_info info;
CHECK (gp_port_info_get (n, &info)); CHECK_RET (gp_port_info_get (n, &info));
if (strcmp (Cam_data.tty_name, info.path) == 0) if (strcmp (Cam_data.port, info.path) == 0)
{ {
break; break;
} }
@ -513,22 +584,21 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback UNUSEDARG authorize)
{ {
DBG (0, DBG (0,
"%s: error: %s is not a valid gphoto2 port. Use \"gphoto2 --list-ports\" for list.\n", "%s: error: %s is not a valid gphoto2 port. Use \"gphoto2 --list-ports\" for list.\n",
f, Cam_data.tty_name); "init_gphoto2", Cam_data.port);
exit (1); exit (1);
} }
} }
else if (strncmp (dev_name, "camera=", 7) == 0) else if (strncmp (dev_name, "camera=", 7) == 0)
{ {
SANE_Int n, entries;
Cam_data.camera_name = strdup (dev_name + 7); Cam_data.camera_name = strdup (dev_name + 7);
DBG (20, "Config file camera=%s\n", Cam_data.camera_name); DBG (20, "Config file camera=%s\n", Cam_data.camera_name);
sprintf (buf, "Image selection - %s", Cam_data.camera_name); sprintf (buf, "Image selection - %s", Cam_data.camera_name);
CHECK (entries = gp_camera_count ()); CHECK_RET (entries = gp_camera_count ());
for (n = 0; n < entries; n++) for (n = 0; n < entries; n++)
{ {
const char *buf; const char *buf;
CHECK (gp_camera_name (n, &buf)); CHECK_RET (gp_camera_name (n, &buf));
if (strcmp (Cam_data.camera_name, buf) == 0) if (strcmp (Cam_data.camera_name, buf) == 0)
{ {
break; break;
@ -548,18 +618,19 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback UNUSEDARG authorize)
{ {
dumpinquiry = SANE_TRUE; dumpinquiry = SANE_TRUE;
} }
else if (strncmp (dev_name, "high_resolution=", 16) == 0) else if (strncmp (dev_name, "speed=", 6) == 0)
{ {
sscanf (&dev_name[16], "%dx%d", &highres_width, sscanf (&dev_name[6], "%d", &Cam_data.speed);
&highres_height);
DBG (20, "Config file high_resolution=%ux%u\n", highres_width, DBG (20, "Config file speed=%u\n", Cam_data.speed);
highres_height);
} }
else if (strncmp (dev_name, "low_resolution=", 15) == 0) else if (strncmp (dev_name, "resolution=", 11) == 0)
{ {
sscanf (&dev_name[15], "%dx%d", &lowres_width, &lowres_height); sscanf (&dev_name[11], "%dx%d", &highres_width,
DBG (20, "Config file low_resolution=%ux%u\n", lowres_width, &highres_height);
lowres_height); DBG (20, "Config file resolution=%ux%u\n", highres_width,
highres_height);
} }
else if (strncmp (dev_name, "thumb_resolution=", 17) == 0) else if (strncmp (dev_name, "thumb_resolution=", 17) == 0)
{ {
@ -572,22 +643,17 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback UNUSEDARG authorize)
TopFolder = strdup (&dev_name[10]); TopFolder = strdup (&dev_name[10]);
DBG (20, "Config file topfolder=%s\n", TopFolder); DBG (20, "Config file topfolder=%s\n", TopFolder);
} }
else if (strncmp (dev_name, "gphoto2path=", 12) == 0)
{
Gphoto2Path = strdup (&dev_name[12]);
DBG (20, "Config file gphoto2path=%s\n", Gphoto2Path);
}
} }
fclose (fp); fclose (fp);
} }
if (init_gphoto2 () == -1) if (init_gphoto2 () != SANE_STATUS_GOOD)
return SANE_STATUS_INVAL; return SANE_STATUS_INVAL;
if (get_info () == -1) if (get_info () != SANE_STATUS_GOOD)
{ {
DBG (1, "error: could not get info\n"); DBG (1, "error: could not get info\n");
close_gphoto2 (Cam_data.fd); close_gphoto2 ();
return SANE_STATUS_INVAL; return SANE_STATUS_INVAL;
} }
@ -612,20 +678,63 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback UNUSEDARG authorize)
if (dumpinquiry) if (dumpinquiry)
{ {
SANE_Int x = 0;
DBG (0, "\nCamera information:\n~~~~~~~~~~~~~~~~~\n\n"); DBG (0, "\nCamera information:\n~~~~~~~~~~~~~~~~~\n\n");
DBG (0, "Model...........: DC%s\n", "240"); DBG (0, "Model : %s\n", abilities->model);
DBG (0, "Firmware version: %d.%d\n", Cam_data.ver_major, DBG (0, "Pictures : %d\n", Cam_data.pic_taken);
Cam_data.ver_minor); DBG (0, "Serial port support : %s\n",
DBG (0, "Pictures........: %d/%d\n", Cam_data.pic_taken, SERIAL_SUPPORTED (abilities->port) ? "yes" : "no");
Cam_data.pic_taken + Cam_data.pic_left); DBG (0, "Parallel port support : %s\n",
DBG (0, "Battery state...: %s\n", PARALLEL_SUPPORTED (abilities->port) ? "yes" : "no");
Cam_data.flags.low_batt == 0 ? "good" : (Cam_data.flags.low_batt == DBG (0, "USB support : %s\n",
1 ? "weak" : "empty")); USB_SUPPORTED (abilities->port) ? "yes" : "no");
DBG (0, "IEEE1394 support : %s\n",
IEEE1394_SUPPORTED (abilities->port) ? "yes" : "no");
DBG (0, "Network support : %s\n",
NETWORK_SUPPORTED (abilities->port) ? "yes" : "no");
if (abilities->speed[0] != 0)
{
DBG (0, "Transfer speeds supported :\n");
do
{
DBG (0, " : %i\n",
abilities->speed[x]);
x++;
}
while (abilities->speed[x] != 0);
}
DBG (0, "Capture choices :\n");
if (abilities->operations & GP_OPERATION_CAPTURE_IMAGE)
DBG (0, " : Image\n");
if (abilities->operations & GP_OPERATION_CAPTURE_VIDEO)
DBG (0, " : Video\n");
if (abilities->operations & GP_OPERATION_CAPTURE_AUDIO)
DBG (0, " : Audio\n");
if (abilities->operations & GP_OPERATION_CAPTURE_PREVIEW)
DBG (0, " : Preview\n");
DBG (0, "Configuration support : %s\n",
abilities->operations & GP_OPERATION_CONFIG ? "yes" : "no");
DBG (0, "Delete files on camera support : %s\n",
abilities->
file_operations & GP_FILE_OPERATION_DELETE ? "yes" : "no");
DBG (0, "File preview (thumbnail) support : %s\n",
abilities->
file_operations & GP_FILE_OPERATION_PREVIEW ? "yes" : "no");
DBG (0, "File upload support : %s\n",
abilities->
folder_operations & GP_FOLDER_OPERATION_PUT_FILE ? "yes" : "no");
} }
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
/*
* sane_exit() - Required by SANE API, but otherwise not used
*/
void void
sane_exit (void) sane_exit (void)
{ {
@ -645,6 +754,9 @@ static const SANE_Device *devlist[] = {
dev + 0, 0 dev + 0, 0
}; };
/*
* sane_get_devices() - From SANE API
*/
SANE_Status SANE_Status
sane_get_devices (const SANE_Device *** device_list, SANE_Bool sane_get_devices (const SANE_Device *** device_list, SANE_Bool
UNUSEDARG local_only) UNUSEDARG local_only)
@ -656,6 +768,10 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
/*
* sane_open() - From SANE API
*/
SANE_Status SANE_Status
sane_open (SANE_String_Const devicename, SANE_Handle * handle) sane_open (SANE_String_Const devicename, SANE_Handle * handle)
{ {
@ -695,6 +811,10 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
/*
* sane_close() - From SANE API
*/
void void
sane_close (SANE_Handle handle) sane_close (SANE_Handle handle)
{ {
@ -705,6 +825,10 @@ sane_close (SANE_Handle handle)
DBG (127, "sane_close returning\n"); DBG (127, "sane_close returning\n");
} }
/*
* sane_get_option_descriptor() - From SANE API
*/
const SANE_Option_Descriptor * const SANE_Option_Descriptor *
sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
{ {
@ -717,6 +841,10 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
static SANE_Int myinfo = 0; static SANE_Int myinfo = 0;
/*
* sane_control_option() - From SANE API
*/
SANE_Status SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option, sane_control_option (SANE_Handle handle, SANE_Int option,
SANE_Action action, void *value, SANE_Int * info) SANE_Action action, void *value, SANE_Int * info)
@ -797,7 +925,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
else else
{ {
/* deactivate the resolution setting */ /* deactivate the resolution setting */
/* sod [GPHOTO2_OPT_LOWRES].cap |= SANE_CAP_INACTIVE; */ sod[GPHOTO2_OPT_LOWRES].cap |= SANE_CAP_INACTIVE;
/* and activate the image number selector, if there are /* and activate the image number selector, if there are
* pictures available */ * pictures available */
if (Cam_data.current_picture_number) if (Cam_data.current_picture_number)
@ -814,7 +942,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
gphoto2_opt_lowres = !!*(SANE_Word *) value; gphoto2_opt_lowres = !!*(SANE_Word *) value;
myinfo |= SANE_INFO_RELOAD_PARAMS; myinfo |= SANE_INFO_RELOAD_PARAMS;
/* XXX - change the number of pictures left depending on resolution /* FIXME - change the number of pictures left depending on resolution
perhaps just call get_info again? perhaps just call get_info again?
*/ */
set_res (gphoto2_opt_lowres); set_res (gphoto2_opt_lowres);
@ -838,24 +966,24 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
gphoto2_opt_snap = 0; gphoto2_opt_snap = 0;
/* deactivate the resolution setting */ /* deactivate the resolution setting */
/* sod[GPHOTO2_OPT_LOWRES].cap |= SANE_CAP_INACTIVE; */ sod[GPHOTO2_OPT_LOWRES].cap |= SANE_CAP_INACTIVE;
/* and activate the image number selector */ /* and activate the image number selector */
sod[GPHOTO2_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE; sod[GPHOTO2_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE;
myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
DBG (1, "Fixme: Set all defaults here!\n"); DBG (1, "FIXME: Set all defaults here!\n");
break; break;
case GPHOTO2_OPT_INIT_GPHOTO2: case GPHOTO2_OPT_INIT_GPHOTO2:
if ((Cam_data.fd = init_gphoto2 ()) == -1) if (init_gphoto2 () != SANE_STATUS_GOOD)
{ {
return SANE_STATUS_INVAL; return SANE_STATUS_INVAL;
} }
if (get_info () == -1) if (get_info () != SANE_STATUS_GOOD)
{ {
DBG (1, "error: could not get info\n"); DBG (1, "error: could not get info\n");
close_gphoto2 (Cam_data.fd); close_gphoto2 ();
return SANE_STATUS_INVAL; return SANE_STATUS_INVAL;
} }
@ -932,6 +1060,9 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
/*
* sane_get_parameters() - From SANE API
*/
SANE_Status SANE_Status
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params) sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
{ {
@ -1010,6 +1141,9 @@ jpeg_term_source (j_decompress_ptr UNUSEDARG cinfo)
/* no work necessary here */ /* no work necessary here */
} }
/*
* sane_start() - From SANE API
*/
SANE_Status SANE_Status
sane_start (SANE_Handle handle) sane_start (SANE_Handle handle)
{ {
@ -1057,24 +1191,24 @@ sane_start (SANE_Handle handle)
} }
} }
CHECK (gp_file_new (&data_file)); CHECK_RET (gp_file_new (&data_file));
sprintf (cmdbuf, "%s/%s", (char *) TopFolder, sprintf (cmdbuf, "%s/%s", (char *) TopFolder,
(const char *) folder_list[current_folder]); (const char *) folder_list[current_folder]);
CHECK (gp_list_get_name CHECK_RET (gp_list_get_name
(dir_list, Cam_data.current_picture_number - 1, &filename)); (dir_list, Cam_data.current_picture_number - 1, &filename));
CHECK (gp_camera_file_get (camera, cmdbuf, filename, CHECK_RET (gp_camera_file_get (camera, cmdbuf, filename,
gphoto2_opt_thumbnails ? GP_FILE_TYPE_PREVIEW : gphoto2_opt_thumbnails ? GP_FILE_TYPE_PREVIEW
GP_FILE_TYPE_NORMAL, data_file)); : GP_FILE_TYPE_NORMAL, data_file));
CHECK (gp_file_get_mime_type (data_file, &mime_type)); CHECK_RET (gp_file_get_mime_type (data_file, &mime_type));
if (strcmp (GP_MIME_JPEG, mime_type) != 0) if (strcmp (GP_MIME_JPEG, mime_type) != 0)
{ {
DBG (0, "FIXME - Only jpeg files currently supported\n"); DBG (0, "FIXME - Only jpeg files currently supported\n");
exit (1); exit (1);
} }
CHECK (gp_file_get_data_and_size (data_file, &data_ptr, &data_size)); CHECK_RET (gp_file_get_data_and_size (data_file, &data_ptr, &data_size));
data_cur = 0; data_cur = 0;
@ -1127,6 +1261,9 @@ sane_start (SANE_Handle handle)
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
/*
* sane_read() - From SANE API
*/
SANE_Status SANE_Status
sane_read (SANE_Handle UNUSEDARG handle, SANE_Byte * data, sane_read (SANE_Handle UNUSEDARG handle, SANE_Byte * data,
SANE_Int max_length, SANE_Int * length) SANE_Int max_length, SANE_Int * length)
@ -1167,12 +1304,15 @@ sane_read (SANE_Handle UNUSEDARG handle, SANE_Byte * data,
sprintf (cmdbuf, "%s/%s", (char *) TopFolder, sprintf (cmdbuf, "%s/%s", (char *) TopFolder,
(const char *) folder_list[current_folder]); (const char *) folder_list[current_folder]);
CHECK (gp_list_get_name CHECK_RET (gp_list_get_name
(dir_list, Cam_data.current_picture_number - 1, &filename)); (dir_list, Cam_data.current_picture_number - 1,
&filename));
Cam_data.pic_taken--; Cam_data.pic_taken--;
Cam_data.pic_left++; Cam_data.pic_left++;
if ( Cam_data.current_picture_number > Cam_data.pic_taken ) {
Cam_data.current_picture_number = Cam_data.pic_taken; Cam_data.current_picture_number = Cam_data.pic_taken;
}
image_range.max--; image_range.max--;
if (image_range.max == 0) if (image_range.max == 0)
{ {
@ -1191,11 +1331,11 @@ sane_read (SANE_Handle UNUSEDARG handle, SANE_Byte * data,
{ {
SANE_String_Const tfilename; SANE_String_Const tfilename;
CHECK (gp_list_get_name (dir_list, i, &tfilename)); CHECK_RET (gp_list_get_name (dir_list, i, &tfilename));
/* If not the one to delete, copy to the new list */ /* If not the one to delete, copy to the new list */
if (strcmp (tfilename, filename) != 0) if (strcmp (tfilename, filename) != 0)
{ {
CHECK (gp_list_append (tmp_list, tfilename, NULL)); CHECK_RET (gp_list_append (tmp_list, tfilename, NULL));
} }
} }
gp_list_free (dir_list); gp_list_free (dir_list);
@ -1223,7 +1363,14 @@ sane_read (SANE_Handle UNUSEDARG handle, SANE_Byte * data,
return SANE_STATUS_EOF; return SANE_STATUS_EOF;
} }
/* XXX - we should read more than 1 line at a time here */ /*
* FIXME: Current implementation reads one scan line at a time. Part
* of the reason for this is in the original code is to give the frontend
* a chance to update * the progress marker periodically. Since the gphoto2
* driver sucks in the whole image before decoding it, perhaps we could
* come up with a simpler implementation.
*/
lines = 1; lines = 1;
(void) jpeg_read_scanlines (&cinfo, dest_mgr->buffer, lines); (void) jpeg_read_scanlines (&cinfo, dest_mgr->buffer, lines);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, lines, (char *) linebuffer); (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, lines, (char *) linebuffer);
@ -1242,6 +1389,9 @@ sane_read (SANE_Handle UNUSEDARG handle, SANE_Byte * data,
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
/*
* sane_cancel() - From SANE API
*/
void void
sane_cancel (SANE_Handle UNUSEDARG handle) sane_cancel (SANE_Handle UNUSEDARG handle)
{ {
@ -1253,6 +1403,9 @@ sane_cancel (SANE_Handle UNUSEDARG handle)
DBG (4, "sane_cancel: not scanning - nothing to do\n"); DBG (4, "sane_cancel: not scanning - nothing to do\n");
} }
/*
* sane_set_io_mode() - From SANE API
*/
SANE_Status SANE_Status
sane_set_io_mode (SANE_Handle UNUSEDARG handle, SANE_Bool sane_set_io_mode (SANE_Handle UNUSEDARG handle, SANE_Bool
UNUSEDARG non_blocking) UNUSEDARG non_blocking)
@ -1260,6 +1413,9 @@ sane_set_io_mode (SANE_Handle UNUSEDARG handle, SANE_Bool
return SANE_STATUS_UNSUPPORTED; return SANE_STATUS_UNSUPPORTED;
} }
/*
* sane_get_select_fd() - From SANE API
*/
SANE_Status SANE_Status
sane_get_select_fd (SANE_Handle UNUSEDARG handle, SANE_Int * UNUSEDARG fd) sane_get_select_fd (SANE_Handle UNUSEDARG handle, SANE_Int * UNUSEDARG fd)
{ {
@ -1322,6 +1478,9 @@ get_pictures_info (void)
return pics; return pics;
} }
/*
* sane_picture_info() - get info about picture p
*/
static SANE_Int static SANE_Int
get_picture_info (PictureInfo * pic, SANE_Int p) get_picture_info (PictureInfo * pic, SANE_Int p)
{ {
@ -1358,23 +1517,23 @@ snap_pic (void)
return SANE_STATUS_INVAL; return SANE_STATUS_INVAL;
} }
CHECK (gp_camera_capture (camera, GP_OPERATION_CAPTURE_IMAGE, &path)); CHECK_RET (gp_camera_capture (camera, GP_OPERATION_CAPTURE_IMAGE, &path));
/* Can't just increment picture count, because if the camera has /* Can't just increment picture count, because if the camera has
* zero pictures we may not know the folder name. Start over * zero pictures we may not know the folder name. Start over
* with get_info and get_pictures_info * with get_info and get_pictures_info
*/ */
if (get_info () == -1) if (get_info () != SANE_STATUS_GOOD)
{ {
DBG (1, "error: could not get info\n"); DBG (1, "error: could not get info\n");
close_gphoto2 (Cam_data.fd); close_gphoto2 ();
return SANE_STATUS_INVAL; return SANE_STATUS_INVAL;
} }
if (get_pictures_info () == NULL) if (get_pictures_info () == NULL)
{ {
DBG (1, "%s: Failed to get new picture info\n", f); DBG (1, "%s: Failed to get new picture info\n", f);
/* XXX - I guess we should try to erase the image here */ /* FIXME - I guess we should try to erase the image here */
return SANE_STATUS_INVAL; return SANE_STATUS_INVAL;
} }
@ -1414,11 +1573,11 @@ read_dir (SANE_String dir, SANE_Bool read_files)
if (read_files) if (read_files)
{ {
CHECK (gp_camera_folder_list_files (camera, dir, dir_list)); CHECK_RET (gp_camera_folder_list_files (camera, dir, dir_list));
} }
else else
{ {
CHECK (gp_camera_folder_list_folders (camera, dir, dir_list)); CHECK_RET (gp_camera_folder_list_folders (camera, dir, dir_list));
} }
retval = gp_list_count (dir_list); retval = gp_list_count (dir_list);
@ -1439,8 +1598,6 @@ read_info (SANE_String_Const fname)
strcat (path, "\\"); strcat (path, "\\");
strcat (path, fname); strcat (path, fname);
return 0; return 0;
} }
@ -1450,18 +1607,14 @@ read_info (SANE_String_Const fname)
static void static void
set_res (SANE_Int lowres) set_res (SANE_Int lowres)
{ {
lowres - lowres;
if (gphoto2_opt_thumbnails) if (gphoto2_opt_thumbnails)
{ {
parms.bytes_per_line = THUMB_WIDTH * 3; parms.bytes_per_line = THUMB_WIDTH * 3;
parms.pixels_per_line = THUMB_WIDTH; parms.pixels_per_line = THUMB_WIDTH;
parms.lines = THUMB_HEIGHT; parms.lines = THUMB_HEIGHT;
} }
else if (lowres)
{
parms.bytes_per_line = LOWRES_WIDTH * 3;
parms.pixels_per_line = LOWRES_WIDTH;
parms.lines = LOWRES_HEIGHT;
}
else else
{ {
parms.bytes_per_line = HIGHRES_WIDTH * 3; parms.bytes_per_line = HIGHRES_WIDTH * 3;