kopia lustrzana https://gitlab.com/sane-project/backends
Minor bug fixes and cosmetic cleanup
rodzic
222a47fa6c
commit
01cca8ef39
|
@ -5,7 +5,7 @@
|
||||||
* which happens to be the only camera I have. I'm very interested
|
* which happens to be the only camera I have. I'm very interested
|
||||||
* in learning what it would take to support more cameras. In
|
* in learning what it would take to support more cameras. In
|
||||||
* particular, the current incarnation will only support cameras
|
* particular, the current incarnation will only support cameras
|
||||||
* the generate jpeg files.
|
* that directly generate jpeg files.
|
||||||
*
|
*
|
||||||
* However, having said that, I've already found it to be quite useful
|
* 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
|
* even in its current form - one reason is that gphoto2 provides access
|
||||||
|
@ -323,7 +323,7 @@ static SANE_Char cmdbuf[256];
|
||||||
static CameraAbilities *abilities;
|
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_file_total_size, data_file_current_index;
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -334,7 +334,7 @@ static long data_size, data_cur;
|
||||||
static SANE_Int
|
static SANE_Int
|
||||||
init_gphoto2 (void)
|
init_gphoto2 (void)
|
||||||
{
|
{
|
||||||
SANE_Int n, entries;
|
SANE_Int n;
|
||||||
CameraList *list;
|
CameraList *list;
|
||||||
|
|
||||||
DBG (1, "GPHOTO2 Backend 05/16/01\n");
|
DBG (1, "GPHOTO2 Backend 05/16/01\n");
|
||||||
|
@ -745,8 +745,8 @@ sane_exit (void)
|
||||||
static const SANE_Device dev[] = {
|
static const SANE_Device dev[] = {
|
||||||
{
|
{
|
||||||
"0",
|
"0",
|
||||||
"Kodak",
|
"Gphoto2",
|
||||||
"DC-240",
|
"Supported",
|
||||||
"still camera"},
|
"still camera"},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1100,17 +1100,17 @@ METHODDEF (boolean) jpeg_fill_input_buffer (j_decompress_ptr cinfo)
|
||||||
|
|
||||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||||
|
|
||||||
if (data_cur + 512 > data_size)
|
if (data_file_current_index + 512 > data_file_total_size)
|
||||||
{
|
{
|
||||||
n = data_size - data_cur;
|
n = data_file_total_size - data_file_current_index;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
n = 512;
|
n = 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy (src->buffer, data_ptr + data_cur, n);
|
memcpy (src->buffer, data_ptr + data_file_current_index, n);
|
||||||
data_cur += n;
|
data_file_current_index += n;
|
||||||
|
|
||||||
src->pub.next_input_byte = src->buffer;
|
src->pub.next_input_byte = src->buffer;
|
||||||
src->pub.bytes_in_buffer = n;
|
src->pub.bytes_in_buffer = n;
|
||||||
|
@ -1147,10 +1147,7 @@ jpeg_term_source (j_decompress_ptr UNUSEDARG cinfo)
|
||||||
SANE_Status
|
SANE_Status
|
||||||
sane_start (SANE_Handle handle)
|
sane_start (SANE_Handle handle)
|
||||||
{
|
{
|
||||||
my_src_ptr src;
|
|
||||||
SANE_String_Const filename, mime_type;
|
SANE_String_Const filename, mime_type;
|
||||||
struct jpeg_error_mgr jerr;
|
|
||||||
SANE_Int row_stride;
|
|
||||||
|
|
||||||
DBG (127, "sane_start called\n");
|
DBG (127, "sane_start called\n");
|
||||||
if (handle != MAGIC || !is_open ||
|
if (handle != MAGIC || !is_open ||
|
||||||
|
@ -1208,41 +1205,10 @@ sane_start (SANE_Handle handle)
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_RET (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_file_total_size));
|
||||||
|
|
||||||
data_cur = 0;
|
converter_init ();
|
||||||
|
|
||||||
cinfo.err = jpeg_std_error (&jerr);
|
|
||||||
jpeg_create_decompress (&cinfo);
|
|
||||||
|
|
||||||
cinfo.src =
|
|
||||||
(struct jpeg_source_mgr *) (*cinfo.mem->
|
|
||||||
alloc_small) ((j_common_ptr) & cinfo,
|
|
||||||
JPOOL_PERMANENT,
|
|
||||||
sizeof (my_source_mgr));
|
|
||||||
src = (my_src_ptr) cinfo.src;
|
|
||||||
|
|
||||||
src->buffer = (JOCTET *) (*cinfo.mem->alloc_small) ((j_common_ptr) &
|
|
||||||
cinfo,
|
|
||||||
JPOOL_PERMANENT,
|
|
||||||
1024 * sizeof (JOCTET));
|
|
||||||
src->pub.init_source = jpeg_init_source;
|
|
||||||
src->pub.fill_input_buffer = jpeg_fill_input_buffer;
|
|
||||||
src->pub.skip_input_data = jpeg_skip_input_data;
|
|
||||||
src->pub.resync_to_restart = jpeg_resync_to_restart; /* default */
|
|
||||||
src->pub.term_source = jpeg_term_source;
|
|
||||||
src->pub.bytes_in_buffer = 0;
|
|
||||||
src->pub.next_input_byte = NULL;
|
|
||||||
|
|
||||||
(void) jpeg_read_header (&cinfo, TRUE);
|
|
||||||
dest_mgr = sanei_jpeg_jinit_write_ppm (&cinfo);
|
|
||||||
(void) jpeg_start_decompress (&cinfo);
|
|
||||||
|
|
||||||
row_stride = cinfo.output_width * cinfo.output_components;
|
|
||||||
|
|
||||||
parms.bytes_per_line = cinfo.output_width * 3; /* 3 colors */
|
|
||||||
parms.pixels_per_line = cinfo.output_width;
|
|
||||||
parms.lines = cinfo.output_height;
|
|
||||||
|
|
||||||
/* Check if a linebuffer has been allocated. Assumes that highres_width
|
/* Check if a linebuffer has been allocated. Assumes that highres_width
|
||||||
* is also large enough to hold a lowres or thumbnail image
|
* is also large enough to hold a lowres or thumbnail image
|
||||||
|
@ -1268,11 +1234,6 @@ 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)
|
||||||
{
|
{
|
||||||
SANE_Int lines = 0;
|
|
||||||
SANE_String_Const filename;
|
|
||||||
CameraList *tmp_list;
|
|
||||||
SANE_Int i;
|
|
||||||
|
|
||||||
/* If there is anything in the buffer, satisfy the read from there */
|
/* If there is anything in the buffer, satisfy the read from there */
|
||||||
if (linebuffer_size && linebuffer_index < linebuffer_size)
|
if (linebuffer_size && linebuffer_index < linebuffer_size)
|
||||||
{
|
{
|
||||||
|
@ -1288,94 +1249,16 @@ sane_read (SANE_Handle UNUSEDARG handle, SANE_Byte * data,
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cinfo.output_scanline >= cinfo.output_height)
|
if (converter_scan_complete ())
|
||||||
{
|
{
|
||||||
gp_file_unref (data_file);
|
SANE_Status retval = converter_do_scan_complete_cleanup ();
|
||||||
|
if (retval != SANE_STATUS_GOOD)
|
||||||
if (gphoto2_opt_erase)
|
|
||||||
{
|
{
|
||||||
DBG (127, "sane_read bp%d, erase image\n", __LINE__);
|
return retval;
|
||||||
if (erase () == -1)
|
|
||||||
{
|
|
||||||
DBG (1, "Failed to erase memory\n");
|
|
||||||
return SANE_STATUS_INVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sprintf (cmdbuf, "%s/%s", (char *) TopFolder,
|
|
||||||
(const char *) folder_list[current_folder]);
|
|
||||||
CHECK_RET (gp_list_get_name
|
|
||||||
(dir_list, Cam_data.current_picture_number - 1,
|
|
||||||
&filename));
|
|
||||||
|
|
||||||
Cam_data.pic_taken--;
|
|
||||||
Cam_data.pic_left++;
|
|
||||||
if ( Cam_data.current_picture_number > Cam_data.pic_taken ) {
|
|
||||||
Cam_data.current_picture_number = Cam_data.pic_taken;
|
|
||||||
}
|
|
||||||
image_range.max--;
|
|
||||||
if (image_range.max == 0)
|
|
||||||
{
|
|
||||||
sod[GPHOTO2_OPT_IMAGE_NUMBER].cap |= SANE_CAP_INACTIVE;
|
|
||||||
}
|
|
||||||
myinfo |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
|
|
||||||
|
|
||||||
/* Too bad we don't have an API function for deleting a
|
|
||||||
* list item. Instead, we copy all the entries in the
|
|
||||||
* current list, skipping over the deleted entry, and then
|
|
||||||
* replace the current list with the new list.
|
|
||||||
*/
|
|
||||||
gp_list_new (&tmp_list);
|
|
||||||
|
|
||||||
for (i = 0; i < gp_list_count (dir_list); i++)
|
|
||||||
{
|
|
||||||
SANE_String_Const tfilename;
|
|
||||||
|
|
||||||
CHECK_RET (gp_list_get_name (dir_list, i, &tfilename));
|
|
||||||
/* If not the one to delete, copy to the new list */
|
|
||||||
if (strcmp (tfilename, filename) != 0)
|
|
||||||
{
|
|
||||||
CHECK_RET (gp_list_append (tmp_list, tfilename, NULL));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gp_list_free (dir_list);
|
|
||||||
dir_list = tmp_list;
|
|
||||||
|
|
||||||
}
|
*length = converter_fill_buffer ();
|
||||||
if (gphoto2_opt_autoinc)
|
|
||||||
{
|
|
||||||
if (Cam_data.current_picture_number <= Cam_data.pic_taken)
|
|
||||||
{
|
|
||||||
Cam_data.current_picture_number++;
|
|
||||||
|
|
||||||
myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
|
||||||
|
|
||||||
/* get the image's resolution */
|
|
||||||
/* OLD:
|
|
||||||
set_res (Cam_data.Pictures[Cam_data.current_picture_number - 1].
|
|
||||||
low_res);
|
|
||||||
*/
|
|
||||||
set_res (gphoto2_opt_lowres);
|
|
||||||
}
|
|
||||||
DBG (4, "Increment count to %d (total %d)\n",
|
|
||||||
Cam_data.current_picture_number, Cam_data.pic_taken);
|
|
||||||
}
|
|
||||||
return SANE_STATUS_EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
(void) jpeg_read_scanlines (&cinfo, dest_mgr->buffer, lines);
|
|
||||||
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, lines, (char *) linebuffer);
|
|
||||||
|
|
||||||
*length = cinfo.output_width * cinfo.output_components * lines;
|
|
||||||
linebuffer_size = *length;
|
linebuffer_size = *length;
|
||||||
linebuffer_index = 0;
|
linebuffer_index = 0;
|
||||||
|
|
||||||
|
@ -1425,7 +1308,9 @@ sane_get_select_fd (SANE_Handle UNUSEDARG handle, SANE_Int * UNUSEDARG fd)
|
||||||
/*
|
/*
|
||||||
* get_pictures_info - load information about all pictures currently in
|
* get_pictures_info - load information about all pictures currently in
|
||||||
* camera: Mainly the mapping of picture number
|
* camera: Mainly the mapping of picture number
|
||||||
* to picture name, and the resolution of each picture.
|
* to picture name. We'ld like to get other
|
||||||
|
* information such as image size, but the API
|
||||||
|
* doesn't provide any support for that.
|
||||||
*/
|
*/
|
||||||
static PictureInfo *
|
static PictureInfo *
|
||||||
get_pictures_info (void)
|
get_pictures_info (void)
|
||||||
|
@ -1479,7 +1364,8 @@ get_pictures_info (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sane_picture_info() - get info about picture p
|
* sane_picture_info() - get info about picture p. Currently we have no
|
||||||
|
* way to get information about a picture beyond it's name.
|
||||||
*/
|
*/
|
||||||
static SANE_Int
|
static SANE_Int
|
||||||
get_picture_info (PictureInfo * pic, SANE_Int p)
|
get_picture_info (PictureInfo * pic, SANE_Int p)
|
||||||
|
@ -1587,6 +1473,8 @@ read_dir (SANE_String dir, SANE_Bool read_files)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read_info - read the info block from camera for the specified file
|
* read_info - read the info block from camera for the specified file
|
||||||
|
* NOT YET SUPPORTED - If it were we could use it to do things
|
||||||
|
* like update the image size parameters displayed by the GUI
|
||||||
*/
|
*/
|
||||||
static SANE_Int
|
static SANE_Int
|
||||||
read_info (SANE_String_Const fname)
|
read_info (SANE_String_Const fname)
|
||||||
|
@ -1622,3 +1510,179 @@ set_res (SANE_Int lowres)
|
||||||
parms.lines = HIGHRES_HEIGHT;
|
parms.lines = HIGHRES_HEIGHT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* converter_do_scan_complete_cleanup - do everything that needs to be
|
||||||
|
* once a "scan" has been completed: Unref the file, Erase the image,
|
||||||
|
* and increment image number to point to next picture.
|
||||||
|
*/
|
||||||
|
static SANE_Status
|
||||||
|
converter_do_scan_complete_cleanup (void)
|
||||||
|
{
|
||||||
|
CameraList *tmp_list;
|
||||||
|
SANE_Int i;
|
||||||
|
SANE_String_Const filename;
|
||||||
|
|
||||||
|
gp_file_unref (data_file);
|
||||||
|
|
||||||
|
if (gphoto2_opt_erase)
|
||||||
|
{
|
||||||
|
DBG (127, "sane_read bp%d, erase image\n", __LINE__);
|
||||||
|
if (erase () == -1)
|
||||||
|
{
|
||||||
|
DBG (1, "Failed to erase memory\n");
|
||||||
|
return SANE_STATUS_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sprintf (cmdbuf, "%s/%s", (char *) TopFolder,
|
||||||
|
(const char *) folder_list[current_folder]);
|
||||||
|
CHECK_RET (gp_list_get_name
|
||||||
|
(dir_list, Cam_data.current_picture_number - 1, &filename));
|
||||||
|
|
||||||
|
Cam_data.pic_taken--;
|
||||||
|
Cam_data.pic_left++;
|
||||||
|
if (Cam_data.current_picture_number > Cam_data.pic_taken)
|
||||||
|
{
|
||||||
|
Cam_data.current_picture_number = Cam_data.pic_taken;
|
||||||
|
}
|
||||||
|
image_range.max--;
|
||||||
|
if (image_range.max == 0)
|
||||||
|
{
|
||||||
|
sod[GPHOTO2_OPT_IMAGE_NUMBER].cap |= SANE_CAP_INACTIVE;
|
||||||
|
}
|
||||||
|
myinfo |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
|
||||||
|
|
||||||
|
/* Too bad we don't have an API function for deleting a
|
||||||
|
* list item. Instead, we copy all the entries in the
|
||||||
|
* current list, skipping over the deleted entry, and then
|
||||||
|
* replace the current list with the new list.
|
||||||
|
*/
|
||||||
|
gp_list_new (&tmp_list);
|
||||||
|
|
||||||
|
for (i = 0; i < gp_list_count (dir_list); i++)
|
||||||
|
{
|
||||||
|
SANE_String_Const tfilename;
|
||||||
|
|
||||||
|
CHECK_RET (gp_list_get_name (dir_list, i, &tfilename));
|
||||||
|
/* If not the one to delete, copy to the new list */
|
||||||
|
if (strcmp (tfilename, filename) != 0)
|
||||||
|
{
|
||||||
|
CHECK_RET (gp_list_append (tmp_list, tfilename, NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gp_list_free (dir_list);
|
||||||
|
dir_list = tmp_list;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (gphoto2_opt_autoinc)
|
||||||
|
{
|
||||||
|
if (Cam_data.current_picture_number <= Cam_data.pic_taken)
|
||||||
|
{
|
||||||
|
Cam_data.current_picture_number++;
|
||||||
|
|
||||||
|
myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||||
|
|
||||||
|
/* get the image's resolution */
|
||||||
|
/* OLD:
|
||||||
|
set_res (Cam_data.Pictures[Cam_data.current_picture_number - 1].
|
||||||
|
low_res);
|
||||||
|
*/
|
||||||
|
set_res (gphoto2_opt_lowres);
|
||||||
|
}
|
||||||
|
DBG (4, "Increment count to %d (total %d)\n",
|
||||||
|
Cam_data.current_picture_number, Cam_data.pic_taken);
|
||||||
|
}
|
||||||
|
return SANE_STATUS_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* converter_fill_buffer - Fill line buffer with next input line from image.
|
||||||
|
* Currently assumes jpeg, but this is where we would put the switch
|
||||||
|
* to handle other image types.
|
||||||
|
*/
|
||||||
|
static SANE_Int
|
||||||
|
converter_fill_buffer (void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
SANE_Int lines = 1;
|
||||||
|
|
||||||
|
(void) jpeg_read_scanlines (&cinfo, dest_mgr->buffer, lines);
|
||||||
|
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, lines, (char *) linebuffer);
|
||||||
|
|
||||||
|
return cinfo.output_width * cinfo.output_components * lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* converter_scan_complete - Check if all the data for the image has been read.
|
||||||
|
* Currently assumes jpeg, but this is where we would put the
|
||||||
|
* switch to handle other image types.
|
||||||
|
*/
|
||||||
|
static SANE_Bool
|
||||||
|
converter_scan_complete (void)
|
||||||
|
{
|
||||||
|
if (cinfo.output_scanline >= cinfo.output_height)
|
||||||
|
{
|
||||||
|
return SANE_TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return SANE_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* converter_init - Initialize image conversion data.
|
||||||
|
* Currently assumes jpeg, but this is where we would put the
|
||||||
|
* switch to handle other image types.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
converter_init (void)
|
||||||
|
{
|
||||||
|
SANE_Int row_stride;
|
||||||
|
struct jpeg_error_mgr jerr;
|
||||||
|
my_src_ptr src;
|
||||||
|
|
||||||
|
data_file_current_index = 0;
|
||||||
|
|
||||||
|
cinfo.err = jpeg_std_error (&jerr);
|
||||||
|
jpeg_create_decompress (&cinfo);
|
||||||
|
|
||||||
|
cinfo.src =
|
||||||
|
(struct jpeg_source_mgr *) (*cinfo.mem->
|
||||||
|
alloc_small) ((j_common_ptr) & cinfo,
|
||||||
|
JPOOL_PERMANENT,
|
||||||
|
sizeof (my_source_mgr));
|
||||||
|
src = (my_src_ptr) cinfo.src;
|
||||||
|
|
||||||
|
src->buffer = (JOCTET *) (*cinfo.mem->alloc_small) ((j_common_ptr) &
|
||||||
|
cinfo,
|
||||||
|
JPOOL_PERMANENT,
|
||||||
|
1024 * sizeof (JOCTET));
|
||||||
|
src->pub.init_source = jpeg_init_source;
|
||||||
|
src->pub.fill_input_buffer = jpeg_fill_input_buffer;
|
||||||
|
src->pub.skip_input_data = jpeg_skip_input_data;
|
||||||
|
src->pub.resync_to_restart = jpeg_resync_to_restart; /* default */
|
||||||
|
src->pub.term_source = jpeg_term_source;
|
||||||
|
src->pub.bytes_in_buffer = 0;
|
||||||
|
src->pub.next_input_byte = NULL;
|
||||||
|
|
||||||
|
(void) jpeg_read_header (&cinfo, TRUE);
|
||||||
|
dest_mgr = sanei_jpeg_jinit_write_ppm (&cinfo);
|
||||||
|
(void) jpeg_start_decompress (&cinfo);
|
||||||
|
|
||||||
|
row_stride = cinfo.output_width * cinfo.output_components;
|
||||||
|
|
||||||
|
parms.bytes_per_line = cinfo.output_width * 3; /* 3 colors */
|
||||||
|
parms.pixels_per_line = cinfo.output_width;
|
||||||
|
parms.lines = cinfo.output_height;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue