kopia lustrzana https://gitlab.com/sane-project/backends
Introduce support for multiple scanners.
Keep all state local and ensure that all resources are freed by sane_exit. Ensure that each function returns only those error codes that are valid according to the SANE standard.merge-requests/1/head
rodzic
6865eaf6ed
commit
7fda9bbf93
|
@ -64,7 +64,9 @@
|
|||
#include "mustek_usb2.h"
|
||||
|
||||
|
||||
static const SANE_Device **devlist = NULL;
|
||||
static Scanner_Handle * first_handle = NULL;
|
||||
static Scanner_Device * first_device = NULL;
|
||||
static SANE_Device ** devlist;
|
||||
|
||||
static const SANE_Range u8_range = {
|
||||
0, /* minimum */
|
||||
|
@ -72,18 +74,6 @@ static const SANE_Range u8_range = {
|
|||
0 /* quantization */
|
||||
};
|
||||
|
||||
static SANE_Range x_range = {
|
||||
SANE_FIX (0.0),
|
||||
SANE_FIX (8.3 * MM_PER_INCH),
|
||||
SANE_FIX (0.0)
|
||||
};
|
||||
|
||||
static SANE_Range y_range = {
|
||||
SANE_FIX (0.0),
|
||||
SANE_FIX (11.6 * MM_PER_INCH),
|
||||
SANE_FIX (0.0)
|
||||
};
|
||||
|
||||
static SANE_String_Const mode_list[] = {
|
||||
SANE_I18N ("Color48"),
|
||||
SANE_I18N ("Color24"),
|
||||
|
@ -105,17 +95,22 @@ static SANE_String_Const source_list[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static const Scanner_Model mustek_A2nu2_model = {
|
||||
static const Scanner_Model models[] = {
|
||||
{
|
||||
"Mustek", /* device vendor string */
|
||||
"BearPaw 2448TA Pro", /* device model name */
|
||||
|
||||
0x055f, 0x0409, /* USB vendor and product ID */
|
||||
|
||||
{5 /* count */, 1200, 600, 300, 150, 75}, /* possible resolutions */
|
||||
|
||||
SANE_FIX (8.5 * MM_PER_INCH), /* size of scan area in mm (x) */
|
||||
SANE_FIX (11.8 * MM_PER_INCH), /* size of scan area in mm (y) */
|
||||
/* x and y size of scan area in mm */
|
||||
{SANE_FIX (0.0), SANE_FIX (8.5 * MM_PER_INCH), SANE_FIX (0.0)},
|
||||
{SANE_FIX (0.0), SANE_FIX (11.8 * MM_PER_INCH), SANE_FIX (0.0)},
|
||||
|
||||
SANE_FIX (1.46 * MM_PER_INCH), /* size of scan area in TA mode in mm (x) */
|
||||
SANE_FIX (6.45 * MM_PER_INCH), /* size of scan area in TA mode in mm (y) */
|
||||
/* x and y size of scan area in TA mode in mm */
|
||||
{SANE_FIX (0.0), SANE_FIX (1.46 * MM_PER_INCH), SANE_FIX (0.0)},
|
||||
{SANE_FIX (0.0), SANE_FIX (6.45 * MM_PER_INCH), SANE_FIX (0.0)},
|
||||
|
||||
SANE_FALSE, /* invert order of the CCD/CIS colors? */
|
||||
|
||||
|
@ -132,11 +127,12 @@ static const Scanner_Model mustek_A2nu2_model = {
|
|||
/* button descriptions */
|
||||
{SANE_DESC_SCAN, SANE_DESC_COPY, SANE_DESC_FAX, SANE_DESC_EMAIL,
|
||||
SANE_I18N ("Panel button")}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
calc_parameters (Mustek_Scanner * s, TARGETIMAGE * pTarget)
|
||||
calc_parameters (Scanner_Handle * s, TARGETIMAGE * pTarget)
|
||||
{
|
||||
SANE_String val;
|
||||
float x1, y1, x2, y2;
|
||||
|
@ -240,7 +236,7 @@ calc_parameters (Mustek_Scanner * s, TARGETIMAGE * pTarget)
|
|||
}
|
||||
|
||||
static void
|
||||
update_button_status (Mustek_Scanner * s)
|
||||
update_button_status (Scanner_Handle * s)
|
||||
{
|
||||
SANE_Byte key;
|
||||
if (Scanner_GetKeyStatus (&s->state, &key) == SANE_STATUS_GOOD)
|
||||
|
@ -263,7 +259,7 @@ max_string_size (SANE_String_Const *strings)
|
|||
}
|
||||
|
||||
static SANE_Status
|
||||
init_options (Mustek_Scanner * s)
|
||||
init_options (Scanner_Handle * s)
|
||||
{
|
||||
SANE_Status status;
|
||||
SANE_Bool hasTA;
|
||||
|
@ -326,8 +322,8 @@ init_options (Mustek_Scanner * s)
|
|||
s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
|
||||
s->opt[OPT_RESOLUTION].size = sizeof (SANE_Word);
|
||||
s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
|
||||
s->opt[OPT_RESOLUTION].constraint.word_list = s->model.dpi_values;
|
||||
s->val[OPT_RESOLUTION].w = s->model.dpi_values[1];
|
||||
s->opt[OPT_RESOLUTION].constraint.word_list = s->model->dpi_values;
|
||||
s->val[OPT_RESOLUTION].w = s->model->dpi_values[1];
|
||||
|
||||
/* preview */
|
||||
s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
|
||||
|
@ -365,9 +361,6 @@ init_options (Mustek_Scanner * s)
|
|||
s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
|
||||
s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
|
||||
|
||||
x_range.max = s->model.x_size;
|
||||
y_range.max = s->model.y_size;
|
||||
|
||||
/* top-left x */
|
||||
s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
|
||||
s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
|
||||
|
@ -376,7 +369,7 @@ init_options (Mustek_Scanner * s)
|
|||
s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
|
||||
s->opt[OPT_TL_X].size = sizeof (SANE_Word);
|
||||
s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
s->opt[OPT_TL_X].constraint.range = &x_range;
|
||||
s->opt[OPT_TL_X].constraint.range = &s->model->x_range;
|
||||
s->val[OPT_TL_X].w = 0;
|
||||
|
||||
/* top-left y */
|
||||
|
@ -387,7 +380,7 @@ init_options (Mustek_Scanner * s)
|
|||
s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
|
||||
s->opt[OPT_TL_Y].size = sizeof (SANE_Word);
|
||||
s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
s->opt[OPT_TL_Y].constraint.range = &y_range;
|
||||
s->opt[OPT_TL_Y].constraint.range = &s->model->y_range;
|
||||
s->val[OPT_TL_Y].w = 0;
|
||||
|
||||
/* bottom-right x */
|
||||
|
@ -398,8 +391,8 @@ init_options (Mustek_Scanner * s)
|
|||
s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
|
||||
s->opt[OPT_BR_X].size = sizeof (SANE_Word);
|
||||
s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
s->opt[OPT_BR_X].constraint.range = &x_range;
|
||||
s->val[OPT_BR_X].w = x_range.max;
|
||||
s->opt[OPT_BR_X].constraint.range = &s->model->x_range;
|
||||
s->val[OPT_BR_X].w = s->model->x_range.max;
|
||||
|
||||
/* bottom-right y */
|
||||
s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
|
||||
|
@ -409,8 +402,8 @@ init_options (Mustek_Scanner * s)
|
|||
s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
|
||||
s->opt[OPT_BR_Y].size = sizeof (SANE_Word);
|
||||
s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
s->opt[OPT_BR_Y].constraint.range = &y_range;
|
||||
s->val[OPT_BR_Y].w = y_range.max;
|
||||
s->opt[OPT_BR_Y].constraint.range = &s->model->y_range;
|
||||
s->val[OPT_BR_Y].w = s->model->y_range.max;
|
||||
|
||||
/* "sensors" group */
|
||||
s->opt[OPT_SENSORS_GROUP].title = SANE_TITLE_SENSORS;
|
||||
|
@ -424,11 +417,11 @@ init_options (Mustek_Scanner * s)
|
|||
for (i = OPT_BUTTON_1; i <= OPT_BUTTON_5; i++)
|
||||
{
|
||||
SANE_Int idx = i - OPT_BUTTON_1;
|
||||
if (idx < s->model.buttons)
|
||||
if (idx < s->model->buttons)
|
||||
{
|
||||
s->opt[i].name = s->model.button_name[idx];
|
||||
s->opt[i].title = s->model.button_title[idx];
|
||||
s->opt[i].desc = s->model.button_desc[idx];
|
||||
s->opt[i].name = s->model->button_name[idx];
|
||||
s->opt[i].title = s->model->button_title[idx];
|
||||
s->opt[i].desc = s->model->button_desc[idx];
|
||||
s->opt[i].cap = SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT |
|
||||
SANE_CAP_ADVANCED;
|
||||
}
|
||||
|
@ -453,6 +446,98 @@ init_options (Mustek_Scanner * s)
|
|||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
attach_scanner (SANE_String_Const devname)
|
||||
{
|
||||
Scanner_Device * device;
|
||||
DBG (DBG_INFO, "attach_scanner: devname = %s\n", devname);
|
||||
|
||||
for (device = first_device; device; device = device->next)
|
||||
{
|
||||
if (strcmp (devname, device->name) == 0)
|
||||
{
|
||||
device->present = SANE_TRUE;
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
}
|
||||
|
||||
device = malloc (sizeof (*device));
|
||||
if (!device)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
device->name = strdup (devname);
|
||||
device->model = NULL;
|
||||
device->present = SANE_TRUE;
|
||||
device->next = first_device;
|
||||
first_device = device;
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
probe_devices(unsigned int * num_devices)
|
||||
{
|
||||
SANE_Status status;
|
||||
Scanner_Device * device, * prev_device;
|
||||
unsigned int i, n;
|
||||
|
||||
for (i = 0; i < (sizeof (models[0]) / sizeof(models)); i++)
|
||||
{
|
||||
status = Asic_FindDevices (models[i].vendor_id, models[i].product_id,
|
||||
attach_scanner);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
break;
|
||||
|
||||
/* Assign model data to all newly attached devices. */
|
||||
for (device = first_device; device; device = device->next)
|
||||
{
|
||||
if (device->model)
|
||||
break;
|
||||
device->model = &models[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove all devices that are no longer present. */
|
||||
n = 0;
|
||||
prev_device = NULL;
|
||||
device = first_device;
|
||||
while (device)
|
||||
{
|
||||
if (!device->present)
|
||||
{
|
||||
Scanner_Device * next = device->next;
|
||||
if (prev_device)
|
||||
prev_device->next = next;
|
||||
else
|
||||
first_device = next;
|
||||
free (device->name);
|
||||
free (device);
|
||||
device = next;
|
||||
}
|
||||
else
|
||||
{
|
||||
n++;
|
||||
device->present = SANE_FALSE;
|
||||
device = device->next;
|
||||
prev_device = device;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_devices)
|
||||
*num_devices = n;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
free_devlist (void)
|
||||
{
|
||||
SANE_Device ** devlist_ptr;
|
||||
for (devlist_ptr = devlist; *devlist_ptr; devlist_ptr++)
|
||||
free (*devlist_ptr);
|
||||
free (devlist);
|
||||
devlist = NULL;
|
||||
}
|
||||
|
||||
|
||||
/****************************** SANE API functions ****************************/
|
||||
|
||||
|
@ -460,6 +545,7 @@ SANE_Status
|
|||
sane_init (SANE_Int * version_code,
|
||||
SANE_Auth_Callback __sane_unused__ authorize)
|
||||
{
|
||||
SANE_Status status;
|
||||
DBG_INIT ();
|
||||
DBG_ENTER ();
|
||||
DBG (DBG_ERR, "SANE Mustek USB2 backend version %d.%d build %d from %s\n",
|
||||
|
@ -468,17 +554,30 @@ sane_init (SANE_Int * version_code,
|
|||
if (version_code)
|
||||
*version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, BUILD);
|
||||
|
||||
status = probe_devices (NULL);
|
||||
|
||||
DBG_LEAVE ();
|
||||
return SANE_STATUS_GOOD;
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
sane_exit (void)
|
||||
{
|
||||
Scanner_Device * device;
|
||||
DBG_ENTER ();
|
||||
|
||||
free (devlist);
|
||||
devlist = NULL;
|
||||
while (first_handle)
|
||||
sane_close (first_handle);
|
||||
|
||||
while (first_device)
|
||||
{
|
||||
device = first_device;
|
||||
free (first_device->name);
|
||||
first_device = first_device->next;
|
||||
free (device);
|
||||
}
|
||||
|
||||
free_devlist ();
|
||||
|
||||
DBG_LEAVE ();
|
||||
}
|
||||
|
@ -487,44 +586,65 @@ SANE_Status
|
|||
sane_get_devices (const SANE_Device *** device_list,
|
||||
SANE_Bool __sane_unused__ local_only)
|
||||
{
|
||||
SANE_Status status;
|
||||
unsigned int num_devices;
|
||||
Scanner_Device * device;
|
||||
SANE_Device ** devlist_ptr;
|
||||
DBG_ENTER ();
|
||||
|
||||
free (devlist);
|
||||
devlist = calloc (2, sizeof (devlist[0]));
|
||||
status = probe_devices (&num_devices);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
return status;
|
||||
|
||||
free_devlist ();
|
||||
devlist = malloc ((num_devices + 1) * sizeof (*devlist));
|
||||
if (!devlist)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
|
||||
/* HOLD: This is ugly (only one scanner!) and should go to sane_init */
|
||||
if (Scanner_IsPresent ())
|
||||
devlist_ptr = devlist;
|
||||
for (device = first_device; device; device = device->next)
|
||||
{
|
||||
SANE_Device *sane_device = malloc (sizeof (*sane_device));
|
||||
SANE_Device * sane_device = malloc (sizeof (*sane_device));
|
||||
if (!sane_device)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
sane_device->name = strdup (device_name);
|
||||
sane_device->vendor = "Mustek";
|
||||
sane_device->model = "BearPaw 2448 TA Pro";
|
||||
sane_device->type = "flatbed scanner";
|
||||
devlist[0] = sane_device;
|
||||
sane_device->name = device->name;
|
||||
sane_device->vendor = device->model->vendor_name;
|
||||
sane_device->model = device->model->model_name;
|
||||
sane_device->type = SANE_I18N ("flatbed scanner");
|
||||
*devlist_ptr++ = sane_device;
|
||||
}
|
||||
*device_list = devlist;
|
||||
*devlist_ptr = NULL;
|
||||
*device_list = (const SANE_Device **) devlist;
|
||||
|
||||
DBG_LEAVE ();
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_open (SANE_String_Const devicename, SANE_Handle * handle)
|
||||
sane_open (SANE_String_Const devname, SANE_Handle * handle)
|
||||
{
|
||||
SANE_Status status;
|
||||
Mustek_Scanner *s;
|
||||
Scanner_Handle * s;
|
||||
Scanner_Device * device;
|
||||
DBG_ENTER ();
|
||||
DBG (DBG_FUNC, "devicename=%s\n", devicename);
|
||||
DBG (DBG_FUNC, "devname=%s\n", devname);
|
||||
|
||||
/* Look up the device name in the list of detected devices. If the device name
|
||||
is an empty string, use the first device. */
|
||||
for (device = first_device; device; device = device->next)
|
||||
{
|
||||
if ((devname[0] == '\0') || (strcmp (devname, device->name) == 0))
|
||||
break;
|
||||
}
|
||||
if (!device)
|
||||
return SANE_STATUS_INVAL;
|
||||
|
||||
s = malloc (sizeof (*s));
|
||||
if (!s)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
memset (s, 0, sizeof (*s));
|
||||
s->model = mustek_A2nu2_model;
|
||||
s->model = device->model;
|
||||
s->state.chip.device_name = device->name;
|
||||
|
||||
Scanner_Init (&s->state);
|
||||
|
||||
|
@ -545,9 +665,24 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
|
|||
void
|
||||
sane_close (SANE_Handle handle)
|
||||
{
|
||||
Mustek_Scanner *s = handle;
|
||||
Scanner_Handle * s, * prev_handle = NULL;
|
||||
DBG_ENTER ();
|
||||
|
||||
for (s = first_handle; s; s = s->next)
|
||||
{
|
||||
if (s == (Scanner_Handle *) handle)
|
||||
break;
|
||||
prev_handle = s;
|
||||
}
|
||||
if (!s)
|
||||
{
|
||||
DBG (DBG_ERR, "attempting to close invalid handle %p\n", handle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->bIsScanning)
|
||||
sane_cancel (handle);
|
||||
|
||||
Scanner_PowerControl (&s->state, SANE_FALSE, SANE_FALSE);
|
||||
Scanner_BackHome (&s->state);
|
||||
|
||||
|
@ -557,7 +692,13 @@ sane_close (SANE_Handle handle)
|
|||
free (s->val[OPT_MODE].s);
|
||||
free (s->val[OPT_SOURCE].s);
|
||||
|
||||
free (handle);
|
||||
/* Remove from list of open handles. */
|
||||
if (prev_handle)
|
||||
prev_handle->next = s->next;
|
||||
else
|
||||
first_handle = s->next;
|
||||
|
||||
free (s);
|
||||
|
||||
DBG_LEAVE ();
|
||||
}
|
||||
|
@ -565,7 +706,7 @@ sane_close (SANE_Handle handle)
|
|||
const SANE_Option_Descriptor *
|
||||
sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
|
||||
{
|
||||
Mustek_Scanner *s = handle;
|
||||
Scanner_Handle * s = handle;
|
||||
|
||||
if ((option >= NUM_OPTIONS) || (option < 0))
|
||||
return NULL;
|
||||
|
@ -580,7 +721,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
SANE_Action action, void *val, SANE_Int * info)
|
||||
{
|
||||
SANE_Status status;
|
||||
Mustek_Scanner *s = handle;
|
||||
Scanner_Handle * s = handle;
|
||||
SANE_Word cap;
|
||||
SANE_Int myinfo = 0;
|
||||
TARGETIMAGE target;
|
||||
|
@ -591,15 +732,10 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
(action == SANE_ACTION_SET_AUTO) ? "set_auto" : "unknown",
|
||||
s->opt[option].name, option);
|
||||
|
||||
if (s->bIsScanning)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy\n");
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
if ((option >= NUM_OPTIONS) || (option < 0))
|
||||
{
|
||||
DBG (DBG_ERR, "option index out of range\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
cap = s->opt[option].cap;
|
||||
|
@ -705,24 +841,30 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
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 (mode_list[CM_RGB24]);
|
||||
x_range.max = s->model.x_size;
|
||||
y_range.max = s->model.y_size;
|
||||
s->opt[OPT_TL_X].constraint.range = &s->model->x_range;
|
||||
s->opt[OPT_TL_Y].constraint.range = &s->model->y_range;
|
||||
s->opt[OPT_BR_X].constraint.range = &s->model->x_range;
|
||||
s->opt[OPT_BR_Y].constraint.range = &s->model->y_range;
|
||||
}
|
||||
else if (strcmp (s->val[option].s, source_list[SS_NEGATIVE]) == 0)
|
||||
{
|
||||
s->opt[OPT_MODE].size = max_string_size (negative_mode_list);
|
||||
s->opt[OPT_MODE].constraint.string_list = negative_mode_list;
|
||||
s->val[OPT_MODE].s = strdup (mode_list[CM_RGB24]);
|
||||
x_range.max = s->model.x_size_ta;
|
||||
y_range.max = s->model.y_size_ta;
|
||||
s->opt[OPT_TL_X].constraint.range = &s->model->x_range_ta;
|
||||
s->opt[OPT_TL_Y].constraint.range = &s->model->y_range_ta;
|
||||
s->opt[OPT_BR_X].constraint.range = &s->model->x_range_ta;
|
||||
s->opt[OPT_BR_Y].constraint.range = &s->model->y_range_ta;
|
||||
}
|
||||
else if (strcmp (s->val[option].s, source_list[SS_POSITIVE]) == 0)
|
||||
{
|
||||
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 (mode_list[CM_RGB24]);
|
||||
x_range.max = s->model.x_size_ta;
|
||||
y_range.max = s->model.y_size_ta;
|
||||
s->opt[OPT_TL_X].constraint.range = &s->model->x_range_ta;
|
||||
s->opt[OPT_TL_Y].constraint.range = &s->model->y_range_ta;
|
||||
s->opt[OPT_BR_X].constraint.range = &s->model->x_range_ta;
|
||||
s->opt[OPT_BR_Y].constraint.range = &s->model->y_range_ta;
|
||||
}
|
||||
}
|
||||
myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||
|
@ -737,7 +879,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
else
|
||||
{
|
||||
DBG (DBG_ERR, "unknown action %d for option %d\n", action, option);
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
DBG_LEAVE ();
|
||||
|
@ -747,7 +889,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
SANE_Status
|
||||
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
|
||||
{
|
||||
Mustek_Scanner *s = handle;
|
||||
Scanner_Handle * s = handle;
|
||||
DBG_ENTER ();
|
||||
|
||||
DBG (DBG_INFO, "params.format = %d\n", s->params.format);
|
||||
|
@ -767,7 +909,7 @@ SANE_Status
|
|||
sane_start (SANE_Handle handle)
|
||||
{
|
||||
SANE_Status status;
|
||||
Mustek_Scanner *s = handle;
|
||||
Scanner_Handle * s = handle;
|
||||
TARGETIMAGE target;
|
||||
DBG_ENTER ();
|
||||
|
||||
|
@ -823,7 +965,7 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
|
|||
SANE_Int * len)
|
||||
{
|
||||
SANE_Status status;
|
||||
Mustek_Scanner *s = handle;
|
||||
Scanner_Handle * s = handle;
|
||||
unsigned short lines;
|
||||
SANE_Int bytes_read;
|
||||
DBG_ENTER ();
|
||||
|
@ -848,7 +990,7 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
|
|||
|
||||
s->bIsReading = SANE_TRUE;
|
||||
status = Scanner_GetRows (&s->state, s->scan_buf, &lines,
|
||||
s->model.isRGBInvert);
|
||||
s->model->isRGBInvert);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
s->bIsReading = SANE_FALSE;
|
||||
|
@ -896,7 +1038,7 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
|
|||
void
|
||||
sane_cancel (SANE_Handle handle)
|
||||
{
|
||||
Mustek_Scanner *s = handle;
|
||||
Scanner_Handle * s = handle;
|
||||
int i;
|
||||
DBG_ENTER ();
|
||||
|
||||
|
|
|
@ -99,13 +99,17 @@ typedef struct
|
|||
/** Device model name. */
|
||||
SANE_String_Const model_name;
|
||||
|
||||
/** USB vendor and product ID */
|
||||
unsigned short vendor_id;
|
||||
unsigned short product_id;
|
||||
|
||||
/** @name Scanner model parameters */
|
||||
/*@{ */
|
||||
SANE_Word dpi_values[MAX_RESOLUTIONS]; /* possible resolutions */
|
||||
SANE_Fixed x_size; /* size of scan area in mm */
|
||||
SANE_Fixed y_size;
|
||||
SANE_Fixed x_size_ta; /* size of scan area in TA mode in mm */
|
||||
SANE_Fixed y_size_ta;
|
||||
SANE_Range x_range; /* size of scan area in mm */
|
||||
SANE_Range y_range;
|
||||
SANE_Range x_range_ta; /* size of scan area in TA mode in mm */
|
||||
SANE_Range y_range_ta;
|
||||
|
||||
SANE_Bool isRGBInvert; /* order of the CCD/CIS colors:
|
||||
RGB if SANE_False, BGR otherwise */
|
||||
|
@ -118,21 +122,32 @@ typedef struct
|
|||
/*@} */
|
||||
} Scanner_Model;
|
||||
|
||||
typedef struct Mustek_Scanner
|
||||
typedef struct Scanner_Device
|
||||
{
|
||||
struct Mustek_Scanner *next;
|
||||
struct Scanner_Device * next;
|
||||
|
||||
const Scanner_Model * model;
|
||||
SANE_String name;
|
||||
SANE_Bool present;
|
||||
} Scanner_Device;
|
||||
|
||||
typedef struct Scanner_Handle
|
||||
{
|
||||
struct Scanner_Handle * next;
|
||||
|
||||
const Scanner_Model * model;
|
||||
SANE_Option_Descriptor opt[NUM_OPTIONS];
|
||||
Option_Value val[NUM_OPTIONS];
|
||||
SANE_Parameters params;
|
||||
Scanner_Model model;
|
||||
|
||||
Scanner_State state;
|
||||
|
||||
SANE_Bool bIsScanning;
|
||||
SANE_Bool bIsReading;
|
||||
SANE_Word read_rows; /* number of image lines left to read */
|
||||
SANE_Byte * scan_buf;
|
||||
SANE_Byte * scan_buf_start;
|
||||
SANE_Int scan_buf_len;
|
||||
} Mustek_Scanner;
|
||||
} Scanner_Handle;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -130,7 +130,7 @@ SwitchBank (ASIC * chip, unsigned short reg)
|
|||
if (bank > SELECT_REGISTER_BANK2)
|
||||
{
|
||||
DBG (DBG_ERR, "invalid register %d\n", reg);
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
if (chip->RegisterBankStatus != bank)
|
||||
|
@ -1783,18 +1783,21 @@ SetExtraSettings (ASIC * chip, unsigned short wXResolution,
|
|||
|
||||
/* ---------------------- high level ASIC functions ------------------------ */
|
||||
|
||||
/* HOLD: We don't want to have global vid/pids */
|
||||
static const unsigned short ProductID = 0x0409;
|
||||
static const unsigned short VendorID = 0x055f;
|
||||
|
||||
SANE_String_Const device_name;
|
||||
|
||||
static SANE_Status
|
||||
attach_one_scanner (SANE_String_Const devname)
|
||||
SANE_Status
|
||||
Asic_FindDevices (unsigned short wVendorID, unsigned short wProductID,
|
||||
SANE_Status (* attach) (SANE_String_Const devname))
|
||||
{
|
||||
DBG (DBG_INFO, "attach_one_scanner: devname = %s\n", devname);
|
||||
device_name = devname;
|
||||
return SANE_STATUS_GOOD;
|
||||
SANE_Status status;
|
||||
DBG_ASIC_ENTER ();
|
||||
|
||||
sanei_usb_init ();
|
||||
status = sanei_usb_find_devices (wVendorID, wProductID, attach);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
DBG (DBG_ERR, "sanei_usb_find_devices failed: %s\n",
|
||||
sane_strstatus (status));
|
||||
|
||||
DBG_ASIC_LEAVE ();
|
||||
return status;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
|
@ -1806,29 +1809,16 @@ Asic_Open (ASIC * chip)
|
|||
if (chip->firmwarestate > FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ASIC, "chip already open, fd=%d\n", chip->fd);
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
device_name = NULL;
|
||||
sanei_usb_init ();
|
||||
status = sanei_usb_find_devices (VendorID, ProductID, attach_one_scanner);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_ERR, "sanei_usb_find_devices failed: %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
if (!device_name)
|
||||
{
|
||||
DBG (DBG_ERR, "no scanner found\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
status = sanei_usb_open (device_name, &chip->fd);
|
||||
status = sanei_usb_open (chip->device_name, &chip->fd);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_ERR, "sanei_usb_open of %s failed: %s\n",
|
||||
device_name, sane_strstatus (status));
|
||||
chip->device_name, sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1869,7 +1859,7 @@ Asic_Open (ASIC * chip)
|
|||
return status;
|
||||
}
|
||||
|
||||
DBG (DBG_INFO, "device %s successfully opened\n", device_name);
|
||||
DBG (DBG_INFO, "device %s successfully opened\n", chip->device_name);
|
||||
DBG_ASIC_LEAVE ();
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
@ -1927,10 +1917,15 @@ Asic_TurnLamp (ASIC * chip, SANE_Bool isLampOn)
|
|||
{
|
||||
DBG_ASIC_ENTER ();
|
||||
|
||||
if (chip->firmwarestate != FS_OPENED)
|
||||
if (chip->firmwarestate < FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy or not open\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
DBG (DBG_ERR, "scanner is not open\n");
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
if (chip->firmwarestate > FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy\n");
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
SendData (chip, ES01_99_LAMP_PWM_FREQ_CONTROL, 1);
|
||||
|
@ -1948,10 +1943,15 @@ Asic_TurnTA (ASIC * chip, SANE_Bool isTAOn)
|
|||
{
|
||||
DBG_ASIC_ENTER ();
|
||||
|
||||
if (chip->firmwarestate != FS_OPENED)
|
||||
if (chip->firmwarestate < FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy or not open\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
DBG (DBG_ERR, "scanner is not open\n");
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
if (chip->firmwarestate > FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy\n");
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
SendData (chip, ES01_99_LAMP_PWM_FREQ_CONTROL, 1);
|
||||
|
@ -2065,10 +2065,15 @@ Asic_SetWindow (ASIC * chip, SCANSOURCE lsLightSource,
|
|||
lsLightSource, ScanType, bScanBits, wXResolution, wYResolution, wX, wY,
|
||||
wWidth, wHeight);
|
||||
|
||||
if (chip->firmwarestate != FS_OPENED)
|
||||
if (chip->firmwarestate < FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy or not open\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
DBG (DBG_ERR, "scanner is not open\n");
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
if (chip->firmwarestate > FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy\n");
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
status = PrepareScanChip (chip);
|
||||
|
@ -2126,7 +2131,6 @@ Asic_SetWindow (ASIC * chip, SCANSOURCE lsLightSource,
|
|||
MOTOR1_SERIAL_INTERFACE_G10_8_ENABLE);
|
||||
|
||||
SendData (chip, ES01_9A_AFEControl, AD9826_AFE);
|
||||
if (ScanType == SCAN_TYPE_NORMAL)
|
||||
SetAFEGainOffset (chip);
|
||||
SendData (chip, ES01_DB_PH_RESET_EDGE_TIMING_ADJUST, 0x00);
|
||||
SendData (chip, ES01_DC_CLEAR_EDGE_TO_PH_TG_EDGE_WIDTH, 0);
|
||||
|
@ -2189,19 +2193,19 @@ Asic_SetWindow (ASIC * chip, SCANSOURCE lsLightSource,
|
|||
SendData (chip, ES01_F8_WHITE_SHADING_DATA_FORMAT,
|
||||
SHADING_4_INT_12_DEC_ES01);
|
||||
|
||||
SetPackAddress (chip, wWidth, wX, XRatioAdderDouble,
|
||||
XRatioTypeDouble, 0, &ValidPixelNumber);
|
||||
SetExtraSettings (chip, wXResolution, wCCD_PixelNumber,
|
||||
(ScanType == SCAN_TYPE_NORMAL) ? SANE_FALSE : SANE_TRUE);
|
||||
SetPackAddress (chip, wWidth, wX, XRatioAdderDouble, XRatioTypeDouble, 0,
|
||||
&ValidPixelNumber);
|
||||
|
||||
if (ScanType == SCAN_TYPE_NORMAL)
|
||||
{
|
||||
SetExtraSettings (chip, wXResolution, wCCD_PixelNumber, SANE_FALSE);
|
||||
SetMotorStepTable (chip, &pMotorStepsTable, wY,
|
||||
wHeight * SENSOR_DPI / wYResolution * wMultiMotorStep,
|
||||
wYResolution);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetExtraSettings (chip, wXResolution, wCCD_PixelNumber, SANE_TRUE);
|
||||
SetMotorStepTableForCalibration (chip, &pMotorStepsTable,
|
||||
wHeight * SENSOR_DPI / wYResolution * wMultiMotorStep);
|
||||
}
|
||||
|
@ -2271,17 +2275,20 @@ Asic_SetWindow (ASIC * chip, SCANSOURCE lsLightSource,
|
|||
CalMotorTable.AccStepBeforeScan = pMotorStepsTable.wScanAccSteps;
|
||||
CalMotorTable.DecStepAfterScan = pMotorStepsTable.bScanDecSteps;
|
||||
CalMotorTable.pMotorTable = pMotorTable;
|
||||
if (ScanType == SCAN_TYPE_NORMAL)
|
||||
CalculateScanMotorTable (&CalMotorTable);
|
||||
else
|
||||
CalculateMoveMotorTable (&CalMotorTable);
|
||||
|
||||
CurrentPhase.MoveType = bMotorMoveType;
|
||||
CurrentPhase.MotorDriverIs3967 = 0;
|
||||
|
||||
if (ScanType == SCAN_TYPE_NORMAL)
|
||||
{
|
||||
CalculateScanMotorTable (&CalMotorTable);
|
||||
CurrentPhase.MotorCurrent = CalculateMotorCurrent (EndSpeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
CalculateMoveMotorTable (&CalMotorTable);
|
||||
CurrentPhase.MotorCurrent = 200;
|
||||
}
|
||||
SetMotorCurrentAndPhase (chip, &CurrentPhase);
|
||||
|
||||
DBG (DBG_ASIC, "MotorCurrent=%d,LinePixelReport=%d\n",
|
||||
|
@ -2335,10 +2342,15 @@ Asic_ScanStart (ASIC * chip)
|
|||
SANE_Status status;
|
||||
DBG_ASIC_ENTER ();
|
||||
|
||||
if (chip->firmwarestate != FS_OPENED)
|
||||
if (chip->firmwarestate < FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy or not open\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
DBG (DBG_ERR, "scanner is not open\n");
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
if (chip->firmwarestate > FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy\n");
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
status = GetChipStatus(chip, 0x1c | 0x20, NULL);
|
||||
|
@ -2367,7 +2379,7 @@ Asic_ScanStop (ASIC * chip)
|
|||
if (chip->firmwarestate < FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is not open\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
if (chip->firmwarestate < FS_SCANNING)
|
||||
return SANE_STATUS_GOOD;
|
||||
|
@ -2419,7 +2431,7 @@ Asic_ReadImage (ASIC * chip, SANE_Byte * pBuffer, unsigned short LinesCount)
|
|||
if (chip->firmwarestate != FS_SCANNING)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is not scanning\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
|
||||
dwXferBytes = (unsigned int) LinesCount * chip->dwBytesCountPerRow;
|
||||
|
@ -2442,10 +2454,15 @@ Asic_CheckFunctionKey (ASIC * chip, SANE_Byte * key)
|
|||
SANE_Byte bBuffer_1, bBuffer_2;
|
||||
DBG_ASIC_ENTER ();
|
||||
|
||||
if (chip->firmwarestate != FS_OPENED)
|
||||
if (chip->firmwarestate < FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy or not open\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
DBG (DBG_ERR, "scanner is not open\n");
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
if (chip->firmwarestate > FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy\n");
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
SendData (chip, ES01_97_GPIOControl0_7, 0x00);
|
||||
|
@ -2488,10 +2505,15 @@ Asic_IsTAConnected (ASIC * chip, SANE_Bool * hasTA)
|
|||
SANE_Byte bBuffer_1 = 0xff;
|
||||
DBG_ASIC_ENTER ();
|
||||
|
||||
if (chip->firmwarestate != FS_OPENED)
|
||||
if (chip->firmwarestate < FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy or not open\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
DBG (DBG_ERR, "scanner is not open\n");
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
if (chip->firmwarestate > FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy\n");
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
SendData (chip, ES01_97_GPIOControl0_7, 0x00);
|
||||
|
@ -2523,7 +2545,7 @@ Asic_ReadCalibrationData (ASIC * chip, SANE_Byte * pBuffer,
|
|||
if (chip->firmwarestate != FS_SCANNING)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is not scanning\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
|
||||
if (separateColors)
|
||||
|
@ -2585,10 +2607,15 @@ Asic_MotorMove (ASIC * chip, SANE_Bool isForward, unsigned int dwTotalSteps)
|
|||
SANE_Byte bActionType;
|
||||
DBG_ASIC_ENTER ();
|
||||
|
||||
if (chip->firmwarestate != FS_OPENED)
|
||||
if (chip->firmwarestate < FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy or not open\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
DBG (DBG_ERR, "scanner is not open\n");
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
if (chip->firmwarestate > FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy\n");
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
bActionType = isForward ? ACTION_TYPE_FORWARD : ACTION_TYPE_BACKWARD;
|
||||
|
@ -2606,10 +2633,15 @@ Asic_CarriageHome (ASIC * chip)
|
|||
SANE_Bool LampHome;
|
||||
DBG_ASIC_ENTER ();
|
||||
|
||||
if (chip->firmwarestate != FS_OPENED)
|
||||
if (chip->firmwarestate < FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy or not open\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
DBG (DBG_ERR, "scanner is not open\n");
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
if (chip->firmwarestate > FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy\n");
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
status = IsCarriageHome (chip, &LampHome);
|
||||
|
@ -2634,10 +2666,15 @@ Asic_SetShadingTable (ASIC * chip, unsigned short * pWhiteShading,
|
|||
double dbXRatioAdderDouble;
|
||||
DBG_ASIC_ENTER ();
|
||||
|
||||
if (chip->firmwarestate != FS_OPENED)
|
||||
if (chip->firmwarestate < FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy or not open\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
DBG (DBG_ERR, "scanner is not open\n");
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
if (chip->firmwarestate > FS_OPENED)
|
||||
{
|
||||
DBG (DBG_ERR, "scanner is busy\n");
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
if (wXResolution > (SENSOR_DPI / 2))
|
||||
|
|
|
@ -191,6 +191,7 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
SANE_String_Const device_name;
|
||||
int fd; /* file descriptor of scanner */
|
||||
|
||||
FIRMWARESTATE firmwarestate;
|
||||
|
@ -967,10 +968,12 @@ typedef struct
|
|||
#define ES01_2CF_VALID_PIXEL_PARAMETER_OF_SEGMENT16 0x2CF
|
||||
|
||||
|
||||
extern SANE_String_Const device_name;
|
||||
|
||||
void SetAFEGainOffset (ASIC * chip);
|
||||
|
||||
SANE_Status Asic_FindDevices (unsigned short wVendorID,
|
||||
unsigned short wProductID,
|
||||
SANE_Status (* attach)
|
||||
(SANE_String_Const devname));
|
||||
SANE_Status Asic_Open (ASIC * chip);
|
||||
SANE_Status Asic_Close (ASIC * chip);
|
||||
void Asic_Initialize (ASIC * chip);
|
||||
|
|
|
@ -957,7 +957,7 @@ Scanner_GetRows (Scanner_State * st, SANE_Byte * pBlock,
|
|||
if (!st->bOpened || !st->bPrepared)
|
||||
{
|
||||
DBG (DBG_FUNC, "invalid state\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
|
||||
switch (st->Target.cmColorMode)
|
||||
|
@ -1269,7 +1269,6 @@ AdjustAD (Scanner_State * st)
|
|||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
DBG (DBG_FUNC, "first AD offset adjustment loop\n");
|
||||
SetAFEGainOffset (&st->chip);
|
||||
status = Asic_ScanStart (&st->chip);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
goto out;
|
||||
|
@ -1320,6 +1319,8 @@ AdjustAD (Scanner_State * st)
|
|||
}
|
||||
}
|
||||
|
||||
SetAFEGainOffset (&st->chip);
|
||||
|
||||
if (!(wMinValue[0] > 15 || wMinValue[0] < 5 ||
|
||||
wMinValue[1] > 15 || wMinValue[1] < 5 ||
|
||||
wMinValue[2] > 15 || wMinValue[2] < 5))
|
||||
|
@ -1346,7 +1347,6 @@ AdjustAD (Scanner_State * st)
|
|||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
SetAFEGainOffset (&st->chip);
|
||||
status = Asic_ScanStart (&st->chip);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
goto out;
|
||||
|
@ -1403,6 +1403,8 @@ AdjustAD (Scanner_State * st)
|
|||
st->chip.AD.Direction[j]);
|
||||
}
|
||||
|
||||
SetAFEGainOffset (&st->chip);
|
||||
|
||||
if (!((wMaxValue[0] - wMinValue[0]) > MAX_LEVEL_RANGE ||
|
||||
(wMaxValue[0] - wMinValue[0]) < MIN_LEVEL_RANGE ||
|
||||
(wMaxValue[1] - wMinValue[1]) > MAX_LEVEL_RANGE ||
|
||||
|
@ -1415,7 +1417,6 @@ AdjustAD (Scanner_State * st)
|
|||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
DBG (DBG_FUNC, "second AD offset adjustment loop\n");
|
||||
SetAFEGainOffset (&st->chip);
|
||||
status = Asic_ScanStart (&st->chip);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
goto out;
|
||||
|
@ -1462,6 +1463,8 @@ AdjustAD (Scanner_State * st)
|
|||
st->chip.AD.Direction[j]);
|
||||
}
|
||||
|
||||
SetAFEGainOffset (&st->chip);
|
||||
|
||||
if (!(wMinValue[0] > 20 || wMinValue[0] < 10 ||
|
||||
wMinValue[1] > 20 || wMinValue[1] < 10 ||
|
||||
wMinValue[2] > 20 || wMinValue[2] < 10))
|
||||
|
@ -1520,7 +1523,6 @@ FindTopLeft (Scanner_State * st, unsigned short * pwStartX,
|
|||
if (status != SANE_STATUS_GOOD)
|
||||
goto out;
|
||||
|
||||
SetAFEGainOffset (&st->chip);
|
||||
status = Asic_ScanStart (&st->chip);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
goto out;
|
||||
|
@ -1705,7 +1707,6 @@ LineCalibration16Bits (Scanner_State * st)
|
|||
}
|
||||
|
||||
/* read white level data */
|
||||
SetAFEGainOffset (&st->chip);
|
||||
status = Asic_SetWindow (&st->chip, st->Target.ssScanSource,
|
||||
SCAN_TYPE_CALIBRATE_LIGHT, 48, st->Target.wXDpi, 600,
|
||||
st->Target.wX, 0, wCalWidth, wCalHeight);
|
||||
|
@ -1726,7 +1727,6 @@ LineCalibration16Bits (Scanner_State * st)
|
|||
goto out1;
|
||||
|
||||
/* read dark level data */
|
||||
SetAFEGainOffset (&st->chip);
|
||||
status = Asic_SetWindow (&st->chip, st->Target.ssScanSource,
|
||||
SCAN_TYPE_CALIBRATE_DARK, 48, st->Target.wXDpi, 600,
|
||||
st->Target.wX, 0, wCalWidth, wCalHeight);
|
||||
|
|
Ładowanie…
Reference in New Issue