- rewrite of gl646 internals to enable easy addition of new models

- rewrite of calibration process to make it more robust and accurate
	- untested full support for hp3670
	- untested support for 50, 100 and 300 uncalibrated scans for hp2400
	- use of id for device parts descriptions instead of using fixed
	  place in tables
 	- SCAN_MODE_* defines to clean up code
merge-requests/1/head
Stéphane Voltz 2009-02-27 12:37:16 +00:00
rodzic 29e407823d
commit ea76aef8a2
7 zmienionych plików z 1812 dodań i 3132 usunięć

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, 2008 Stéphane Voltz <stef.dev@free.fr>
Copyright (C) 2004-2009 Stéphane Voltz <stef.dev@free.fr>
Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
Copyright (C) 2006 Laurent Charpentier <laurent_pubs@yahoo.com>
Copyright (C) 2007 Luke <iceyfor@gmail.com>
@ -60,8 +60,6 @@
#include <unistd.h>
#include <math.h>
#include "_stdint.h"
#include "../include/sane/sane.h"
#include "../include/sane/sanei.h"
#include "../include/sane/saneopts.h"
@ -71,6 +69,7 @@
#include "../include/sane/sanei_backend.h"
#include "../include/sane/sanei_usb.h"
#include "../include/sane/sanei_config.h"
#include "_stdint.h"
#include "genesys.h"
#include "genesys_devices.c"
@ -394,25 +393,63 @@ sanei_genesys_set_buffer_address (Genesys_Device * dev, uint32_t addr)
void
sanei_genesys_init_structs (Genesys_Device * dev)
{
unsigned int i, sensor_ok = 0, gpo_ok = 0, motor_ok = 0;
/* initialize the sensor data stuff */
memcpy (&dev->sensor, &Sensor[dev->model->ccd_type],
sizeof (Genesys_Sensor));
for (i = 0; i < sizeof (Sensor) / sizeof (Genesys_Sensor); i++)
{
if (dev->model->ccd_type == Sensor[i].sensor_id)
{
memcpy (&dev->sensor, &Sensor[i], sizeof (Genesys_Sensor));
sensor_ok = 1;
}
}
/* initialize the GPO data stuff */
memcpy (&dev->gpo, &Gpo[dev->model->gpo_type], sizeof (Genesys_Gpo));
for (i = 0; i < sizeof (Gpo) / sizeof (Genesys_Gpo); i++)
{
if (dev->model->gpo_type == Gpo[i].gpo_id)
{
memcpy (&dev->gpo, &Gpo[i], sizeof (Genesys_Gpo));
gpo_ok = 1;
}
}
/* initialize the motor data stuff */
memcpy (&dev->motor, &Motor[dev->model->motor_type],
sizeof (Genesys_Motor));
for (i = 0; i < sizeof (Motor) / sizeof (Genesys_Motor); i++)
{
if (dev->model->motor_type == Motor[i].motor_id)
{
memcpy (&dev->motor, &Motor[i], sizeof (Genesys_Motor));
motor_ok = 1;
}
}
if (sensor_ok == 0 || motor_ok == 0 || gpo_ok == 0)
{
DBG (DBG_error0,
"sanei_genesys_init_structs: bad description(s) for ccd/gpo/motor=%d/%d/%d\n",
dev->model->ccd_type, dev->model->gpo_type, dev->model->motor_type);
}
}
void
sanei_genesys_init_fe (Genesys_Device * dev)
{
unsigned int i;
memcpy (&dev->frontend, &Wolfson[dev->model->dac_type],
sizeof (Genesys_Frontend));
for (i = 0; i < sizeof (Wolfson) / sizeof (Genesys_Frontend); i++)
{
if (dev->model->dac_type == Wolfson[i].fe_id)
{
memcpy (&dev->frontend, &Wolfson[i], sizeof (Genesys_Frontend));
return;
}
}
DBG (DBG_error0,
"sanei_genesys_init_fe: failed to find description for dac_type %d\n",
dev->model->dac_type);
DBG (DBG_info, "sanei_genesys_init_fe: dac_type %d set up\n", dev->model->dac_type);
}
/* Write data for analog frontend */
@ -1693,13 +1730,13 @@ sanei_genesys_calculate_zmode2 (SANE_Bool two_table,
/* huh? */
/* todo: double check */
/* Z1 and Z2 seem to be a time to synchronize with clock or a phase correction */
/* steps_sum is the result of create_slope_table */
/* last_speed is the last entry of the slope_table */
/* feedl is registers 3d,3e,3f */
/* fastfed is register 02 bit 3 */
/* scanfed is register 1f */
/* fwdstep is register 22 */
/* tgtime is register 6c bit 6+7 >> 6 */
/* steps_sum is the result of create_slope_table */
/* last_speed is the last entry of the slope_table */
/* feedl is registers 3d,3e,3f */
/* fastfed is register 02 bit 3 */
/* scanfed is register 1f */
/* fwdstep is register 22 */
/* tgtime is register 6c bit 6+7 >> 6 */
void
sanei_genesys_calculate_zmode (Genesys_Device * dev, uint32_t exposure_time,
@ -1833,7 +1870,7 @@ genesys_average_black (Genesys_Device * dev, int channel,
sum = 0;
if (dev->settings.scan_mode == 4) /* single pass color */
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
{
data += (channel * 2);
pixel_step = 3 * 2;
@ -1878,7 +1915,7 @@ genesys_coarse_calibration (Genesys_Device * dev)
black_pixels = dev->sensor.black_pixels
* dev->settings.xres / dev->sensor.optical_res;
if (dev->settings.scan_mode == 4) /* single pass color */
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
channels = 3;
else
channels = 1;
@ -2085,7 +2122,7 @@ genesys_coarse_calibration (Genesys_Device * dev)
sane_strstatus (status));
return status;
}
if (dev->settings.scan_mode == 4) /* single pass color */
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
{
for (j = 0; j < 3; j++)
{
@ -2112,7 +2149,7 @@ genesys_coarse_calibration (Genesys_Device * dev)
if (i == 3)
{
if (dev->settings.scan_mode == 4) /* single pass color */
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
{
/* todo: huh? */
dev->dark[0] =
@ -2205,7 +2242,7 @@ genesys_dark_shading_calibration (Genesys_Device * dev)
(genesys_pixels_per_line (dev->calib_reg)
* genesys_dpiset (dev->calib_reg)) / dev->sensor.optical_res;
if (dev->settings.scan_mode == 4) /* single pass color */
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
channels = 3;
else
channels = 1;
@ -2336,7 +2373,7 @@ genesys_dummy_dark_shading (Genesys_Device * dev)
(genesys_pixels_per_line (dev->calib_reg)
* genesys_dpiset (dev->calib_reg)) / dev->sensor.optical_res;
if (dev->settings.scan_mode == 4) /* single pass color */
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
channels = 3;
else
channels = 1;
@ -2431,7 +2468,7 @@ genesys_white_shading_calibration (Genesys_Device * dev)
(genesys_pixels_per_line (dev->calib_reg)
* genesys_dpiset (dev->calib_reg)) / dev->sensor.optical_res;
if (dev->settings.scan_mode == 4) /* single pass color */
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
channels = 3;
else
channels = 1;
@ -2447,7 +2484,7 @@ genesys_white_shading_calibration (Genesys_Device * dev)
return SANE_STATUS_NO_MEM;
}
size = channels * 2 * pixels_per_line * dev->model->shading_lines;
size = channels * 2 * pixels_per_line * (dev->model->shading_lines + 1);
calibration_data = malloc (size);
if (!calibration_data)
@ -2477,7 +2514,7 @@ genesys_white_shading_calibration (Genesys_Device * dev)
if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)
usleep (500 * 1000); /* wait 500ms to make sure lamp is bright again */
status = dev->model->cmd_set->begin_scan (dev, dev->calib_reg, SANE_FALSE);
status = dev->model->cmd_set->begin_scan (dev, dev->calib_reg, SANE_TRUE);
if (status != SANE_STATUS_GOOD)
{
free (calibration_data);
@ -2562,7 +2599,7 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev)
(genesys_pixels_per_line (dev->calib_reg)
* genesys_dpiset (dev->calib_reg)) / dev->sensor.optical_res;
if (dev->settings.scan_mode == 4) /* single pass color */
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
channels = 3;
else
channels = 1;
@ -2752,7 +2789,7 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
(genesys_pixels_per_line (dev->calib_reg)
* genesys_dpiset (dev->calib_reg)) / dev->sensor.optical_res;
if (dev->settings.scan_mode == 4) /* single pass color */
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
channels = 3;
else
channels = 1;
@ -3264,7 +3301,6 @@ genesys_flatbed_calibration (Genesys_Device * dev)
}
/* since all the registers are set up correctly, just use them */
status = dev->model->cmd_set->coarse_gain_calibration (dev, yres);
if (status != SANE_STATUS_GOOD)
{
@ -3292,7 +3328,7 @@ genesys_flatbed_calibration (Genesys_Device * dev)
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"genesys_flatbed_calibration: failed to do static calibration: %s\n",
"genesys_flatbed_calibration: failed to do coarse gain calibration: %s\n",
sane_strstatus (status));
return status;
}
@ -3491,7 +3527,6 @@ genesys_wait_not_moving (Genesys_Device * dev, int mseconds)
static SANE_Status
genesys_warmup_lamp (Genesys_Device * dev)
{
Genesys_Register_Set local_reg[GENESYS_MAX_REGS];
uint8_t *first_line, *second_line;
int seconds = 0;
int pixel;
@ -3499,12 +3534,12 @@ genesys_warmup_lamp (Genesys_Device * dev)
double first_average = 0;
double second_average = 0;
int difference = 255;
int empty;
int empty, lines = 3;
SANE_Status status = SANE_STATUS_IO_ERROR;
DBG (DBG_proc, "genesys_warmup_lamp: start\n");
dev->model->cmd_set->init_regs_for_warmup (dev, local_reg, &channels,
dev->model->cmd_set->init_regs_for_warmup (dev, dev->reg, &channels,
&total_size);
first_line = malloc (total_size);
if (!first_line)
@ -3518,19 +3553,13 @@ genesys_warmup_lamp (Genesys_Device * dev)
{
DBG (DBG_info, "genesys_warmup_lamp: one more loop\n");
RIE (dev->model->cmd_set->begin_scan (dev, local_reg, SANE_TRUE));
RIE (dev->model->cmd_set->begin_scan (dev, dev->reg, SANE_FALSE));
do
{
sanei_genesys_test_buffer_empty (dev, &empty);
}
while (empty);
/* STEF: workaround 'hang' problem with gl646 : data reading hangs
depending on the amount of data read by the last scan done
before scanner reset. So we allow for one read failure, which
fixes the communication with scanner . Put usb timeout to a friendly
value first, so that 'recovery' doesn't take too long */
sanei_usb_set_timeout (2 * 1000);
status =
sanei_genesys_read_data_from_scanner (dev, first_line, total_size);
if (status != SANE_STATUS_GOOD)
@ -3538,14 +3567,13 @@ genesys_warmup_lamp (Genesys_Device * dev)
RIE (sanei_genesys_read_data_from_scanner
(dev, first_line, total_size));
}
/* back to normal time out */
sanei_usb_set_timeout (30 * 1000);
RIE (dev->model->cmd_set->end_scan (dev, local_reg, SANE_FALSE));
RIE (dev->model->cmd_set->end_scan (dev, dev->reg, SANE_TRUE));
sleep (1); /* sleep 1 s */
seconds++;
RIE (dev->model->cmd_set->begin_scan (dev, local_reg, SANE_FALSE));
RIE (dev->model->cmd_set->begin_scan (dev, dev->reg, SANE_FALSE));
do
{
sanei_genesys_test_buffer_empty (dev, &empty);
@ -3553,14 +3581,12 @@ genesys_warmup_lamp (Genesys_Device * dev)
while (empty);
RIE (sanei_genesys_read_data_from_scanner
(dev, second_line, total_size));
RIE (dev->model->cmd_set->end_scan (dev, local_reg, SANE_FALSE));
sleep (1); /* sleep 1 s */
seconds++;
RIE (dev->model->cmd_set->end_scan (dev, dev->reg, SANE_TRUE));
/* compute difference between the two scans */
for (pixel = 0; pixel < total_size; pixel++)
{
if (dev->model->cmd_set->get_bitset_bit (local_reg))
if (dev->model->cmd_set->get_bitset_bit (dev->reg))
{
first_average +=
(first_line[pixel] + first_line[pixel + 1] * 256);
@ -3574,10 +3600,10 @@ genesys_warmup_lamp (Genesys_Device * dev)
second_average += second_line[pixel];
}
}
if (dev->model->cmd_set->get_bitset_bit (local_reg))
if (dev->model->cmd_set->get_bitset_bit (dev->reg))
{
DBG (DBG_info,
"genesys_warmup_lamp: average = %.2f %%, diff = %.3f %%\n",
"genesys_warmup_lamp: average = %.2f, diff = %.3f\n",
100 * ((second_average) / (256 * 256)),
100 * (difference / second_average));
first_average /= pixel;
@ -3595,9 +3621,13 @@ genesys_warmup_lamp (Genesys_Device * dev)
if (DBG_LEVEL >= DBG_data)
{
sanei_genesys_write_pnm_file ("warmup1.pnm", first_line, 8,
channels, total_size / 2, 2);
channels,
total_size / (lines * channels),
lines);
sanei_genesys_write_pnm_file ("warmup2.pnm", second_line, 8,
channels, total_size / 2, 2);
channels,
total_size / (lines * channels),
lines);
}
DBG (DBG_info,
"genesys_warmup_lamp: average 1 = %.2f %%, average 2 = %.2f %%\n",
@ -3606,6 +3636,10 @@ genesys_warmup_lamp (Genesys_Device * dev)
&& second_average > 120)
break;
}
/* sleep another second before next loop */
sleep (1);
seconds++;
}
while (seconds < WARMUP_TIME);
@ -3914,6 +3948,7 @@ sanei_genesys_buffer_consume (Genesys_Buffer * buf, size_t size)
#include "genesys_conv.c"
/*#undef SANE_DEBUG_LOG_RAW_DATA*/
#define SANE_DEBUG_LOG_RAW_DATA 1
#ifdef SANE_DEBUG_LOG_RAW_DATA
static FILE *rawfile = NULL;
@ -4620,19 +4655,19 @@ calc_parameters (Genesys_Scanner * s)
s->params.bytes_per_line *= 3;
if (strcmp (mode, SANE_VALUE_SCAN_MODE_COLOR) == 0)
s->dev->settings.scan_mode = 4;
s->dev->settings.scan_mode = SCAN_MODE_COLOR;
else if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0)
s->dev->settings.scan_mode = 2;
s->dev->settings.scan_mode = SCAN_MODE_GRAY;
else if (strcmp (mode, SANE_TITLE_HALFTONE) == 0)
s->dev->settings.scan_mode = 1;
s->dev->settings.scan_mode = SCAN_MODE_HALFTONE;
else /* Lineart */
s->dev->settings.scan_mode = 0;
s->dev->settings.scan_mode = SCAN_MODE_LINEART;
/* todo: change and check */
if (strcmp (source, "Flatbed") == 0)
s->dev->settings.scan_method = 0;
s->dev->settings.scan_method = SCAN_METHOD_FLATBED;
else /* transparency */
s->dev->settings.scan_method = 2;
s->dev->settings.scan_method = SCAN_METHOD_TRANSPARENCY;
s->dev->settings.lines = s->params.lines;
s->dev->settings.pixels = s->params.pixels_per_line;
@ -4987,7 +5022,8 @@ init_options (Genesys_Scanner * s)
s->opt[OPT_FILE_SW].type = SANE_TYPE_BOOL;
s->opt[OPT_FILE_SW].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_FILE_SW)
s->opt[OPT_FILE_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
s->opt[OPT_FILE_SW].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else
s->opt[OPT_FILE_SW].cap = SANE_CAP_INACTIVE;
s->val[OPT_FILE_SW].b = 0;
@ -4998,8 +5034,9 @@ init_options (Genesys_Scanner * s)
s->opt[OPT_EMAIL_SW].desc = SANE_DESC_EMAIL;
s->opt[OPT_EMAIL_SW].type = SANE_TYPE_BOOL;
s->opt[OPT_EMAIL_SW].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_EMAIL_SW)
s->opt[OPT_EMAIL_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
if (model->buttons & GENESYS_HAS_EMAIL_SW)
s->opt[OPT_EMAIL_SW].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else
s->opt[OPT_EMAIL_SW].cap = SANE_CAP_INACTIVE;
s->val[OPT_EMAIL_SW].b = 0;
@ -5010,8 +5047,9 @@ init_options (Genesys_Scanner * s)
s->opt[OPT_COPY_SW].desc = SANE_DESC_COPY;
s->opt[OPT_COPY_SW].type = SANE_TYPE_BOOL;
s->opt[OPT_COPY_SW].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_COPY_SW)
s->opt[OPT_COPY_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
if (model->buttons & GENESYS_HAS_COPY_SW)
s->opt[OPT_COPY_SW].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else
s->opt[OPT_COPY_SW].cap = SANE_CAP_INACTIVE;
s->val[OPT_COPY_SW].b = 0;
@ -5022,8 +5060,9 @@ init_options (Genesys_Scanner * s)
s->opt[OPT_PAGE_LOADED_SW].desc = SANE_DESC_PAGE_LOADED;
s->opt[OPT_PAGE_LOADED_SW].type = SANE_TYPE_BOOL;
s->opt[OPT_PAGE_LOADED_SW].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_PAGE_LOADED_SW)
s->opt[OPT_PAGE_LOADED_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
if (model->buttons & GENESYS_HAS_PAGE_LOADED_SW)
s->opt[OPT_PAGE_LOADED_SW].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else
s->opt[OPT_PAGE_LOADED_SW].cap = SANE_CAP_INACTIVE;
s->val[OPT_PAGE_LOADED_SW].b = 0;
@ -5035,8 +5074,9 @@ init_options (Genesys_Scanner * s)
s->opt[OPT_OCR_SW].desc = "OCR button";
s->opt[OPT_OCR_SW].type = SANE_TYPE_BOOL;
s->opt[OPT_OCR_SW].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_OCR_SW)
s->opt[OPT_OCR_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
if (model->buttons & GENESYS_HAS_OCR_SW)
s->opt[OPT_OCR_SW].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else
s->opt[OPT_OCR_SW].cap = SANE_CAP_INACTIVE;
s->val[OPT_OCR_SW].b = 0;
@ -5048,13 +5088,28 @@ init_options (Genesys_Scanner * s)
s->opt[OPT_POWER_SW].desc = "Power button";
s->opt[OPT_POWER_SW].type = SANE_TYPE_BOOL;
s->opt[OPT_POWER_SW].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_POWER_SW)
s->opt[OPT_POWER_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
if (model->buttons & GENESYS_HAS_POWER_SW)
s->opt[OPT_POWER_SW].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else
s->opt[OPT_POWER_SW].cap = SANE_CAP_INACTIVE;
s->val[OPT_POWER_SW].b = 0;
s->last_val[OPT_POWER_SW].b = 0;
/* calibrate button */
s->opt[OPT_CALIBRATE].name = "calibrate";
s->opt[OPT_CALIBRATE].title = "Calibrate button";
s->opt[OPT_CALIBRATE].desc = "Start calibration using special sheet";
s->opt[OPT_CALIBRATE].type = SANE_TYPE_BOOL;
s->opt[OPT_CALIBRATE].unit = SANE_UNIT_NONE;
if (model->buttons & GENESYS_HAS_CALIBRATE)
s->opt[OPT_CALIBRATE].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT
| SANE_CAP_ADVANCED | SANE_CAP_AUTOMATIC;
else
s->opt[OPT_CALIBRATE].cap = SANE_CAP_INACTIVE;
s->val[OPT_CALIBRATE].b = 0;
s->last_val[OPT_CALIBRATE].b = 0;
RIE (calc_parameters (s));
DBG (DBG_proc, "init_options: exit\n");
@ -5589,7 +5644,7 @@ get_option_value (Genesys_Scanner * s, int option, void *val)
case OPT_PAGE_LOADED_SW:
case OPT_OCR_SW:
case OPT_POWER_SW:
RIE(s->dev->model->cmd_set->update_hardware_sensors(s));
RIE (s->dev->model->cmd_set->update_hardware_sensors (s));
*(SANE_Bool *) val = s->val[option].b;
s->last_val[option].b = *(SANE_Bool *) val;
break;

Wyświetl plik

@ -9,10 +9,10 @@
#usb 0x0638 0x0a10
# Hewlett Packard ScanJet 2400c
#usb 0x03f0 0x0a01
usb 0x03f0 0x0a01
# Hewlett Packard ScanJet 3670c
#usb 0x03f0 0x1405
usb 0x03f0 0x1405
# Plustek OpticPro ST24
#usb 0x07b3 0x0601

Wyświetl plik

@ -103,13 +103,14 @@ enum Genesys_Option
OPT_PAGE_LOADED_SW,
OPT_OCR_SW,
OPT_POWER_SW,
OPT_CALIBRATE,
/* must come last: */
NUM_OPTIONS
};
/** Scanner object.
/** Scanner object. Should have better be called Session than Scanner
*/
typedef struct Genesys_Scanner
{

Wyświetl plik

@ -3,7 +3,7 @@
Copyright (C) 2003 Oliver Rauch
Copyright (C) 2003-2005 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-2009 Stéphane Voltz <stef.dev@free.fr>
Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
Copyright (C) 2007 Luke <iceyfor@gmail.com>
@ -53,69 +53,77 @@
/** Setup table for various scanners using a Wolfson DAC
*/
static Genesys_Frontend Wolfson[] = {
{{0x00, 0x03, 0x05, 0x11}
{ DAC_WOLFSON_UMAX, {0x00, 0x03, 0x05, 0x11}
, {0x00, 0x00, 0x00}
, {0x80, 0x80, 0x80}
, {0x02, 0x02, 0x02}
, {0x00, 0x00, 0x00}
}
, /* 0: UMAX */
{{0x00, 0x03, 0x05, 0x03}
{DAC_WOLFSON_ST12, {0x00, 0x03, 0x05, 0x03}
, {0x00, 0x00, 0x00}
, {0xc8, 0xc8, 0xc8}
, {0x04, 0x04, 0x04}
, {0x00, 0x00, 0x00}
}
, /* 1: ST12 */
{{0x00, 0x03, 0x05, 0x21}
{DAC_WOLFSON_ST24,{0x00, 0x03, 0x05, 0x21}
, {0x00, 0x00, 0x00}
, {0xc8, 0xc8, 0xc8}
, {0x06, 0x06, 0x06}
, {0x00, 0x00, 0x00}
}
, /* 2: ST24 */
{{0x00, 0x03, 0x05, 0x12}
{DAC_WOLFSON_5345,{0x00, 0x03, 0x05, 0x12}
, {0x00, 0x00, 0x00}
, {0xc8, 0xc8, 0xc8}
, {0xb8, 0xb8, 0xb8}
, {0x04, 0x04, 0x04}
, {0x00, 0x00, 0x00}
}
, /* 3: MD6228/MD6471 */
{{0x00, 0x03, 0x05, 0x02}
{DAC_WOLFSON_HP2400,{0x00, 0x03, 0x05, 0x02}
, {0x00, 0x00, 0x00}
, {0xc0, 0xc0, 0xc0}
, {0x07, 0x07, 0x07}
, {0x00, 0x00, 0x00}
}
, /* 4: HP2400c */
{{0x00, 0x03, 0x04, 0x02}
{DAC_WOLFSON_HP2300,{0x00, 0x03, 0x04, 0x02}
, {0x00, 0x00, 0x00}
, {0xb0, 0xb0, 0xb0}
, {0xbe, 0xbe, 0xbe}
, {0x04, 0x04, 0x04}
, {0x00, 0x00, 0x00}
}
, /* 5: HP2300c */
{{0x00, 0x3d, 0x08, 0x00}
{DAC_CANONLIDE35,{0x00, 0x3d, 0x08, 0x00}
, {0x00, 0x00, 0x00}
, {0xe1, 0xe1, 0xe1}
, {0x93, 0x93, 0x93}
, {0x00, 0x19, 0x06}
}
, /* 6: CANONLIDE35 */
{{0x58, 0x00, 0x00, 0x00} /* TODO create an AnalogDevice struct */
{DAC_AD_XP200,{0x58, 0x00, 0x00, 0x00} /* TODO create an AnalogDevice struct */
, {0x00, 0x00, 0x00}
, {0x06, 0x00, 0x00}
, {0x0c, 0x00, 0x00}
, {0x00, 0x00, 0x00}
}
, /* 7: XP200 */
{{0x00, 0x35, 0x20, 0x14}
,
{DAC_WOLFSON_XP300,{0x00, 0x35, 0x20, 0x14} /* 7: XP300 */
, {0x00, 0x00, 0x00}
, {0xe1, 0xe1, 0xe1}
, {0x93, 0x93, 0x93}
, {0x07, 0x00, 0x00}
}
, /* 8: XP300 */
{DAC_WOLFSON_HP3670, /* uses one write for offset or gain like hp2300/2400 */
{0x00, 0x03, 0x04, 0x02}
, {0x00, 0x00, 0x00}
, {0xb4, 0xb4, 0xb4}
, {0x08, 0x08, 0x08}
, {0x00, 0x00, 0x00}
}
,
};
@ -126,7 +134,7 @@ static Genesys_Frontend Wolfson[] = {
*/
static Genesys_Sensor Sensor[] = {
/* 0: UMAX */
{1200, 48, 64, 0, 10800, 210, 230,
{CCD_UMAX,1200, 48, 64, 0, 10800, 210, 230,
{0x01, 0x03, 0x05, 0x07}
,
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x05, 0x31, 0x2a, 0x00, 0x00,
@ -139,7 +147,7 @@ static Genesys_Sensor Sensor[] = {
NULL, NULL, NULL}
,
/* 1: Plustek OpticPro S12/ST12 */
{600, 48, 85, 152, 5416, 210, 230,
{CCD_ST12,600, 48, 85, 152, 5416, 210, 230,
{0x02, 0x00, 0x06, 0x04}
,
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x08, 0x20, 0x2a, 0x00, 0x00,
@ -152,7 +160,7 @@ static Genesys_Sensor Sensor[] = {
NULL, NULL, NULL}
,
/* 2: Plustek OpticPro S24/ST24 */
{1200, 48, 64, 0, 10800, 210, 230,
{CCD_ST24,1200, 48, 64, 0, 10800, 210, 230,
{0x0e, 0x0c, 0x00, 0x0c}
,
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x08, 0x31, 0x2a, 0x00, 0x00,
@ -165,10 +173,10 @@ static Genesys_Sensor Sensor[] = {
NULL, NULL, NULL}
,
/* 3: MD6471 */
{1200,
{CCD_5345,1200,
48,
16, 0, 10872,
210, 200,
210, 240,
{0x0d, 0x0f, 0x11, 0x13}
,
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x30, 0x2a, 0x00, 0x00,
@ -181,7 +189,7 @@ static Genesys_Sensor Sensor[] = {
NULL, NULL, NULL}
,
/* 4: HP2400c */
{1200,
{CCD_HP2400,1200,
48,
15, 0, 10872, 210, 200,
{0x14, 0x15, 0x00, 0x00} /* registers 0x08-0x0b */
@ -196,9 +204,9 @@ static Genesys_Sensor Sensor[] = {
NULL, NULL, NULL}
,
/* 5: HP2300c */
{600,
{CCD_HP2300,600,
48,
20, 0, 5454, 210, 200,
20, 0, 5454, 210, 240,
{0x16, 0x00, 0x01, 0x03}
,
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x0a, 0x20, 0x2a, 0x6a, 0x8a,
@ -211,7 +219,7 @@ static Genesys_Sensor Sensor[] = {
NULL, NULL, NULL}
,
/* CANOLIDE35 */
{1200,
{CCD_CANONLIDE35, 1200,
/*TODO: find a good reason for keeping all three following variables*/
87, /*(black) */
87, /* (dummy) */
@ -234,7 +242,7 @@ static Genesys_Sensor Sensor[] = {
NULL, NULL, NULL}
,
/* 7: Strobe XP200 */
{600,
{CIS_XP200, 600,
48,
38, 0, 5454, 210, 200,
{0x16, 0x00, 0x01, 0x03}
@ -246,10 +254,20 @@ static Genesys_Sensor Sensor[] = {
0x16}
,
2.1, 2.1, 2.1,
NULL, NULL, NULL},
/* HP3670 */
{CCD_HP3670,1200,
48,
16, 0, 10872,
210, 200,
{0x00, 0x0a, 0x0b, 0x0d} ,
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x07, 0x20, 0x2a, 0x00, 0x00, 0xc0, 0x43} ,
{0x0f, 0x13, 0x17, 0x03, 0x07, 0x0b, 0x83, 0x00, 0x15, 0x05, 0x0a, 0x0f, 0x00},
2.38, 2.35, 2.34,
NULL, NULL, NULL}
,
/* 8: Strobe XP300 */
{600,
{CCD_XP300, 600,
/*TODO: find a good reason for keeping all three following variables*/
87, /*(black) */
87, /* (dummy) */
@ -279,7 +297,7 @@ static Genesys_Sensor Sensor[] = {
*/
static Genesys_Gpo Gpo[] = {
/* UMAX */
{
{GPO_UMAX,
{0x11, 0x00}
,
{0x51, 0x20}
@ -287,7 +305,7 @@ static Genesys_Gpo Gpo[] = {
}
,
/* Plustek OpticPro S12/ST12 */
{
{GPO_ST12,
{0x11, 0x00}
,
{0x51, 0x20}
@ -295,7 +313,7 @@ static Genesys_Gpo Gpo[] = {
}
,
/* Plustek OpticPro S24/ST24 */
{
{GPO_ST24,
{0x00, 0x00}
,
{0x51, 0x20}
@ -303,7 +321,7 @@ static Genesys_Gpo Gpo[] = {
}
,
/* MD5345/MD6471 */
{
{GPO_5345,
{0x30, 0x18}
, /* bits 11-12 are for bipolar V-ref input voltage */
{0xa0, 0x18}
@ -311,7 +329,7 @@ static Genesys_Gpo Gpo[] = {
}
,
/* HP2400C */
{
{GPO_HP2400,
{0x30, 0x00}
,
{0x31, 0x00}
@ -319,7 +337,7 @@ static Genesys_Gpo Gpo[] = {
}
,
/* HP2300C */
{
{GPO_HP2300,
{0x00, 0x00}
,
{0x00, 0x00}
@ -327,7 +345,7 @@ static Genesys_Gpo Gpo[] = {
}
,
/* CANONLIDE35 */
{
{GPO_CANONLIDE35,
{0x81, 0x80}
,
{0xef, 0x80}
@ -335,24 +353,29 @@ static Genesys_Gpo Gpo[] = {
}
,
/* 7: XP200 */
{
{GPO_XP200,
{0x30, 0x00}
,
{0xb0, 0x00}
,
}
},
/* HP2400C */
{GPO_HP3670,
{0x20, 0x00}
,
{0x70, 0x00}
}
,
/* 8: XP300 */
{
{GPO_XP300,
{0x09, 0xc6},
{0xbb, 0x00},
}
}
};
#define MOTOR_ST24 2
static Genesys_Motor Motor[] = {
/* 0: UMAX */
{
/* UMAX */
{MOTOR_UMAX,
1200, /* motor base steps */
2400, /* maximum motor resolution */
1, /* maximum step mode */
@ -370,7 +393,7 @@ static Genesys_Motor Motor[] = {
1.0,
},},},
},
{ /* 1: MD5345/6228/6471 */
{MOTOR_5345, /* MD5345/6228/6471 */
1200,
2400,
1,
@ -388,7 +411,7 @@ static Genesys_Motor Motor[] = {
0.5,
},},},
},
{ /* 2: ST24 */
{MOTOR_ST24, /* ST24 */
2400,
2400,
1,
@ -406,7 +429,7 @@ static Genesys_Motor Motor[] = {
0.3,
},},},
},
{ /* 3: HP 2400c */
{MOTOR_HP3670, /* HP 3670 */
1200,
2400,
1,
@ -424,7 +447,25 @@ static Genesys_Motor Motor[] = {
0.5,
},},},
},
{ /* 4: HP 2300c */
{MOTOR_HP2400, /* HP 2400c */
1200,
2400,
1,
1,
{{{
11000, /* start speed */
3000, /* max speed */
128, /* min steps */
0.25,
},
{
11000,
3000,
128,
0.5,
},},},
},
{MOTOR_HP2300, /* HP 2300c */
600,
1200,
1,
@ -442,7 +483,7 @@ static Genesys_Motor Motor[] = {
0.5,
},},},
},
{ /* 5: Canon LiDE 35 */
{MOTOR_CANONLIDE35, /* Canon LiDE 35 */
1200,
2400,
1,
@ -460,7 +501,7 @@ static Genesys_Motor Motor[] = {
0.8,
},},},
},
{ /* 6: Strobe XP200 */
{MOTOR_XP200, /* Strobe XP200 */
600,
600,
1,
@ -478,7 +519,7 @@ static Genesys_Motor Motor[] = {
0.5,
},},},
},
{ /* 7: Visioneer Strobe XP300 */
{MOTOR_XP300, /* 7: Visioneer Strobe XP300 */
300,
600,
1,
@ -669,8 +710,8 @@ static Genesys_Model hp2300c_model = {
{16, 8, 0}, /* possible depths in gray mode */
{16, 8, 0}, /* possible depths in color mode */
SANE_FIX (-2.0), /* Start of scan area in mm (x_offset) */
SANE_FIX (0.0), /* Start of scan area in mm (y_offset) */
SANE_FIX (2.0), /* Start of scan area in mm (x_offset) */
SANE_FIX (7.5), /* Start of scan area in mm (y_offset) */
SANE_FIX (215.9), /* Size of scan area in mm (x) */
SANE_FIX (295.0), /* Size of scan area in mm (y) */
@ -699,12 +740,12 @@ static Genesys_Model hp2300c_model = {
DAC_WOLFSON_HP2300,
GPO_HP2300,
MOTOR_HP2300,
GENESYS_FLAG_REPARK
| GENESYS_FLAG_14BIT_GAMMA
GENESYS_FLAG_14BIT_GAMMA
/* | GENESYS_FLAG_NO_CALIBRATION */
| GENESYS_FLAG_SEARCH_START
| GENESYS_FLAG_MUST_WAIT
| GENESYS_FLAG_DARK_CALIBRATION
| GENESYS_FLAG_OFFSET_CALIBRATION
| GENESYS_FLAG_HALF_CCD_MODE
| GENESYS_FLAG_CUSTOM_GAMMA,
GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW,
9,
@ -755,9 +796,7 @@ Genesys_Model hp2400c_model = {
GPO_HP2400,
MOTOR_HP2400,
GENESYS_FLAG_UNTESTED /* not fully working yet */
| GENESYS_FLAG_REPARK
| GENESYS_FLAG_14BIT_GAMMA
| GENESYS_FLAG_MUST_WAIT
| GENESYS_FLAG_DARK_CALIBRATION
| GENESYS_FLAG_OFFSET_CALIBRATION
| GENESYS_FLAG_CUSTOM_GAMMA
@ -811,8 +850,7 @@ Genesys_Model visioneer_xp200_model = {
DAC_AD_XP200, /* Analog Device frontend */
GPO_XP200,
MOTOR_XP200,
GENESYS_FLAG_UNTESTED /* not fully working yet */
| GENESYS_FLAG_14BIT_GAMMA
GENESYS_FLAG_14BIT_GAMMA
| GENESYS_FLAG_CUSTOM_GAMMA
| GENESYS_FLAG_SKIP_WARMUP
| GENESYS_FLAG_NO_CALIBRATION,
@ -828,8 +866,8 @@ static Genesys_Model hp3670c_model = {
GENESYS_GL646,
NULL,
{1200, 600, 300, 150, 75, 0}, /* possible x-resolutions */
{2400, 1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */
{1200, 600, 300, 150, 100, 50, 0}, /* possible x-resolutions */
{1200, 600, 300, 150, 100, 50, 0}, /* possible y-resolutions */
{16, 8, 0}, /* possible depths in gray mode */
{16, 8, 0}, /* possible depths in color mode */
@ -859,12 +897,15 @@ static Genesys_Model hp3670c_model = {
SANE_FALSE, /* Is this a CIS scanner? */
SANE_FALSE, /* Is this a sheetfed scanner? */
CCD_UMAX,
DAC_WOLFSON_UMAX,
GPO_UMAX,
MOTOR_UMAX,
GENESYS_FLAG_UNTESTED, /* Which flags are needed for this scanner? */
/* untested, values set by mike p. according to vendor's datasheet. */
CCD_HP3670,
DAC_WOLFSON_HP3670,
GPO_HP3670,
MOTOR_HP3670,
GENESYS_FLAG_14BIT_GAMMA
| GENESYS_FLAG_SEARCH_START
| GENESYS_FLAG_DARK_CALIBRATION
| GENESYS_FLAG_OFFSET_CALIBRATION
| GENESYS_FLAG_CUSTOM_GAMMA,
GENESYS_HAS_NO_BUTTONS, /* no buttons supported */
20,
200
@ -964,7 +1005,6 @@ static Genesys_Model plustek_st24_model = {
| GENESYS_FLAG_14BIT_GAMMA
| GENESYS_FLAG_LAZY_INIT
| GENESYS_FLAG_USE_PARK
| GENESYS_FLAG_SKIP_WARMUP
| GENESYS_FLAG_SEARCH_START | GENESYS_FLAG_OFFSET_CALIBRATION,
GENESYS_HAS_NO_BUTTONS, /* no buttons supported */
20,
@ -978,13 +1018,13 @@ static Genesys_Model medion_md5345_model = {
GENESYS_GL646,
NULL,
{1200, 600, 300, 200, 150, 100, 75, 50, 0}, /* possible x-resolutions */
{2400, 1200, 600, 500, 400, 300, 250, 200, 150, 100, 50, 0}, /* possible y-resolutions */
{1200, 600, 400, 300, 200, 150, 100, 75, 50, 0}, /* possible x-resolutions */
{2400, 1200, 600, 500, 400, 300, 200, 150, 100, 75, 50, 0}, /* possible y-resolutions */
{16, 8, 0}, /* possible depths in gray mode */
{16, 8, 0}, /* possible depths in color mode */
SANE_FIX (1.00), /* Start of scan area in mm (x) */
SANE_FIX (5.00), /* 2.79 < Start of scan area in mm (y) */
SANE_FIX ( 0.00), /* Start of scan area in mm (x) */
SANE_FIX ( 0.00), /* 2.79 < Start of scan area in mm (y) */
SANE_FIX (215.9), /* Size of scan area in mm (x) */
SANE_FIX (296.4), /* Size of scan area in mm (y) */
@ -1016,11 +1056,11 @@ static Genesys_Model medion_md5345_model = {
GENESYS_FLAG_14BIT_GAMMA
| GENESYS_FLAG_LAZY_INIT
| GENESYS_FLAG_USE_PARK
| GENESYS_FLAG_SKIP_WARMUP
| GENESYS_FLAG_SEARCH_START
| GENESYS_FLAG_DARK_CALIBRATION
| GENESYS_FLAG_STAGGERED_LINE
| GENESYS_FLAG_DARK_CALIBRATION
| GENESYS_FLAG_OFFSET_CALIBRATION
| GENESYS_FLAG_HALF_CCD_MODE
| GENESYS_FLAG_CUSTOM_GAMMA,
GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_POWER_SW | GENESYS_HAS_OCR_SW | GENESYS_HAS_SCAN_SW,
32,

Plik diff jest za duży Load Diff

Wyświetl plik

@ -58,7 +58,6 @@
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "_stdint.h"
#include "../include/sane/sane.h"
@ -127,7 +126,7 @@
#define REG07_DMASEL 0x02
#define REG07_DMARDWR 0x01
#define REG08_DECFLAG 0x40
#define REG08_DECFLAG 0x40
#define REG08_GMMFFR 0x20
#define REG08_GMMFFG 0x10
#define REG08_GMMFFB 0x08

Wyświetl plik

@ -3,8 +3,8 @@
Copyright (C) 2003 Oliver Rauch
Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de>
Copyright (C) 2004, 2005 Gerhard Jaeger <gerhard@gjaeger.de>
Copyright (C) 2004, 2005 Stephane Voltz <stef.dev@free.fr>
Copyright (C) 2005 - 2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
Copyright (C) 2004-2009 Stéphane Voltz <stef.dev@free.fr>
Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
Copyright (C) 2006 Laurent Charpentier <laurent_pubs@yahoo.com>
Parts of the structs have been taken from the gt68xx backend by
Sergey Vlasov <vsu@altlinux.ru> et al.
@ -107,6 +107,7 @@
#define GENESYS_HAS_PAGE_LOADED_SW (1 << 4) /* scanner has paper in detection */
#define GENESYS_HAS_OCR_SW (1 << 5) /* scanner has OCR button */
#define GENESYS_HAS_POWER_SW (1 << 6) /* scanner has power button */
#define GENESYS_HAS_CALIBRATE (1 << 7) /* scanner has 'calibrate' software button to start calibration */
/* USB control message values */
#define REQUEST_TYPE_IN (USB_TYPE_VENDOR | USB_DIR_IN)
@ -166,6 +167,7 @@ typedef struct
typedef struct
{
uint8_t fe_id; /**> id of the frontend description */
uint8_t reg[4];
uint8_t sign[3];
uint8_t offset[3];
@ -175,6 +177,7 @@ typedef struct
typedef struct
{
uint8_t sensor_id; /**> id of the sensor description */
int optical_res;
int black_pixels;
int dummy_pixel; /* value of dummy register. */
@ -195,6 +198,7 @@ typedef struct
typedef struct
{
uint8_t gpo_id; /**> id of the gpo description */
uint8_t value[2];
uint8_t enable[2];
} Genesys_Gpo;
@ -213,6 +217,7 @@ typedef struct
typedef struct
{
uint8_t motor_id; /**> id of the motor description */
SANE_Int base_ydpi; /* motor base steps. Unit: 1/" */
SANE_Int optical_ydpi; /* maximum resolution in y-direction. Unit: 1/" */
SANE_Int max_step_type; /* maximum step type. 0-2 */
@ -247,6 +252,7 @@ Genesys_Color_Order;
#define DAC_CANONLIDE35 6
#define DAC_AD_XP200 7 /* Analog Device frontend */
#define DAC_WOLFSON_XP300 8
#define DAC_WOLFSON_HP3670 9
#define CCD_UMAX 0
#define CCD_ST12 1 /* SONY ILX548: 5340 Pixel ??? */
@ -257,6 +263,7 @@ Genesys_Color_Order;
#define CCD_CANONLIDE35 6
#define CIS_XP200 7 /* CIS sensor for Strobe XP200 */
#define CCD_XP300 8
#define CCD_HP3670 9
#define GPO_UMAX 0
#define GPO_ST12 1
@ -267,6 +274,7 @@ Genesys_Color_Order;
#define GPO_CANONLIDE35 6
#define GPO_XP200 7
#define GPO_XP300 8
#define GPO_HP3670 9
#define MOTOR_UMAX 0
#define MOTOR_5345 1
@ -276,6 +284,8 @@ Genesys_Color_Order;
#define MOTOR_CANONLIDE35 5
#define MOTOR_XP200 6
#define MOTOR_XP300 7
#define MOTOR_HP3670 9
/* Forward typedefs */
typedef struct Genesys_Device Genesys_Device;
@ -439,6 +449,14 @@ typedef struct Genesys_Model
SANE_Int search_lines; /* how many lines are used to search start position */
} Genesys_Model;
#define SCAN_METHOD_FLATBED 0 /**> normal scan method */
#define SCAN_METHOD_TRANSPARENCY 2 /**> scan using transparency adaptor */
#define SCAN_METHOD_NEGATIVE 0x88 /**> scan using negative adaptor */
#define SCAN_MODE_LINEART 0 /**> lineart scan mode */
#define SCAN_MODE_HALFTONE 1 /**> halftone scan mode */
#define SCAN_MODE_GRAY 2 /**> gray scan mode */
#define SCAN_MODE_COLOR 4 /**> color scan mode */
typedef struct
{