- added OPT_CUSTOM_GAMMA and OPT_GAMMA_VECTOR* options for GL646

- fixed allocation bugs detected by valgrind
	- fixed bugs detected by 'tstbackend -r 1 -l 1'
	- allow 'genesys' as default value for backend opening
	- made OPT_COLOR_FILTER effectively work for GL646 scanners
	- split sane_control_options() to make it more readable
merge-requests/1/head
Stéphane Voltz 2008-04-05 09:21:56 +00:00
rodzic 0239a8344a
commit 79fbd0c2f1
6 zmienionych plików z 603 dodań i 241 usunięć

Wyświetl plik

@ -1,3 +1,11 @@
2008-04-05 Stéphane Voltz <stef.dev@free.fr>
* backend/genesys.c backend/genesys.h backend/genesys_devices.c
backend/genesys_gl646.c backend/genesys_low.h:
Fixed double free problems, made OPT_COLOR_FILTER work for
GL646 scanners, added OPT_CUSTOM_GAMMA and OPT_GAMMA_VECTOR*
options, split sane_control_options to make it more readable,
fixed 'reset stream' problem for MD6471.
2008-04-05 Stéphane Voltz <stef.dev@free.fr>
* backend/rts8891.c:
split sane_control_option() to make it more readable

Wyświetl plik

