kopia lustrzana https://gitlab.com/sane-project/backends
fix genesys issues when using saned
- fix --clear-calibration option descriptor - rewrite dynmaic lineart code to fix incorrect returned data lengthmerge-requests/1/head
rodzic
8d8eb5ee29
commit
41733d874e
|
@ -58,7 +58,7 @@
|
||||||
* SANE backend for Genesys Logic GL646/GL841/GL842/GL843/GL847/GL124 based scanners
|
* SANE backend for Genesys Logic GL646/GL841/GL842/GL843/GL847/GL124 based scanners
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BUILD 2301
|
#define BUILD 2302
|
||||||
#define BACKEND_NAME genesys
|
#define BACKEND_NAME genesys
|
||||||
|
|
||||||
#include "genesys.h"
|
#include "genesys.h"
|
||||||
|
@ -1993,7 +1993,7 @@ genesys_white_shading_calibration (Genesys_Device * dev)
|
||||||
uint8_t channels;
|
uint8_t channels;
|
||||||
SANE_Bool motor;
|
SANE_Bool motor;
|
||||||
|
|
||||||
DBG (DBG_proc, "genesys_white_shading_calibration (lines = %d)\n",
|
DBG (DBG_proc, "genesys_white_shading_calibration (lines = %lu)\n",
|
||||||
dev->calib_lines);
|
dev->calib_lines);
|
||||||
|
|
||||||
pixels_per_line = dev->calib_pixels;
|
pixels_per_line = dev->calib_pixels;
|
||||||
|
@ -2137,7 +2137,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
|
||||||
SANE_Bool motor;
|
SANE_Bool motor;
|
||||||
|
|
||||||
|
|
||||||
DBG (DBG_proc, "genesys_black_white_shading_calibration (lines = %d)\n",
|
DBG (DBG_proc, "genesys_black_white_shading_calibration (lines = %lu)\n",
|
||||||
dev->calib_lines);
|
dev->calib_lines);
|
||||||
|
|
||||||
pixels_per_line = dev->calib_pixels;
|
pixels_per_line = dev->calib_pixels;
|
||||||
|
@ -4733,7 +4733,6 @@ genesys_read_ordered_data (Genesys_Device * dev, SANE_Byte * destination,
|
||||||
unsigned int needs_ccd;
|
unsigned int needs_ccd;
|
||||||
unsigned int needs_shrink;
|
unsigned int needs_shrink;
|
||||||
unsigned int needs_reverse;
|
unsigned int needs_reverse;
|
||||||
unsigned int needs_gray_lineart;
|
|
||||||
Genesys_Buffer *src_buffer;
|
Genesys_Buffer *src_buffer;
|
||||||
Genesys_Buffer *dst_buffer;
|
Genesys_Buffer *dst_buffer;
|
||||||
|
|
||||||
|
@ -4791,15 +4790,13 @@ genesys_read_ordered_data (Genesys_Device * dev, SANE_Byte * destination,
|
||||||
needs_ccd = dev->current_setup.max_shift > 0;
|
needs_ccd = dev->current_setup.max_shift > 0;
|
||||||
needs_shrink = dev->settings.pixels != src_pixels;
|
needs_shrink = dev->settings.pixels != src_pixels;
|
||||||
needs_reverse = depth == 1;
|
needs_reverse = depth == 1;
|
||||||
needs_gray_lineart = depth == 8 && dev->settings.scan_mode == 0;
|
|
||||||
|
|
||||||
DBG (DBG_info,
|
DBG (DBG_info,
|
||||||
"genesys_read_ordered_data: using filters:%s%s%s%s%s\n",
|
"genesys_read_ordered_data: using filters:%s%s%s%s\n",
|
||||||
needs_reorder ? " reorder" : "",
|
needs_reorder ? " reorder" : "",
|
||||||
needs_ccd ? " ccd" : "",
|
needs_ccd ? " ccd" : "",
|
||||||
needs_shrink ? " shrink" : "",
|
needs_shrink ? " shrink" : "",
|
||||||
needs_reverse ? " reverse" : "",
|
needs_reverse ? " reverse" : "");
|
||||||
needs_gray_lineart ? " gray_lineart" : "");
|
|
||||||
|
|
||||||
DBG (DBG_info,
|
DBG (DBG_info,
|
||||||
"genesys_read_ordered_data: frontend requested %lu bytes\n",
|
"genesys_read_ordered_data: frontend requested %lu bytes\n",
|
||||||
|
@ -5159,7 +5156,6 @@ Problems with the first approach:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* move data to destination */
|
/* move data to destination */
|
||||||
|
|
||||||
bytes = src_buffer->avail;
|
bytes = src_buffer->avail;
|
||||||
if (bytes > *len)
|
if (bytes > *len)
|
||||||
bytes = *len;
|
bytes = *len;
|
||||||
|
@ -5177,39 +5173,6 @@ Problems with the first approach:
|
||||||
}
|
}
|
||||||
*len = bytes;
|
*len = bytes;
|
||||||
}
|
}
|
||||||
else if (needs_gray_lineart)
|
|
||||||
{
|
|
||||||
if (depth != 8)
|
|
||||||
{
|
|
||||||
DBG (DBG_error, "Cannot convert from 16bit to lineart\n");
|
|
||||||
return SANE_STATUS_INVAL;
|
|
||||||
}
|
|
||||||
/* lines in input to process */
|
|
||||||
dst_lines = bytes / (dev->settings.pixels * channels);
|
|
||||||
if(dst_lines==0)
|
|
||||||
{
|
|
||||||
/* padd to at least line length */
|
|
||||||
dst_lines=1;
|
|
||||||
}
|
|
||||||
bytes = dst_lines * dev->settings.pixels * channels;
|
|
||||||
|
|
||||||
status = genesys_gray_lineart (dev,
|
|
||||||
work_buffer_src,
|
|
||||||
destination,
|
|
||||||
dev->settings.pixels,
|
|
||||||
dst_lines,
|
|
||||||
dev->settings.threshold);
|
|
||||||
if (status != SANE_STATUS_GOOD)
|
|
||||||
{
|
|
||||||
DBG (DBG_error,
|
|
||||||
"genesys_read_ordered_data: failed to convert bits(%s)\n",
|
|
||||||
sane_strstatus (status));
|
|
||||||
return SANE_STATUS_IO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
*len = dst_lines * channels *
|
|
||||||
(dev->settings.pixels / 8 + ((dev->settings.pixels % 8) ? 1 : 0));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy (destination, work_buffer_src, bytes);
|
memcpy (destination, work_buffer_src, bytes);
|
||||||
|
@ -5494,14 +5457,10 @@ init_options (Genesys_Scanner * s)
|
||||||
SANE_Status status;
|
SANE_Status status;
|
||||||
SANE_Word *dpi_list;
|
SANE_Word *dpi_list;
|
||||||
Genesys_Model *model = s->dev->model;
|
Genesys_Model *model = s->dev->model;
|
||||||
SANE_Bool has_ta;
|
|
||||||
SANE_Range *x_range, *y_range;
|
SANE_Range *x_range, *y_range;
|
||||||
|
|
||||||
DBGSTART;
|
DBGSTART;
|
||||||
|
|
||||||
/* no transparency adaptor support yet */
|
|
||||||
has_ta = SANE_FALSE;
|
|
||||||
|
|
||||||
memset (s->opt, 0, sizeof (s->opt));
|
memset (s->opt, 0, sizeof (s->opt));
|
||||||
memset (s->val, 0, sizeof (s->val));
|
memset (s->val, 0, sizeof (s->val));
|
||||||
|
|
||||||
|
@ -6021,9 +5980,10 @@ init_options (Genesys_Scanner * s)
|
||||||
s->opt[OPT_CLEAR_CALIBRATION].desc = SANE_I18N ("Clear calibration cache");
|
s->opt[OPT_CLEAR_CALIBRATION].desc = SANE_I18N ("Clear calibration cache");
|
||||||
s->opt[OPT_CLEAR_CALIBRATION].type = SANE_TYPE_BUTTON;
|
s->opt[OPT_CLEAR_CALIBRATION].type = SANE_TYPE_BUTTON;
|
||||||
s->opt[OPT_CLEAR_CALIBRATION].unit = SANE_UNIT_NONE;
|
s->opt[OPT_CLEAR_CALIBRATION].unit = SANE_UNIT_NONE;
|
||||||
|
s->opt[OPT_CLEAR_CALIBRATION].size = 0;
|
||||||
|
s->opt[OPT_CLEAR_CALIBRATION].constraint_type = SANE_CONSTRAINT_NONE;
|
||||||
s->opt[OPT_CLEAR_CALIBRATION].cap =
|
s->opt[OPT_CLEAR_CALIBRATION].cap =
|
||||||
SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED |
|
SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
|
||||||
SANE_CAP_AUTOMATIC;
|
|
||||||
s->val[OPT_CLEAR_CALIBRATION].b = 0;
|
s->val[OPT_CLEAR_CALIBRATION].b = 0;
|
||||||
s->last_val[OPT_CLEAR_CALIBRATION].b = 0;
|
s->last_val[OPT_CLEAR_CALIBRATION].b = 0;
|
||||||
|
|
||||||
|
@ -6758,6 +6718,8 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
|
||||||
s->dev->lines_buffer.buffer = NULL;
|
s->dev->lines_buffer.buffer = NULL;
|
||||||
s->dev->shrink_buffer.buffer = NULL;
|
s->dev->shrink_buffer.buffer = NULL;
|
||||||
s->dev->out_buffer.buffer = NULL;
|
s->dev->out_buffer.buffer = NULL;
|
||||||
|
s->dev->binarize_buffer.buffer = NULL;
|
||||||
|
s->dev->local_buffer.buffer = NULL;
|
||||||
s->dev->parking = SANE_FALSE;
|
s->dev->parking = SANE_FALSE;
|
||||||
s->dev->read_active = SANE_FALSE;
|
s->dev->read_active = SANE_FALSE;
|
||||||
s->dev->white_average_data = NULL;
|
s->dev->white_average_data = NULL;
|
||||||
|
@ -6888,6 +6850,8 @@ sane_close (SANE_Handle handle)
|
||||||
sanei_genesys_buffer_free (&(s->dev->lines_buffer));
|
sanei_genesys_buffer_free (&(s->dev->lines_buffer));
|
||||||
sanei_genesys_buffer_free (&(s->dev->shrink_buffer));
|
sanei_genesys_buffer_free (&(s->dev->shrink_buffer));
|
||||||
sanei_genesys_buffer_free (&(s->dev->out_buffer));
|
sanei_genesys_buffer_free (&(s->dev->out_buffer));
|
||||||
|
sanei_genesys_buffer_free (&(s->dev->binarize_buffer));
|
||||||
|
sanei_genesys_buffer_free (&(s->dev->local_buffer));
|
||||||
FREE_IFNOT_NULL (s->dev->white_average_data);
|
FREE_IFNOT_NULL (s->dev->white_average_data);
|
||||||
FREE_IFNOT_NULL (s->dev->dark_average_data);
|
FREE_IFNOT_NULL (s->dev->dark_average_data);
|
||||||
FREE_IFNOT_NULL (s->dev->calib_file);
|
FREE_IFNOT_NULL (s->dev->calib_file);
|
||||||
|
@ -6979,7 +6943,6 @@ get_option_value (Genesys_Scanner * s, int option, void *val)
|
||||||
case OPT_THRESHOLD:
|
case OPT_THRESHOLD:
|
||||||
case OPT_THRESHOLD_CURVE:
|
case OPT_THRESHOLD_CURVE:
|
||||||
case OPT_DISABLE_DYNAMIC_LINEART:
|
case OPT_DISABLE_DYNAMIC_LINEART:
|
||||||
case OPT_CLEAR_CALIBRATION:
|
|
||||||
case OPT_DISABLE_INTERPOLATION:
|
case OPT_DISABLE_INTERPOLATION:
|
||||||
case OPT_LAMP_OFF:
|
case OPT_LAMP_OFF:
|
||||||
case OPT_LAMP_OFF_TIME:
|
case OPT_LAMP_OFF_TIME:
|
||||||
|
@ -7550,6 +7513,15 @@ sane_start (SANE_Handle handle)
|
||||||
|
|
||||||
s->scanning = SANE_TRUE;
|
s->scanning = SANE_TRUE;
|
||||||
|
|
||||||
|
/* allocate intermediate buffer when doing dynamic lineart */
|
||||||
|
if(s->dev->settings.dynamic_lineart==SANE_TRUE)
|
||||||
|
{
|
||||||
|
RIE (sanei_genesys_buffer_free (&(s->dev->binarize_buffer)));
|
||||||
|
RIE (sanei_genesys_buffer_alloc (&(s->dev->binarize_buffer), s->dev->settings.pixels));
|
||||||
|
RIE (sanei_genesys_buffer_free (&(s->dev->local_buffer)));
|
||||||
|
RIE (sanei_genesys_buffer_alloc (&(s->dev->local_buffer), s->dev->binarize_buffer.size * 8));
|
||||||
|
}
|
||||||
|
|
||||||
/* if one of the software enhancement option is selected,
|
/* if one of the software enhancement option is selected,
|
||||||
* we do the scan internally, process picture then put it an internal
|
* we do the scan internally, process picture then put it an internal
|
||||||
* buffer. Since cropping may change scan parameters, we recompute them
|
* buffer. Since cropping may change scan parameters, we recompute them
|
||||||
|
@ -7642,19 +7614,68 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_proc, "sane_read: start, %d maximum bytes required\n", max_len);
|
DBG (DBG_proc, "sane_read: start, %d maximum bytes required\n", max_len);
|
||||||
|
DBG (DBG_io2, "sane_read: bytes_to_read=%lu, total_bytes_read=%lu\n",
|
||||||
|
(u_long) dev->total_bytes_to_read, (u_long) dev->total_bytes_read);
|
||||||
|
DBG (DBG_io2, "sane_read: physical bytes to read = %lu\n", (u_long) dev->read_bytes_left);
|
||||||
|
|
||||||
if(dev->total_bytes_read>=dev->total_bytes_to_read)
|
if(dev->total_bytes_read>=dev->total_bytes_to_read)
|
||||||
{
|
{
|
||||||
|
DBG (DBG_proc, "sane_read: nothing more to scan: EOF\n");
|
||||||
return SANE_STATUS_EOF;
|
return SANE_STATUS_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_len = max_len;
|
local_len = max_len;
|
||||||
|
|
||||||
/* if image hasn't been buffered, read data from scanner */
|
/* in case of image processing, all data has been stored in
|
||||||
|
* buffer_image. So read data from it if it exists, else from scanner */
|
||||||
if(!dev->buffer_image)
|
if(!dev->buffer_image)
|
||||||
{
|
{
|
||||||
|
/* dynamic lineart is another kind of digital processing that needs
|
||||||
|
* another layer of buffering on top of genesys_read_ordered_data */
|
||||||
|
if(dev->settings.dynamic_lineart==SANE_TRUE)
|
||||||
|
{
|
||||||
|
/* if buffer is empty, fill it with genesys_read_ordered_data */
|
||||||
|
if(dev->binarize_buffer.avail==0)
|
||||||
|
{
|
||||||
|
/* store gray data */
|
||||||
|
local_len=dev->local_buffer.size;
|
||||||
|
status = genesys_read_ordered_data (dev, dev->local_buffer.buffer, &local_len);
|
||||||
|
|
||||||
|
/* binarize data is read successful */
|
||||||
|
if(status==SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
dev->local_buffer.avail=local_len;
|
||||||
|
dev->local_buffer.pos=0;
|
||||||
|
dev->binarize_buffer.avail=local_len/8;
|
||||||
|
dev->binarize_buffer.pos=0;
|
||||||
|
genesys_gray_lineart (dev,
|
||||||
|
dev->local_buffer.buffer,
|
||||||
|
dev->binarize_buffer.buffer,
|
||||||
|
dev->settings.pixels,
|
||||||
|
local_len/dev->settings.pixels,
|
||||||
|
dev->settings.threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return data from lineart buffer if any, up to the available amount */
|
||||||
|
local_len = max_len;
|
||||||
|
if((size_t)max_len>dev->binarize_buffer.avail)
|
||||||
|
{
|
||||||
|
local_len=dev->binarize_buffer.avail;
|
||||||
|
}
|
||||||
|
if(local_len)
|
||||||
|
{
|
||||||
|
memcpy(buf,sanei_genesys_buffer_get_read_pos (&(dev->binarize_buffer)),local_len);
|
||||||
|
RIE (sanei_genesys_buffer_consume (&(dev->binarize_buffer), local_len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* most usual case, direct read of data from scanner */
|
||||||
status = genesys_read_ordered_data (dev, buf, &local_len);
|
status = genesys_read_ordered_data (dev, buf, &local_len);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else /* read data from buffer */
|
else /* read data from buffer */
|
||||||
{
|
{
|
||||||
if(dev->total_bytes_read+local_len>dev->total_bytes_to_read)
|
if(dev->total_bytes_read+local_len>dev->total_bytes_to_read)
|
||||||
|
@ -7666,6 +7687,11 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
|
||||||
}
|
}
|
||||||
|
|
||||||
*len = local_len;
|
*len = local_len;
|
||||||
|
if(local_len>(size_t)max_len)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "[genesys] sane_read: returning incorrect length!!\n");
|
||||||
|
}
|
||||||
|
DBG (DBG_proc, "sane_read: %d bytes returned\n", *len);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1694,7 +1694,7 @@ gl124_init_scan_regs (Genesys_Device * dev,
|
||||||
dev->current_setup.max_shift = max_shift + stagger;
|
dev->current_setup.max_shift = max_shift + stagger;
|
||||||
|
|
||||||
dev->total_bytes_read = 0;
|
dev->total_bytes_read = 0;
|
||||||
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
|
if (depth == 1)
|
||||||
dev->total_bytes_to_read =
|
dev->total_bytes_to_read =
|
||||||
((dev->settings.pixels * dev->settings.lines) / 8 +
|
((dev->settings.pixels * dev->settings.lines) / 8 +
|
||||||
(((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) *
|
(((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) *
|
||||||
|
|
|
@ -1301,7 +1301,7 @@ gl646_setup_registers (Genesys_Device * dev,
|
||||||
* read_bytes_left is the number of bytes to read from the scanner
|
* read_bytes_left is the number of bytes to read from the scanner
|
||||||
*/
|
*/
|
||||||
dev->total_bytes_read = 0;
|
dev->total_bytes_read = 0;
|
||||||
if (depth == 1 || scan_settings.scan_mode == SCAN_MODE_LINEART)
|
if (depth == 1)
|
||||||
dev->total_bytes_to_read =
|
dev->total_bytes_to_read =
|
||||||
((scan_settings.pixels * scan_settings.lines) / 8 +
|
((scan_settings.pixels * scan_settings.lines) / 8 +
|
||||||
(((scan_settings.pixels * scan_settings.lines) % 8) ? 1 : 0)) *
|
(((scan_settings.pixels * scan_settings.lines) % 8) ? 1 : 0)) *
|
||||||
|
|
|
@ -2549,7 +2549,7 @@ dummy \ scanned lines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dev->total_bytes_read = 0;
|
dev->total_bytes_read = 0;
|
||||||
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
|
if (depth == 1)
|
||||||
dev->total_bytes_to_read =
|
dev->total_bytes_to_read =
|
||||||
((dev->settings.pixels * dev->settings.lines) / 8 +
|
((dev->settings.pixels * dev->settings.lines) / 8 +
|
||||||
(((dev->settings.pixels * dev->settings.lines)%8)?1:0)
|
(((dev->settings.pixels * dev->settings.lines)%8)?1:0)
|
||||||
|
|
|
@ -1644,7 +1644,7 @@ gl843_init_scan_regs (Genesys_Device * dev,
|
||||||
dev->current_setup.max_shift = max_shift + stagger;
|
dev->current_setup.max_shift = max_shift + stagger;
|
||||||
|
|
||||||
dev->total_bytes_read = 0;
|
dev->total_bytes_read = 0;
|
||||||
if (depth == 1 || scan_mode == SCAN_MODE_LINEART)
|
if (depth == 1)
|
||||||
dev->total_bytes_to_read =
|
dev->total_bytes_to_read =
|
||||||
((dev->settings.pixels * dev->settings.lines) / 8 +
|
((dev->settings.pixels * dev->settings.lines) / 8 +
|
||||||
(((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) *
|
(((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) *
|
||||||
|
|
|
@ -1649,7 +1649,7 @@ gl847_init_scan_regs (Genesys_Device * dev,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dev->total_bytes_read = 0;
|
dev->total_bytes_read = 0;
|
||||||
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
|
if (depth == 1)
|
||||||
dev->total_bytes_to_read =
|
dev->total_bytes_to_read =
|
||||||
((dev->settings.pixels * dev->settings.lines) / 8 +
|
((dev->settings.pixels * dev->settings.lines) / 8 +
|
||||||
(((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) *
|
(((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) *
|
||||||
|
|
|
@ -696,6 +696,8 @@ struct Genesys_Device
|
||||||
Genesys_Buffer lines_buffer;
|
Genesys_Buffer lines_buffer;
|
||||||
Genesys_Buffer shrink_buffer;
|
Genesys_Buffer shrink_buffer;
|
||||||
Genesys_Buffer out_buffer;
|
Genesys_Buffer out_buffer;
|
||||||
|
Genesys_Buffer binarize_buffer; /**> buffer for digital lineart from gray data */
|
||||||
|
Genesys_Buffer local_buffer; /**> local buffer for gray data during dynamix lineart */
|
||||||
|
|
||||||
size_t read_bytes_left; /**> bytes to read from scanner */
|
size_t read_bytes_left; /**> bytes to read from scanner */
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue