kopia lustrzana https://gitlab.com/sane-project/backends
Various minor fixes
rodzic
08ae4502e3
commit
4174ca9ded
|
@ -1,3 +1,19 @@
|
||||||
|
/* Please note! This is extremely alpha code, and is really intended as
|
||||||
|
* a "proof of concept" since I don't yet know whether it's going to
|
||||||
|
* to be practical and/or possible to implement a the complete backend.
|
||||||
|
* The current implemenation uses the gphoto2 command as the interface
|
||||||
|
* to the camera - the longterm plan is access the cameras directly by
|
||||||
|
* linking with the gphoto2 libraries. It's also been tested with only
|
||||||
|
* one camera model, the Kodak DC240 which happens to be the camera I
|
||||||
|
* have. I'm very interested in learning what it would take to support
|
||||||
|
* more cameras.
|
||||||
|
*
|
||||||
|
* However, having said that, I've already found it to be quite useful
|
||||||
|
* even in its current form - one reason is that gphoto2 provides access
|
||||||
|
* to the camera via USB which is not supported by the regular DC240
|
||||||
|
* backend and is dramatically faster than the serial port.
|
||||||
|
*/
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _S_A_N_E - Scanner Access Now Easy.
|
* _S_A_N_E - Scanner Access Now Easy.
|
||||||
|
|
||||||
|
@ -285,14 +301,20 @@ static SANE_Parameters parms = {
|
||||||
8, /* Number of bits per sample. */
|
8, /* Number of bits per sample. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Linked list of file names in the current folder */
|
||||||
static struct cam_dirlist *dir_head = NULL;
|
static struct cam_dirlist *dir_head = NULL;
|
||||||
|
|
||||||
|
/* Buffer to hold line currently being processed by sane_read */
|
||||||
static SANE_Byte *linebuffer = NULL;
|
static SANE_Byte *linebuffer = NULL;
|
||||||
static SANE_Int linebuffer_size = 0;
|
static SANE_Int linebuffer_size = 0;
|
||||||
static SANE_Int linebuffer_index = 0;
|
static SANE_Int linebuffer_index = 0;
|
||||||
|
|
||||||
static SANE_Byte tmpstr[256];
|
/* gphoto2 command currently being executed */
|
||||||
|
static SANE_Char cmdbuf[256];
|
||||||
|
/* The pipe corresponding to cmdbuf */
|
||||||
static FILE *cmdpipe;
|
static FILE *cmdpipe;
|
||||||
|
/* String read from cmdpipe */
|
||||||
|
static SANE_Byte tmpstr[256];
|
||||||
|
|
||||||
static SANE_Byte name_buf[60];
|
static SANE_Byte name_buf[60];
|
||||||
|
|
||||||
|
@ -302,7 +324,6 @@ static SANE_Byte name_buf[60];
|
||||||
static SANE_Int
|
static SANE_Int
|
||||||
init_gphoto2 (void)
|
init_gphoto2 (void)
|
||||||
{
|
{
|
||||||
SANE_Char cmdbuf[256];
|
|
||||||
SANE_Int entries, n;
|
SANE_Int entries, n;
|
||||||
|
|
||||||
DBG (1, "GPHOTO2 Backend 05/16/01\n");
|
DBG (1, "GPHOTO2 Backend 05/16/01\n");
|
||||||
|
@ -404,14 +425,28 @@ get_info (void)
|
||||||
static SANE_Int
|
static SANE_Int
|
||||||
erase (void)
|
erase (void)
|
||||||
{
|
{
|
||||||
|
sprintf ((char *) cmdbuf,
|
||||||
|
"%s --camera \"%s\" --port %s --folder %s/%s --stdout -d %d",
|
||||||
|
(char *) Gphoto2Path, (char *) Camera.camera_name,
|
||||||
|
(char *) Camera.tty_name, (char *) TopFolder,
|
||||||
|
(char *) folder_list[current_folder],
|
||||||
|
Camera.current_picture_number);
|
||||||
|
cmdpipe = popen ((char *) cmdbuf, "r");
|
||||||
|
if (cmdpipe == NULL)
|
||||||
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (cmdpipe);
|
||||||
|
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SANE_Int
|
static SANE_Int
|
||||||
change_res (SANE_Byte res)
|
change_res (SANE_Byte res)
|
||||||
{
|
{
|
||||||
|
|
||||||
return 0;
|
return (res - res);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,7 +473,8 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback UNUSEDARG authorize)
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
/* default to /dev/whatever instead of insisting on config file */
|
/* default to /dev/whatever instead of insisting on config file */
|
||||||
DBG (1, "%s: missing config file '%s'\n", f, GPHOTO2_CONFIG_FILE);
|
DBG (1, "warning: %s: missing config file '%s'\n", f,
|
||||||
|
GPHOTO2_CONFIG_FILE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -454,16 +490,90 @@ 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)
|
||||||
Camera.tty_name = strdup (p);
|
Camera.tty_name = strdup (p);
|
||||||
DBG (20, "Config file port=%s\n", Camera.tty_name);
|
DBG (20, "Config file port=%s\n", Camera.tty_name);
|
||||||
|
sprintf ((char *) cmdbuf, "%s -q --list-ports",
|
||||||
|
(char *) Gphoto2Path);
|
||||||
|
cmdpipe = popen ((char *) cmdbuf, "r");
|
||||||
|
if (cmdpipe == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fgets ((char *) tmpstr, sizeof (tmpstr), cmdpipe);
|
||||||
|
n = sscanf ((char *) tmpstr, "%d", &entries);
|
||||||
|
if (n == 0 || entries < 1)
|
||||||
|
{
|
||||||
|
DBG (0, "%s: error: Can't list available ports\n", f);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
for (n = 0; n < entries; n++)
|
||||||
|
{
|
||||||
|
fgets ((char *) tmpstr, sizeof (tmpstr), cmdpipe);
|
||||||
|
if (strchr (tmpstr, ' '))
|
||||||
|
{
|
||||||
|
*strchr (tmpstr, ' ') = '\0';
|
||||||
|
}
|
||||||
|
if (strcmp (Camera.tty_name, tmpstr) == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n == entries)
|
||||||
|
{
|
||||||
|
DBG (0,
|
||||||
|
"%s: error: %s is not a valid gphoto2 port. Use \"gphoto2 --list-ports\" for list.\n",
|
||||||
|
f, Camera.tty_name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
fclose (cmdpipe);
|
||||||
}
|
}
|
||||||
else if (strncmp (dev_name, "camera=", 7) == 0)
|
else if (strncmp (dev_name, "camera=", 7) == 0)
|
||||||
{
|
{
|
||||||
|
SANE_Int n, entries;
|
||||||
Camera.camera_name = strdup (dev_name + 7);
|
Camera.camera_name = strdup (dev_name + 7);
|
||||||
DBG (20, "Config file camera=%s\n", Camera.camera_name);
|
DBG (20, "Config file camera=%s\n", Camera.camera_name);
|
||||||
sprintf (buf, "Image selection - %s", Camera.camera_name);
|
sprintf (buf, "Image selection - %s", Camera.camera_name);
|
||||||
|
|
||||||
|
sprintf ((char *) cmdbuf, "%s -q --list-cameras",
|
||||||
|
(char *) Gphoto2Path);
|
||||||
|
cmdpipe = popen ((char *) cmdbuf, "r");
|
||||||
|
if (cmdpipe == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fgets ((char *) tmpstr, sizeof (tmpstr), cmdpipe);
|
||||||
|
n = sscanf ((char *) tmpstr, "%d", &entries);
|
||||||
|
if (n == 0 || entries < 1)
|
||||||
|
{
|
||||||
|
DBG (0, "%s: error: Can't list available cameras\n", f);
|
||||||
|
return SANE_STATUS_INVAL;
|
||||||
|
}
|
||||||
|
for (n = 0; n < entries; n++)
|
||||||
|
{
|
||||||
|
fgets ((char *) tmpstr, sizeof (tmpstr), cmdpipe);
|
||||||
|
if (strchr (tmpstr, '\n'))
|
||||||
|
{
|
||||||
|
*strchr (tmpstr, '\n') = '\0';
|
||||||
|
}
|
||||||
|
if (strcmp (Camera.camera_name, tmpstr) == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n == entries)
|
||||||
|
{
|
||||||
|
DBG (0,
|
||||||
|
"%s: error: %s is not a valid camera type. Use \"gphoto2 --list-cameras\" for list.\n",
|
||||||
|
f, Camera.camera_name);
|
||||||
|
return SANE_STATUS_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose (cmdpipe);
|
||||||
|
|
||||||
sod[GPHOTO2_OPT_IMAGE_SELECTION].title = strdup (buf);
|
sod[GPHOTO2_OPT_IMAGE_SELECTION].title = strdup (buf);
|
||||||
}
|
}
|
||||||
else if (strcmp (dev_name, "dumpinquiry") == 0)
|
else if (strcmp (dev_name, "dumpinquiry") == 0)
|
||||||
|
@ -526,7 +636,10 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback UNUSEDARG authorize)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Camera.current_picture_number = 1;
|
Camera.current_picture_number = 1;
|
||||||
|
/* OLD:
|
||||||
set_res (Camera.Pictures[Camera.current_picture_number - 1].low_res);
|
set_res (Camera.Pictures[Camera.current_picture_number - 1].low_res);
|
||||||
|
*/
|
||||||
|
set_res( gphoto2_opt_lowres );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dumpinquiry)
|
if (dumpinquiry)
|
||||||
|
@ -676,8 +789,11 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
||||||
*/
|
*/
|
||||||
if (Camera.pic_taken != 0)
|
if (Camera.pic_taken != 0)
|
||||||
{
|
{
|
||||||
|
/* OLD:
|
||||||
set_res (Camera.
|
set_res (Camera.
|
||||||
Pictures[Camera.current_picture_number - 1].low_res);
|
Pictures[Camera.current_picture_number - 1].low_res);
|
||||||
|
*/
|
||||||
|
set_res (gphoto2_opt_lowres);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -687,8 +803,11 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
||||||
|
|
||||||
if (Camera.pic_taken != 0)
|
if (Camera.pic_taken != 0)
|
||||||
{
|
{
|
||||||
|
/* OLD:
|
||||||
set_res (Camera.
|
set_res (Camera.
|
||||||
Pictures[Camera.current_picture_number - 1].low_res);
|
Pictures[Camera.current_picture_number - 1].low_res);
|
||||||
|
*/
|
||||||
|
set_res (gphoto2_opt_lowres);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -706,10 +825,14 @@ 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 */
|
/* and activate the image number selector, if there are
|
||||||
|
* pictures available */
|
||||||
|
if (Camera.current_picture_number)
|
||||||
|
{
|
||||||
sod[GPHOTO2_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE;
|
sod[GPHOTO2_OPT_IMAGE_NUMBER].cap &= ~SANE_CAP_INACTIVE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* set params according to resolution settings */
|
/* set params according to resolution settings */
|
||||||
set_res (gphoto2_opt_lowres);
|
set_res (gphoto2_opt_lowres);
|
||||||
|
|
||||||
|
@ -916,7 +1039,6 @@ sane_start (SANE_Handle handle)
|
||||||
|
|
||||||
struct jpeg_error_mgr jerr;
|
struct jpeg_error_mgr jerr;
|
||||||
SANE_Int row_stride;
|
SANE_Int row_stride;
|
||||||
SANE_Char cmdbuf[256];
|
|
||||||
|
|
||||||
DBG (127, "sane_start called\n");
|
DBG (127, "sane_start called\n");
|
||||||
if (handle != MAGIC || !is_open ||
|
if (handle != MAGIC || !is_open ||
|
||||||
|
@ -1064,8 +1186,11 @@ sane_read (SANE_Handle UNUSEDARG handle, SANE_Byte * data,
|
||||||
myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||||
|
|
||||||
/* get the image's resolution */
|
/* get the image's resolution */
|
||||||
|
/* OLD:
|
||||||
set_res (Camera.Pictures[Camera.current_picture_number - 1].
|
set_res (Camera.Pictures[Camera.current_picture_number - 1].
|
||||||
low_res);
|
low_res);
|
||||||
|
*/
|
||||||
|
set_res (gphoto2_opt_lowres);
|
||||||
}
|
}
|
||||||
DBG (4, "Increment count to %d (total %d)\n",
|
DBG (4, "Increment count to %d (total %d)\n",
|
||||||
Camera.current_picture_number, Camera.pic_taken);
|
Camera.current_picture_number, Camera.pic_taken);
|
||||||
|
@ -1202,7 +1327,6 @@ static SANE_Status
|
||||||
snap_pic (void)
|
snap_pic (void)
|
||||||
{
|
{
|
||||||
SANE_Bool found = SANE_FALSE;
|
SANE_Bool found = SANE_FALSE;
|
||||||
SANE_Char cmdbuf[256];
|
|
||||||
SANE_Char f[] = "snap_pic";
|
SANE_Char f[] = "snap_pic";
|
||||||
SANE_Int linecount = 0;
|
SANE_Int linecount = 0;
|
||||||
|
|
||||||
|
@ -1226,10 +1350,10 @@ snap_pic (void)
|
||||||
return SANE_STATUS_INVAL;
|
return SANE_STATUS_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fgets ((char *) cmdbuf, sizeof (cmdbuf), cmdpipe)
|
while (fgets ((char *) tmpstr, sizeof (tmpstr), cmdpipe)
|
||||||
&& linecount++ < 100)
|
&& linecount++ < 100)
|
||||||
{
|
{
|
||||||
if (strncmp (cmdbuf, "/DCIM/", 6) == 0)
|
if (strncmp (tmpstr, "/DCIM/", 6) == 0)
|
||||||
{
|
{
|
||||||
found = SANE_TRUE;
|
found = SANE_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1277,7 +1401,6 @@ static SANE_Int
|
||||||
read_dir (SANE_String dir, SANE_Bool read_files)
|
read_dir (SANE_String dir, SANE_Bool read_files)
|
||||||
{
|
{
|
||||||
SANE_Int retval = 0;
|
SANE_Int retval = 0;
|
||||||
SANE_Byte buf[256];
|
|
||||||
SANE_Int i, entries;
|
SANE_Int i, entries;
|
||||||
SANE_Char f[] = "read_dir";
|
SANE_Char f[] = "read_dir";
|
||||||
struct cam_dirlist *e, *next;
|
struct cam_dirlist *e, *next;
|
||||||
|
@ -1293,20 +1416,20 @@ read_dir (SANE_String dir, SANE_Bool read_files)
|
||||||
|
|
||||||
if (read_files)
|
if (read_files)
|
||||||
{
|
{
|
||||||
sprintf ((char *) buf,
|
sprintf ((char *) cmdbuf,
|
||||||
"%s --camera \"%s\" --port %s --folder %s --list-files --stdout",
|
"%s --camera \"%s\" --port %s --folder %s --list-files --stdout",
|
||||||
(char *) Gphoto2Path, (char *) Camera.camera_name,
|
(char *) Gphoto2Path, (char *) Camera.camera_name,
|
||||||
(char *) Camera.tty_name, dir);
|
(char *) Camera.tty_name, dir);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf ((char *) buf,
|
sprintf ((char *) cmdbuf,
|
||||||
"%s --camera \"%s\" --port %s --folder %s --list-folders -q",
|
"%s --camera \"%s\" --port %s --folder %s --list-folders -q",
|
||||||
(char *) Gphoto2Path, (char *) Camera.camera_name,
|
(char *) Gphoto2Path, (char *) Camera.camera_name,
|
||||||
(char *) Camera.tty_name, dir);
|
(char *) Camera.tty_name, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdpipe = popen ((char *) buf, "r");
|
cmdpipe = popen ((char *) cmdbuf, "r");
|
||||||
if (cmdpipe == NULL)
|
if (cmdpipe == NULL)
|
||||||
{
|
{
|
||||||
DBG (0, "%s: error: couldn't open gphoto2", f);
|
DBG (0, "%s: error: couldn't open gphoto2", f);
|
||||||
|
|
Ładowanie…
Reference in New Issue