@ -2,7 +2,7 @@
Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de>
Copyright (C) 2004, 2005 Gerhard Jaeger <gerhard@gjaeger.de>
Copyright (C) 2004, 2007 Stephane Voltz <stef.dev@free.fr>
Copyright (C) 2004, 2008 Stéphane Voltz <stef.dev@free.fr>
Copyright (C) 2005, 2006 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
Copyright (C) 2006 Laurent Charpentier <laurent_pubs@yahoo.com>
Copyright (C) 2007 Luke <iceyfor@gmail.com>
@ -73,6 +73,8 @@
#include "genesys.h"
#include "genesys_devices.c"
#define FREE_IFNOT_NULL(x) if(x!=NULL) { free(x); x=NULL;}
static SANE_Int num_devices = 0;
static Genesys_Device *first_dev = 0;
static Genesys_Scanner *first_handle = 0;
@ -85,10 +87,10 @@ static SANE_Int new_dev_len = 0;
static SANE_Int new_dev_alloced = 0;
static SANE_String_Const mode_list[] = {
SANE_I18N ("Color"),
SANE_I18N ("Gray"),
/* SANE_I18N ("Halftone"), currently unused */
SANE_I18N ("Lineart"),
SANE_VALUE_SCAN_MODE_COLOR,
SANE_VALUE_SCAN_MODE_GRAY,
/* SANE_TITLE_HALFTONE, currently unused */
SANE_VALUE_SCAN_MODE_LINEART,
0
};
@ -129,6 +131,24 @@ static const SANE_Range u8_range = {
0 /* quantization */
};
static const SANE_Range u12_range = {
0, /* minimum */
4095, /* maximum */
0 /* quantization */
};
static const SANE_Range u14_range = {
0, /* minimum */
16383, /* maximum */
0 /* quantization */
};
static const SANE_Range u16_range = {
0, /* minimum */
65535, /* maximum */
0 /* quantization */
};
static const SANE_Range threshold_percentage_range = {
SANE_FIX (0), /* minimum */
SANE_FIX (100), /* maximum */
@ -686,9 +706,11 @@ sanei_genesys_create_slope_table3 (Genesys_Device * dev,
vtarget,
vstart,
vend,
dev->motor.slopes[power_mode][step_type].
dev->motor.
slopes[power_mode][step_type].
minimum_steps << step_type,
dev->motor.slopes[power_mode][step_type].g,
dev->motor.
slopes[power_mode][step_type].g,
used_steps, &vfinal);
if (final_exposure)
@ -719,9 +741,8 @@ genesys_create_slope_table4 (Genesys_Device * dev,
DBG (DBG_proc,
"sanei_genesys_create_slope_table: %d steps, step_type = %d, "
"exposure_time = %d, same_speed = %d, yres = %.2f, power_mode = %d\n",
steps, step_type,
exposure_time, same_speed, yres, power_mode);
"exposure_time = %d, same_speed = %d, yres = %.2f, power_mode = %d\n",
steps, step_type, exposure_time, same_speed, yres, power_mode);
/* final speed */
vtarget = (exposure_time * yres) / dev->motor.base_ydpi;
@ -746,9 +767,11 @@ genesys_create_slope_table4 (Genesys_Device * dev,
vtarget,
vstart,
vend,
dev->motor.slopes[power_mode][step_type].
dev->motor.
slopes[power_mode][step_type].
minimum_steps << step_type,
dev->motor.slopes[power_mode][step_type].g,
dev->motor.
slopes[power_mode][step_type].g,
NULL, NULL);
DBG (DBG_proc,
@ -774,9 +797,8 @@ genesys_create_slope_table2 (Genesys_Device * dev,
DBG (DBG_proc,
"sanei_genesys_create_slope_table2: %d steps, step_type = %d, "
"exposure_time = %d, same_speed = %d, yres = %.2f, power_mode = %d\n",
steps, step_type,
exposure_time, same_speed, yres, power_mode);
"exposure_time = %d, same_speed = %d, yres = %.2f, power_mode = %d\n",
steps, step_type, exposure_time, same_speed, yres, power_mode);
/* start speed */
if (dev->model->motor_type == MOTOR_5345)
@ -1104,9 +1126,9 @@ sanei_genesys_exposure_time2 (Genesys_Device * dev, float ydpi,
int led_exposure, int power_mode)
{
int exposure_by_ccd = endpixel + 32;
int exposure_by_motor =
(dev->motor.slopes[power_mode][step_type].maximum_speed
*dev->motor.base_ydpi)/ydpi;
int exposure_by_motor =
(dev->motor.slopes[power_mode][step_type].maximum_speed
* dev->motor.base_ydpi) / ydpi;
int exposure_by_led = led_exposure;
int exposure = exposure_by_ccd;
@ -2201,8 +2223,7 @@ genesys_dark_shading_calibration (Genesys_Device * dev)
else
channels = 1;
if (dev->dark_average_data)
free (dev->dark_average_data);
FREE_IFNOT_NULL (dev->dark_average_data);
dev->dark_average_data = malloc (channels * 2 * pixels_per_line);
if (!dev->dark_average_data)
@ -2333,8 +2354,7 @@ genesys_dummy_dark_shading (Genesys_Device * dev)
else
channels = 1;
if (dev->dark_average_data)
free (dev->dark_average_data);
FREE_IFNOT_NULL (dev->dark_average_data);
dev->dark_average_data = malloc (channels * 2 * pixels_per_line);
if (!dev->dark_average_data)
@ -3225,8 +3245,17 @@ genesys_flatbed_calibration (Genesys_Device * dev)
if (dev->settings.yres <= dev->sensor.optical_res / 2)
yres /= 2;
/* send default gamma table */
status = dev->model->cmd_set->send_gamma_table (dev, 1);
/* send custom or generic gamma tables depending on flag */
if (dev->model->flags & GENESYS_FLAG_CUSTOM_GAMMA)
{
/* use custom gamma table */
status = dev->model->cmd_set->send_gamma_table (dev, 0);
}
else
{
/* send default gamma table if no custom gamma */
status = dev->model->cmd_set->send_gamma_table (dev, 1);
}
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
@ -3412,7 +3441,7 @@ genesys_flatbed_calibration (Genesys_Device * dev)
return status;
}
/* send gamma tables if needed */
/* send specific gamma tables if needed */
status = dev->model->cmd_set->send_gamma_table (dev, 0);
if (status != SANE_STATUS_GOOD)
{
@ -4488,12 +4517,13 @@ calc_parameters (Genesys_Scanner * s)
s->params.last_frame = SANE_TRUE; /* only single pass scanning supported */
if (strcmp (mode, "Gray") == 0 || strcmp (mode, "Lineart") == 0)
if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0
|| strcmp (mode, SANE_VALUE_SCAN_MODE_LINEART) == 0)
s->params.format = SANE_FRAME_GRAY;
else /* Color */
s->params.format = SANE_FRAME_RGB;
if (strcmp (mode, "Lineart") == 0)
if (strcmp (mode, SANE_VALUE_SCAN_MODE_LINEART) == 0)
s->params.depth = 1;
else
s->params.depth = depth;
@ -4534,11 +4564,11 @@ calc_parameters (Genesys_Scanner * s)
if (s->params.format == SANE_FRAME_RGB)
s->params.bytes_per_line *= 3;
if (strcmp (mode, "Color") == 0)
if (strcmp (mode, SANE_VALUE_SCAN_MODE_COLOR) == 0)
s->dev->settings.scan_mode = 4;
else if (strcmp (mode, "Gray") == 0)
else if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0)
s->dev->settings.scan_mode = 2;
else if (strcmp (mode, "Halftone") == 0)
else if (strcmp (mode, SANE_TITLE_HALFTONE) == 0)
s->dev->settings.scan_mode = 1;
else /* Lineart */
s->dev->settings.scan_mode = 0;
@ -4584,6 +4614,41 @@ create_bpp_list (Genesys_Scanner * s, SANE_Int * bpp)
return SANE_STATUS_GOOD;
}
/* this function initialize a gamma vector based on the ASIC:
* gl646: 12 or 14 bits gamma table depending on GENESYS_FLAG_14BIT_GAMMA
* gl84x: 16 bits
*/
static void
init_gamma_vector_option (Genesys_Scanner * scanner, int option)
{
/* the option is inactive until the custom gamma control
* is enabled */
scanner->opt[option].type = SANE_TYPE_INT;
scanner->opt[option].cap |= SANE_CAP_INACTIVE | SANE_CAP_ADVANCED;
scanner->opt[option].unit = SANE_UNIT_NONE;
scanner->opt[option].constraint_type = SANE_CONSTRAINT_RANGE;
if (scanner->dev->model->asic_type == GENESYS_GL646)
{
if ((scanner->dev->model->flags & GENESYS_FLAG_14BIT_GAMMA) != 0)
{
scanner->opt[option].size = 16384 * sizeof (SANE_Word);
scanner->opt[option].constraint.range = &u14_range;
}
else
{ /* 12 bits gamma tables */
scanner->opt[option].size = 4096 * sizeof (SANE_Word);
scanner->opt[option].constraint.range = &u12_range;
}
}
else
{ /* GL841 case */
scanner->opt[option].size = 256 * sizeof (SANE_Word);
scanner->opt[option].constraint.range = &u16_range;
}
/* default value is NULL */
scanner->val[option].wa = NULL;
}
static SANE_Status
init_options (Genesys_Scanner * s)
{
@ -4629,7 +4694,7 @@ init_options (Genesys_Scanner * s)
s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
s->opt[OPT_MODE].size = max_string_size (mode_list);
s->opt[OPT_MODE].constraint.string_list = mode_list;
s->val[OPT_MODE].s = strdup ("Gray");
s->val[OPT_MODE].s = strdup (SANE_VALUE_SCAN_MODE_GRAY);
/* scan source */
s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
@ -4735,6 +4800,56 @@ init_options (Genesys_Scanner * s)
s->opt[OPT_BR_Y].constraint.range = &y_range;
s->val[OPT_BR_Y].w = y_range.max;
/* "Enhancement" group: */
s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement");
s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
s->opt[OPT_ENHANCEMENT_GROUP].cap = SANE_CAP_ADVANCED;
s->opt[OPT_ENHANCEMENT_GROUP].size = 0;
s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
/* custom-gamma table */
s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA;
s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA;
s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_ADVANCED;
s->val[OPT_CUSTOM_GAMMA].b = SANE_FALSE;
/* grayscale gamma vector */
s->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
s->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
s->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
init_gamma_vector_option (s, OPT_GAMMA_VECTOR);
/* red gamma vector */
s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
init_gamma_vector_option (s, OPT_GAMMA_VECTOR_R);
/* green gamma vector */
s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
init_gamma_vector_option (s, OPT_GAMMA_VECTOR_G);
/* blue gamma vector */
s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
init_gamma_vector_option (s, OPT_GAMMA_VECTOR_B);
/* currently, there are only gamma table options in this group,
* so if the scanner doesn't support gamma table, disable the
* whole group */
if (!(s->dev->model->flags & GENESYS_FLAG_CUSTOM_GAMMA))
{
s->opt[OPT_ENHANCEMENT_GROUP].cap |= SANE_CAP_INACTIVE;
s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
DBG (DBG_info, "init_options: custom gamma disabled\n");
}
/* "Extras" group: */
s->opt[OPT_EXTRAS_GROUP].title = SANE_I18N ("Extras");
s->opt[OPT_EXTRAS_GROUP].desc = "";
@ -5033,15 +5148,8 @@ sane_exit (void)
DBG (DBG_proc, "sane_exit: start\n");
for (dev = first_dev; dev; dev = next)
{
if (dev->already_initialized)
{
if (dev->sensor.red_gamma_table)
free (dev->sensor.red_gamma_table);
if (dev->sensor.green_gamma_table)
free (dev->sensor.green_gamma_table);
if (dev->sensor.blue_gamma_table)
free (dev->sensor.blue_gamma_table);
}
/* sane_close() free many fields, not much things left to
* do here */
next = dev->next;
free (dev->file_name);
free (dev);
@ -5103,8 +5211,12 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
DBG (DBG_proc, "sane_open: start (devicename = `%s')\n", devicename);
if (devicename[0])
/* devicename="" or devicename="genesys" are default values that use
* first available device
*/
if (devicename[0] && strcmp ("genesys", devicename) != 0)
{
/* search for the given devicename in the device list */
for (dev = first_dev; dev; dev = dev->next)
if (strcmp (dev->file_name, devicename) == 0)
break;
@ -5122,7 +5234,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
}
else
{
/* empty devicename -> use first device */
/* empty devicename or "genesys" -> use first device */
dev = first_dev;
if (dev)
{
@ -5219,16 +5331,19 @@ sane_close (SANE_Handle handle)
sanei_genesys_buffer_free (&(s->dev->lines_buffer));
sanei_genesys_buffer_free (&(s->dev->shrink_buffer));
sanei_genesys_buffer_free (&(s->dev->out_buffer));
FREE_IFNOT_NULL (s->dev->white_average_data);
FREE_IFNOT_NULL (s->dev->dark_average_data);
if (s->dev->white_average_data != NULL)
free (s->dev->white_average_data);
if (s->dev->dark_average_data != NULL)
free (s->dev->dark_average_data);
/* free allocated gamma tables */
FREE_IFNOT_NULL (s->dev->sensor.red_gamma_table);
FREE_IFNOT_NULL (s->dev->sensor.green_gamma_table);
FREE_IFNOT_NULL (s->dev->sensor.blue_gamma_table);
/* for an handful of bytes .. */
free (s->opt[OPT_RESOLUTION].constraint.word_list);
free (s->val[OPT_SOURCE].s);
free (s->val[OPT_MODE].s);
free (s->val[OPT_COLOR_FILTER].s);
if (prev)
prev->next = s->next;
@ -5255,12 +5370,291 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
return s->opt + option;
}
/* gets an option , called by sane_control_option */
static SANE_Status
get_option_value (Genesys_Scanner * s, int option, void *val)
{
unsigned int i;
SANE_Word *table;
u_int16_t *gamma;
switch (option)
{
/* word options: */
case OPT_NUM_OPTS:
case OPT_RESOLUTION:
case OPT_BIT_DEPTH:
case OPT_PREVIEW:
case OPT_TL_X:
case OPT_TL_Y:
case OPT_BR_X:
case OPT_BR_Y:
case OPT_THRESHOLD:
case OPT_DISABLE_INTERPOLATION:
case OPT_LAMP_OFF_TIME:
case OPT_CUSTOM_GAMMA:
*(SANE_Word *) val = s->val[option].w;
break;
/* string options: */
case OPT_MODE:
case OPT_COLOR_FILTER:
case OPT_SOURCE:
strcpy (val, s->val[option].s);
break;
/* word array options */
case OPT_GAMMA_VECTOR:
table = (SANE_Word *) val;
if (strcmp (s->val[OPT_COLOR_FILTER].s, "Red") == 0)
{
gamma = s->dev->sensor.red_gamma_table;
}
else if (strcmp (s->val[OPT_COLOR_FILTER].s, "Blue") == 0)
{
gamma = s->dev->sensor.blue_gamma_table;
}
else
{
gamma = s->dev->sensor.green_gamma_table;
}
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
table[i] = gamma[i];
}
break;
case OPT_GAMMA_VECTOR_R:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
table[i] = s->dev->sensor.red_gamma_table[i];
}
break;
case OPT_GAMMA_VECTOR_G:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
table[i] = s->dev->sensor.green_gamma_table[i];
}
break;
case OPT_GAMMA_VECTOR_B:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
table[i] = s->dev->sensor.blue_gamma_table[i];
}
break;
default:
DBG (DBG_warn, "get_option_value: can't get unknown option %d\n",
option);
}
return SANE_STATUS_GOOD;
}
/* sets an option , called by sane_control_option */
static SANE_Status
set_option_value (Genesys_Scanner * s, int option, void *val,
SANE_Int * myinfo)
{
SANE_Status status;
SANE_Word *table;
unsigned int i;
switch (option)
{
case OPT_TL_X:
case OPT_TL_Y:
case OPT_BR_X:
case OPT_BR_Y:
s->val[option].w = *(SANE_Word *) val;
RIE (calc_parameters (s));
*myinfo |= SANE_INFO_RELOAD_PARAMS;
break;
case OPT_RESOLUTION:
case OPT_BIT_DEPTH:
case OPT_THRESHOLD:
case OPT_DISABLE_INTERPOLATION:
case OPT_PREVIEW:
s->val[option].w = *(SANE_Word *) val;
RIE (calc_parameters (s));
*myinfo |= SANE_INFO_RELOAD_PARAMS;
break;
case OPT_SOURCE:
if (strcmp (s->val[option].s, val) != 0)
{ /* something changed */
if (s->val[option].s)
free (s->val[option].s);
s->val[option].s = strdup (val);
*myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
}
break;
case OPT_MODE:
if (s->val[option].s)
free (s->val[option].s);
s->val[option].s = strdup (val);
if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
{
ENABLE (OPT_THRESHOLD);
DISABLE (OPT_BIT_DEPTH);
ENABLE (OPT_COLOR_FILTER);
}
else
{
DISABLE (OPT_THRESHOLD);
if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_GRAY) == 0)
{
ENABLE (OPT_COLOR_FILTER);
create_bpp_list (s, s->dev->model->bpp_gray_values);
}
else
{
DISABLE (OPT_COLOR_FILTER);
create_bpp_list (s, s->dev->model->bpp_color_values);
}
if (s->bpp_list[0] < 2)
DISABLE (OPT_BIT_DEPTH);
else
ENABLE (OPT_BIT_DEPTH);
}
RIE (calc_parameters (s));
/* if custom gamma, toggle gamma table options according to the mode */
if (s->val[OPT_CUSTOM_GAMMA].b == SANE_TRUE)
{
if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
{
DISABLE (OPT_GAMMA_VECTOR);
ENABLE (OPT_GAMMA_VECTOR_R);
ENABLE (OPT_GAMMA_VECTOR_G);
ENABLE (OPT_GAMMA_VECTOR_B);
}
else
{
ENABLE (OPT_GAMMA_VECTOR);
DISABLE (OPT_GAMMA_VECTOR_R);
DISABLE (OPT_GAMMA_VECTOR_G);
DISABLE (OPT_GAMMA_VECTOR_B);
}
}
*myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
break;
case OPT_COLOR_FILTER:
if (s->val[option].s)
free (s->val[option].s);
s->val[option].s = strdup (val);
RIE (calc_parameters (s));
break;
case OPT_LAMP_OFF_TIME:
if (*(SANE_Word *) val != s->val[option].w)
{
s->val[option].w = *(SANE_Word *) val;
RIE (s->dev->model->cmd_set->
set_powersaving (s->dev, s->val[option].w));
}
break;
case OPT_CUSTOM_GAMMA:
*myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
s->val[OPT_CUSTOM_GAMMA].b = *(SANE_Bool *) val;
if (s->val[OPT_CUSTOM_GAMMA].b == SANE_TRUE)
{
if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
{
DISABLE (OPT_GAMMA_VECTOR);
ENABLE (OPT_GAMMA_VECTOR_R);
ENABLE (OPT_GAMMA_VECTOR_G);
ENABLE (OPT_GAMMA_VECTOR_B);
}
else
{
ENABLE (OPT_GAMMA_VECTOR);
DISABLE (OPT_GAMMA_VECTOR_R);
DISABLE (OPT_GAMMA_VECTOR_G);
DISABLE (OPT_GAMMA_VECTOR_B);
}
}
else
{
DISABLE (OPT_GAMMA_VECTOR);
DISABLE (OPT_GAMMA_VECTOR_R);
DISABLE (OPT_GAMMA_VECTOR_G);
DISABLE (OPT_GAMMA_VECTOR_B);
/* restore default sensor gamma table */
/* currently there is no sensor's specific gamma table,
* tables are built by sanei_genesys_create_gamma_table */
sanei_genesys_create_gamma_table (s->dev->sensor.red_gamma_table,
s->opt[OPT_GAMMA_VECTOR_R].size /
sizeof (SANE_Word),
s->opt[OPT_GAMMA_VECTOR_R].
constraint.range->max,
s->opt[OPT_GAMMA_VECTOR_R].
constraint.range->max,
s->dev->sensor.red_gamma);
sanei_genesys_create_gamma_table (s->dev->sensor.green_gamma_table,
s->opt[OPT_GAMMA_VECTOR_G].size /
sizeof (SANE_Word),
s->opt[OPT_GAMMA_VECTOR_G].
constraint.range->max,
s->opt[OPT_GAMMA_VECTOR_G].
constraint.range->max,
s->dev->sensor.red_gamma);
sanei_genesys_create_gamma_table (s->dev->sensor.blue_gamma_table,
s->opt[OPT_GAMMA_VECTOR_B].size /
sizeof (SANE_Word),
s->opt[OPT_GAMMA_VECTOR_B].
constraint.range->max,
s->opt[OPT_GAMMA_VECTOR_B].
constraint.range->max,
s->dev->sensor.red_gamma);
}
break;
case OPT_GAMMA_VECTOR:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
s->dev->sensor.red_gamma_table[i] = table[i];
s->dev->sensor.green_gamma_table[i] = table[i];
s->dev->sensor.blue_gamma_table[i] = table[i];
}
break;
case OPT_GAMMA_VECTOR_R:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
s->dev->sensor.red_gamma_table[i] = table[i];
}
break;
case OPT_GAMMA_VECTOR_G:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
s->dev->sensor.green_gamma_table[i] = table[i];
}
break;
case OPT_GAMMA_VECTOR_B:
table = (SANE_Word *) val;
for (i = 0; i < s->opt[option].size / sizeof (SANE_Word); i++)
{
s->dev->sensor.blue_gamma_table[i] = table[i];
}
break;
default:
DBG (DBG_warn, "set_option_value: can't set unknown option %d\n",
option);
}
return SANE_STATUS_GOOD;
}
/* sets and gets scanner option values */
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
SANE_Action action, void *val, SANE_Int * info)
{
Genesys_Scanner *s = handle;
SANE_Status status;
SANE_Status status = SANE_STATUS_GOOD;
SANE_Word cap;
SANE_Int myinfo = 0;
@ -5297,37 +5691,13 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
return SANE_STATUS_INVAL;
}
if (action == SANE_ACTION_GET_VALUE)
{
switch (option)
{
/* word options: */
case OPT_NUM_OPTS:
case OPT_RESOLUTION:
case OPT_BIT_DEPTH:
case OPT_PREVIEW:
case OPT_TL_X:
case OPT_TL_Y:
case OPT_BR_X:
case OPT_BR_Y:
case OPT_THRESHOLD:
case OPT_DISABLE_INTERPOLATION:
case OPT_LAMP_OFF_TIME:
*(SANE_Word *) val = s->val[option].w;
break;
/* string options: */
case OPT_MODE:
case OPT_COLOR_FILTER:
case OPT_SOURCE:
strcpy (val, s->val[option].s);
break;
default:
DBG (DBG_warn, "sane_control_option: can't get unknown option %d\n",
option);
}
}
else if (action == SANE_ACTION_SET_VALUE)
switch (action)
{
case SANE_ACTION_GET_VALUE:
status = get_option_value (s, option, val);
break;
case SANE_ACTION_SET_VALUE:
if (!SANE_OPTION_IS_SETTABLE (cap))
{
DBG (DBG_warn, "sane_control_option: option %d is not settable\n",
@ -5336,7 +5706,6 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
}
status = sanei_constrain_value (s->opt + option, val, &myinfo);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_warn,
@ -5345,113 +5714,31 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
return status;
}
switch (option)
{
case OPT_TL_X:
case OPT_TL_Y:
case OPT_BR_X:
case OPT_BR_Y:
s->val[option].w = *(SANE_Word *) val;
RIE (calc_parameters (s));
myinfo |= SANE_INFO_RELOAD_PARAMS;
break;
case OPT_RESOLUTION:
case OPT_BIT_DEPTH:
case OPT_THRESHOLD:
case OPT_DISABLE_INTERPOLATION:
case OPT_PREVIEW:
s->val[option].w = *(SANE_Word *) val;
RIE (calc_parameters (s));
myinfo |= SANE_INFO_RELOAD_PARAMS;
break;
case OPT_SOURCE:
if (strcmp (s->val[option].s, val) != 0)
{ /* something changed */
if (s->val[option].s)
free (s->val[option].s);
s->val[option].s = strdup (val);
if (strcmp (s->val[option].s, "Transparency Adapter") == 0)
{
/* RIE (gt68xx_device_lamp_control
(s->dev, SANE_FALSE, SANE_TRUE));
x_range.max = s->dev->model->x_size_ta;
y_range.max = s->dev->model->y_size_ta; */
}
else
{
/* RIE (gt68xx_device_lamp_control
(s->dev, SANE_TRUE, SANE_FALSE));
x_range.max = s->dev->model->x_size;
y_range.max = s->dev->model->y_size; */
}
myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
}
break;
case OPT_MODE:
if (s->val[option].s)
free (s->val[option].s);
s->val[option].s = strdup (val);
if (strcmp (s->val[option].s, "Lineart") == 0)
{
ENABLE (OPT_THRESHOLD);
DISABLE (OPT_BIT_DEPTH);
ENABLE (OPT_COLOR_FILTER);
}
else
{
DISABLE (OPT_THRESHOLD);
if (strcmp (s->val[option].s, "Gray") == 0)
{
ENABLE (OPT_COLOR_FILTER);
create_bpp_list (s, s->dev->model->bpp_gray_values);
}
else
{
DISABLE (OPT_COLOR_FILTER);
create_bpp_list (s, s->dev->model->bpp_color_values);
}
if (s->bpp_list[0] < 2)
DISABLE (OPT_BIT_DEPTH);
else
ENABLE (OPT_BIT_DEPTH);
}
RIE (calc_parameters (s));
myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
break;
case OPT_COLOR_FILTER:
if (s->val[option].s)
free (s->val[option].s);
s->val[option].s = strdup (val);
RIE (calc_parameters (s));
break;
case OPT_LAMP_OFF_TIME:
if (*(SANE_Word *) val != s->val[option].w)
{
s->val[option].w = *(SANE_Word *) val;
RIE (s->dev->model->cmd_set->
set_powersaving (s->dev, s->val[option].w));
}
break;
/* string options: */
status = set_option_value (s, option, val, &myinfo);
break;
default:
DBG (DBG_warn, "sane_control_option: can't set unknown option %d\n",
option);
}
}
else
{
case SANE_ACTION_SET_AUTO:
DBG (DBG_error,
"sane_control_option: SANE_ACTION_SET_AUTO unsupported since no option has SANE_CAP_AUTOMATIC\n");
status = SANE_STATUS_INVAL;
break;
default:
DBG (DBG_warn, "sane_control_option: unknown action %d for option %d\n",
action, option);
return SANE_STATUS_INVAL;
status = SANE_STATUS_INVAL;
break;
}
if (info)
*info = myinfo;
DBG (DBG_io2, "sane_control_option: exit\n");
return SANE_STATUS_GOOD;
return status;
}
SANE_Status
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
{

Wyświetl plik

@ -81,6 +81,14 @@ enum Genesys_Option
OPT_BR_X, /* bottom-right x */
OPT_BR_Y, /* bottom-right y */
/* advanced image enhancement options */
OPT_ENHANCEMENT_GROUP,
OPT_CUSTOM_GAMMA, /* toggle to enable custom gamma tables */
OPT_GAMMA_VECTOR,
OPT_GAMMA_VECTOR_R,
OPT_GAMMA_VECTOR_G,
OPT_GAMMA_VECTOR_B,
OPT_EXTRAS_GROUP,
OPT_LAMP_OFF_TIME,
OPT_THRESHOLD,

Wyświetl plik

@ -561,7 +561,9 @@ static Genesys_Model hp2300c_model = {
| GENESYS_FLAG_14BIT_GAMMA
| GENESYS_FLAG_SEARCH_START
| GENESYS_FLAG_MUST_WAIT
| GENESYS_FLAG_DARK_CALIBRATION | GENESYS_FLAG_OFFSET_CALIBRATION,
| GENESYS_FLAG_DARK_CALIBRATION
| GENESYS_FLAG_OFFSET_CALIBRATION
| GENESYS_FLAG_CUSTOM_GAMMA,
9,
132
};
@ -607,7 +609,9 @@ static Genesys_Model hp2400c_model = {
| GENESYS_FLAG_14BIT_GAMMA
| GENESYS_FLAG_SEARCH_START
| GENESYS_FLAG_MUST_WAIT
| GENESYS_FLAG_DARK_CALIBRATION | GENESYS_FLAG_OFFSET_CALIBRATION,
| GENESYS_FLAG_DARK_CALIBRATION
| GENESYS_FLAG_OFFSET_CALIBRATION
| GENESYS_FLAG_CUSTOM_GAMMA,
20,
132
};
@ -783,7 +787,9 @@ static Genesys_Model medion_md5345_model = {
| GENESYS_FLAG_SKIP_WARMUP
| GENESYS_FLAG_SEARCH_START
| GENESYS_FLAG_DARK_CALIBRATION
| GENESYS_FLAG_STAGGERED_LINE | GENESYS_FLAG_OFFSET_CALIBRATION,
| GENESYS_FLAG_STAGGERED_LINE
| GENESYS_FLAG_OFFSET_CALIBRATION
| GENESYS_FLAG_CUSTOM_GAMMA,
32,
200
};

Wyświetl plik

@ -269,7 +269,7 @@ gl646_bulk_write_register (Genesys_Device * dev,
elems = i;
size = i * 2;
DBG (DBG_io, "gl646_bulk_write_register (elems= %lu, size = %lu)\n",
DBG (DBG_io, "gl646_bulk_write_register (elems= %lu, size = %lu)\n",
(u_long) elems, (u_long) size);
@ -312,7 +312,7 @@ gl646_bulk_write_register (Genesys_Device * dev,
for (i = 0; i < size; i += 2)
DBG (DBG_io2, "reg[0x%02x] = 0x%02x\n", buffer[i], buffer[i + 1]);
DBG (DBG_io, "gl646_bulk_write_register: wrote %lu bytes, %lu registers\n",
DBG (DBG_io, "gl646_bulk_write_register: wrote %lu bytes, %lu registers\n",
(u_long) size, (u_long) elems);
return status;
}
@ -1322,7 +1322,7 @@ gl646_set_motor_power (Genesys_Register_Set * regs, SANE_Bool set)
}
static void
gl646_set_lamp_power (Genesys_Device * dev,
gl646_set_lamp_power (Genesys_Device * dev,
Genesys_Register_Set * regs, SANE_Bool set)
{
if (set)
@ -1430,8 +1430,9 @@ gl646_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ )
local_reg[3].value = exposure_time / 256; /* highbyte */
local_reg[4].value = exposure_time & 255; /* lowbyte */
status = gl646_bulk_write_register (dev, local_reg,
sizeof (local_reg)/sizeof (local_reg[0]));
status = gl646_bulk_write_register (dev, local_reg,
sizeof (local_reg) /
sizeof (local_reg[0]));
if (status != SANE_STATUS_GOOD)
DBG (DBG_error,
"gl646_set_powersaving: Failed to bulk write registers: %s\n",
@ -1464,8 +1465,9 @@ gl646_begin_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
else
local_reg[2].value = 0x00; /* do not start motor yet */
status = gl646_bulk_write_register (dev, local_reg,
sizeof (local_reg)/sizeof (local_reg[0]));
status = gl646_bulk_write_register (dev, local_reg,
sizeof (local_reg) /
sizeof (local_reg[0]));
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
@ -1576,7 +1578,8 @@ gl646_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
usleep (200000UL);
}
memcpy (local_reg, dev->reg, (GENESYS_GL646_MAX_REGS + 1) * sizeof(Genesys_Register_Set));
memcpy (local_reg, dev->reg,
(GENESYS_GL646_MAX_REGS + 1) * sizeof (Genesys_Register_Set));
prepare_steps = 4;
exposure_time = 6 * MOTOR_SPEED_MAX;
@ -1629,9 +1632,7 @@ gl646_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
}
else
{
sanei_genesys_create_slope_table (dev, slope_table0, prepare_steps, 0,
exposure_time, 0,
dev->motor.base_ydpi, /*MOTOR_GEAR */
sanei_genesys_create_slope_table (dev, slope_table0, prepare_steps, 0, exposure_time, 0, dev->motor.base_ydpi, /*MOTOR_GEAR */
0);
}
@ -1682,8 +1683,7 @@ gl646_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
return status;
}
status =
gl646_bulk_write_register (dev, local_reg, GENESYS_GL646_MAX_REGS);
status = gl646_bulk_write_register (dev, local_reg, GENESYS_GL646_MAX_REGS);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
@ -1934,7 +1934,8 @@ gl646_search_start_position (Genesys_Device * dev)
DBG (DBG_proc, "gl646_search_start_position\n");
memset (local_reg, 0, sizeof (local_reg));
memcpy (local_reg, dev->reg, (GENESYS_GL646_MAX_REGS + 1) * sizeof(Genesys_Register_Set));
memcpy (local_reg, dev->reg,
(GENESYS_GL646_MAX_REGS + 1) * sizeof (Genesys_Register_Set));
gettimeofday (&tv, NULL);
/* is scanner warm enough ? */
@ -2064,8 +2065,7 @@ gl646_search_start_position (Genesys_Device * dev)
}
/* send to scanner */
status =
gl646_bulk_write_register (dev, local_reg, GENESYS_GL646_MAX_REGS);
status = gl646_bulk_write_register (dev, local_reg, GENESYS_GL646_MAX_REGS);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
@ -2184,7 +2184,8 @@ gl646_search_start_position (Genesys_Device * dev)
/* update regs to copy ASIC internal state */
dev->reg[reg_0x01].value = local_reg[reg_0x01].value;
dev->reg[reg_0x02].value = local_reg[reg_0x02].value;
memcpy (dev->reg, local_reg, (GENESYS_GL646_MAX_REGS + 1) * sizeof(Genesys_Register_Set));
memcpy (dev->reg, local_reg,
(GENESYS_GL646_MAX_REGS + 1) * sizeof (Genesys_Register_Set));
status =
sanei_genesys_search_reference_point (dev, data, start_pixel, dpi, pixels,
@ -2307,14 +2308,8 @@ gl646_init_regs_for_coarse_calibration (Genesys_Device * dev)
/* todo: only 2 steps? */
steps_sum =
sanei_genesys_create_slope_table (dev, slope_table,
dev->calib_reg[reg_0x21].value,
dev->calib_reg[reg_0x02].
value & REG02_STEPSEL,
dev->settings.exposure_time, 0,
dev->motor.base_ydpi, /*MOTOR_GEAR */
0);
steps_sum = sanei_genesys_create_slope_table (dev, slope_table, dev->calib_reg[reg_0x21].value, dev->calib_reg[reg_0x02].value & REG02_STEPSEL, dev->settings.exposure_time, 0, dev->motor.base_ydpi, /*MOTOR_GEAR */
0);
/* todo: z1 = z2 = 0? */
sanei_genesys_calculate_zmode (dev,
@ -2353,8 +2348,7 @@ gl646_init_regs_for_coarse_calibration (Genesys_Device * dev)
}
status =
gl646_bulk_write_register (dev, dev->calib_reg,
GENESYS_GL646_MAX_REGS);
gl646_bulk_write_register (dev, dev->calib_reg, GENESYS_GL646_MAX_REGS);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
@ -2400,7 +2394,25 @@ gl646_init_regs_for_shading (Genesys_Device * dev)
/* monochrome / color scan */
dev->calib_reg[reg_0x04].value &= ~REG04_FILTER;
if (channels == 1)
dev->calib_reg[reg_0x04].value |= 0x08;
{
switch (dev->settings.color_filter)
{
/* red */
case 0:
dev->calib_reg[reg_0x04].value |= 0x04;
break;
/* green */
case 1:
dev->calib_reg[reg_0x04].value |= 0x08;
break;
/* blue */
case 2:
dev->calib_reg[reg_0x04].value |= 0x0c;
break;
default:
return SANE_STATUS_INVAL;
}
}
/* disable forward/backward+motor, stepsel = 1 */
dev->calib_reg[reg_0x02].value =
@ -2638,8 +2650,7 @@ gl646_init_regs_for_shading (Genesys_Device * dev)
}
status =
gl646_bulk_write_register (dev, dev->calib_reg,
GENESYS_GL646_MAX_REGS);
gl646_bulk_write_register (dev, dev->calib_reg, GENESYS_GL646_MAX_REGS);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
@ -2821,15 +2832,34 @@ gl646_init_regs_for_scan (Genesys_Device * dev)
/* monochrome / color scan */
dev->reg[reg_0x04].value &= ~(REG04_FILTER | REG04_BITSET);
/* we could make the color filter used an advanced option of the backend */
/* select color filter based on settings */
if (channels == 1)
dev->reg[reg_0x04].value |= 0x08; /* green filter */
{
switch (dev->settings.color_filter)
{
/* red */
case 0:
dev->reg[reg_0x04].value |= 0x04;
break;
/* green */
case 1:
dev->reg[reg_0x04].value |= 0x08;
break;
/* blue */
case 2:
dev->reg[reg_0x04].value |= 0x0c;
break;
default:
return SANE_STATUS_INVAL;
}
}
/* bit depth: 8bit + gamma, 16 bits + no gamma */
if (dev->settings.scan_mode == 0)
{
/* lineart, todo : find logs of real lineart, not an emulated one
with gray level scanning */
/* lineart, TODO : find logs of real lineart, not an emulated one
with gray level scanning, since can't make it work on doc basis */
depth = 8;
dev->reg[reg_0x04].value &= ~REG04_LINEART;
}
@ -3198,22 +3228,6 @@ gl646_send_gamma_table (Genesys_Device * dev, SANE_Bool generic)
else
size = 4096;
/* table address */
switch (dev->reg[reg_0x05].value >> 6)
{
case 0: /* 600 dpi */
address = 0x09000;
break;
case 1: /* 1200 dpi */
address = 0x11000;
break;
case 2: /* 2400 dpi */
address = 0x20000;
break;
default:
return SANE_STATUS_INVAL;
}
/* allocate temporary gamma tables: 16 bits words, 3 channels */
gamma = (u_int8_t *) malloc (size * 2 * 3);
if (!gamma)
@ -3246,6 +3260,23 @@ gl646_send_gamma_table (Genesys_Device * dev, SANE_Bool generic)
}
}
/* table address */
switch (dev->reg[reg_0x05].value >> 6)
{
case 0: /* 600 dpi */
address = 0x09000;
break;
case 1: /* 1200 dpi */
address = 0x11000;
break;
case 2: /* 2400 dpi */
address = 0x20000;
break;
default:
free (gamma);
return SANE_STATUS_INVAL;
}
/* send address */
status = sanei_genesys_set_buffer_address (dev, address);
if (status != SANE_STATUS_GOOD)
@ -3371,7 +3402,25 @@ gl646_offset_calibration (Genesys_Device * dev)
(dev->calib_reg[reg_0x04].
value & ~REG04_LINEART & ~REG04_FILTER) | REG04_BITSET;
if (channels == 1)
dev->calib_reg[reg_0x04].value |= 0x08; /* green filter */
{
switch (dev->settings.color_filter)
{
/* red */
case 0:
dev->calib_reg[reg_0x04].value |= 0x04;
break;
/* green */
case 1:
dev->calib_reg[reg_0x04].value |= 0x08;
break;
/* blue */
case 2:
dev->calib_reg[reg_0x04].value |= 0x0c;
break;
default:
return SANE_STATUS_INVAL;
}
}
dev->calib_reg[reg_0x05].value = (dev->calib_reg[reg_0x05].value & ~REG05_GMMENB); /* disable gamma */
@ -3855,7 +3904,8 @@ gl646_init_regs_for_warmup (Genesys_Device * dev,
DBG (DBG_proc, "gl646_warmup_lamp\n");
memcpy (local_reg, dev->reg, (GENESYS_GL646_MAX_REGS + 1) * sizeof(Genesys_Register_Set));
memcpy (local_reg, dev->reg,
(GENESYS_GL646_MAX_REGS + 1) * sizeof (Genesys_Register_Set));
*total_size = num_pixels * 3 * 2 * 1; /* colors * bytes_per_color * scan lines */
/* ST12: 0x01 0x00 0x02 0x41 0x03 0x1f 0x04 0x53 0x05 0x10 0x06 0x10 0x08 0x02 0x09 0x00 0x0a 0x06 0x0b 0x04 */
@ -4019,8 +4069,7 @@ gl646_init_regs_for_warmup (Genesys_Device * dev,
RIE (gl646_set_fe (dev, AFE_INIT));
RIE (gl646_bulk_write_register
(dev, local_reg, GENESYS_GL646_MAX_REGS));
RIE (gl646_bulk_write_register (dev, local_reg, GENESYS_GL646_MAX_REGS));
return status;
}
@ -4046,7 +4095,8 @@ gl646_repark_head (Genesys_Device * dev)
DBG (DBG_proc, "gl646_repark_head\n");
memset (local_reg, 0, sizeof (local_reg));
memcpy (local_reg, dev->reg, (GENESYS_GL646_MAX_REGS + 1) * sizeof(Genesys_Register_Set));
memcpy (local_reg, dev->reg,
(GENESYS_GL646_MAX_REGS + 1) * sizeof (Genesys_Register_Set));
local_reg[reg_0x01].value =
local_reg[reg_0x01].value & ~REG01_DVDSET & ~REG01_FASTMOD & ~REG01_SCAN;
@ -4156,8 +4206,7 @@ gl646_repark_head (Genesys_Device * dev)
return status;
}
status =
gl646_bulk_write_register (dev, local_reg, GENESYS_GL646_MAX_REGS);
status = gl646_bulk_write_register (dev, local_reg, GENESYS_GL646_MAX_REGS);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl646_repark_head: failed to send registers: %s\n",
@ -4227,7 +4276,7 @@ gl646_init (Genesys_Device * dev)
dev->dark_average_data = NULL;
dev->white_average_data = NULL;
dev->settings.color_filter = 0;
dev->settings.color_filter = 1; /* green filter by default */
gettimeofday (&tv, NULL);
dev->init_date = tv.tv_sec;
@ -4275,7 +4324,7 @@ gl646_init (Genesys_Device * dev)
dev->reg[reg_0x21].value,
dev->reg[reg_0x02].
value & REG02_STEPSEL,
dev->settings.exposure_time, 0, 600,
dev->settings.exposure_time, 0, 600,
0);
sanei_genesys_create_slope_table (dev, dev->slope_table1,
dev->reg[reg_0x6b].value,
@ -4288,7 +4337,8 @@ gl646_init (Genesys_Device * dev)
sanei_genesys_create_slope_table (dev, dev->slope_table0,
dev->reg[reg_0x21].value,
dev->reg[reg_0x02].
value & REG02_STEPSEL, 250, 0, 600, 0);
value & REG02_STEPSEL, 250, 0, 600,
0);
sanei_genesys_create_slope_table (dev, dev->slope_table1,
dev->reg[reg_0x6b].value,
(dev->reg[reg_0x6a].
@ -4366,16 +4416,17 @@ gl646_init (Genesys_Device * dev)
/* fix for timeouts at init */
if (dev->model->ccd_type == CCD_5345)
{
sanei_usb_set_timeout (2 * 1000);
/* we read data without any pending scan to trigger timeout */
status = dev->model->cmd_set->bulk_read_data (dev, 0x45, data, 64);
if (status != SANE_STATUS_GOOD)
{
/* expected error */
DBG (DBG_error, "gl646_init: read stream reset ... %s\n",
DBG (DBG_info, "gl646_init: read stream reset ... %s\n",
sane_strstatus (status));
return status;
}
/* restore timeout */
sanei_usb_set_timeout (30 * 1000);
}
/* Move home */
@ -4412,7 +4463,8 @@ gl646_init (Genesys_Device * dev)
}
/* initial calibration reg values */
memcpy (dev->calib_reg, dev->reg, (GENESYS_GL646_MAX_REGS + 1) * sizeof(Genesys_Register_Set));
memcpy (dev->calib_reg, dev->reg,
(GENESYS_GL646_MAX_REGS + 1) * sizeof (Genesys_Register_Set));
/* Set powersaving (default = 15 minutes) */
RIE (gl646_set_powersaving (dev, 15));

Wyświetl plik

@ -95,6 +95,7 @@
creation function */
#define GENESYS_FLAG_DARK_WHITE_CALIBRATION (1 << 12) /*yet another calibration method. does white and dark shading in one run, depending on a black and a white strip*/
#define GENESYS_FLAG_CUSTOM_GAMMA (1 << 13) /* allow custom gamma tables */
/* USB control message values */
#define REQUEST_TYPE_IN (USB_TYPE_VENDOR | USB_DIR_IN)