Updated ScanExpress 2400 USB values. Added implementation of gt6801 lamp

control for CCD scanners. Added flag for SE 2400 USB, added some quirks in
gt68xx_gt6801.c. Fixed gt68xx_gt6801 -> lamp control. Adjusted Plustek 1248U
geometry and afe values. CCD gross calibration changed: start with the default
value from module struct. Is faster now for most cases. Only 2.5 mm of
calibration for GT-6801 scanners. Added "afe" option for gt68xx.conf for
selecting default afe values. Removed AFE and exposure SANE options. Added
documentation for afe option in gt68xx.conf. New version: 1.0-35.
RELEASE_1_0_11_BRANCH
Henning Geinitz 2002-12-30 13:05:24 +00:00
rodzic 503f6e61ae
commit b97a0721b5
11 zmienionych plików z 272 dodań i 381 usunięć

Wyświetl plik

@ -12,6 +12,18 @@
* backend/Makefile.in: Backends shouldn't be linked to sanei_config2 if
they aren't also linked to sanei_scsi. sanei_config2 needs
sanei_scsi.
* backend/gt68xx.c backend/gt68xx_devices.c backend/gt68xx_gt6801.c
backend/gt68xx_gt6816.c backend/gt68xx_high.c backend/gt68xx_high.h
backend/gt68xx_low.h doc/sane-gt68xx.man doc/descriptions/gt68xx.desc
doc/gt68xx/gt68xx.CHANGES: Updated ScanExpress 2400 USB values. Added
implementation of gt6801 lamp control for CCD scanners. Added flag for
SE 2400 USB, added some quirks in gt68xx_gt6801.c. Fixed gt68xx_gt6801
-> lamp control. Adjusted Plustek 1248U geometry and afe values. CCD
gross calibration changed: start with the default value from module
struct. Is faster now for most cases. Only 2.5 mm of calibration for
GT-6801 scanners. Added "afe" option for gt68xx.conf for selecting
default afe values. Removed AFE and exposure SANE options. Added
documentation for afe option in gt68xx.conf. New version: 1.0-35.
2002-12-28 Karl Heinz Kremer <khk@khk.net>

Wyświetl plik

@ -48,11 +48,12 @@
#include "../include/sane/config.h"
#define BUILD 32
#define BUILD 35
#define MAX_DEBUG
#define WARMUP_TIME 30
#define CALIBRATION_HEIGHT 2.5
#if 1
#if 0
#ifdef HAVE_SYS_SHM_H
#define USE_FORK
#define SHM_BUFFERS 10
@ -187,6 +188,79 @@ max_string_size (const SANE_String_Const strings[])
return max_size;
}
static SANE_Status
get_afe_values (SANE_String_Const cp, GT68xx_AFE_Parameters *afe)
{
SANE_Char *word, *end;
int i;
for (i = 0; i < 6; i++)
{
cp = sanei_config_get_string (cp, &word);
if (word && *word)
{
long int long_value;
errno = 0;
long_value = strtol (word, &end, 0);
if (end == word)
{
DBG (5, "get_afe_values: can't parse %d. parameter `%s'\n",
i + 1, word);
free (word);
word = 0;
return SANE_STATUS_INVAL;
}
else if (errno)
{
DBG (5, "get_afe_values: can't parse %d. parameter `%s' "
"(%s)\n", i + 1, word, strerror (errno));
free (word);
word = 0;
return SANE_STATUS_INVAL;
}
else if (long_value < 0)
{
DBG (5, "get_afe_values: %d. parameter < 0 (%d)\n", i + 1,
(int) long_value);
free (word);
word = 0;
return SANE_STATUS_INVAL;
}
else if (long_value > 0x3f)
{
DBG (5, "get_afe_values: %d. parameter > 0x3f (%d)\n", i + 1,
(int) long_value);
free (word);
word = 0;
return SANE_STATUS_INVAL;
}
else
{
DBG (5, "get_afe_values: %d. parameter set to 0x%02x\n", i + 1,
(int) long_value);
switch (i)
{
case 0: afe->r_offset = (SANE_Byte) long_value; break;
case 1: afe->r_pga = (SANE_Byte) long_value; break;
case 2: afe->g_offset = (SANE_Byte) long_value; break;
case 3: afe->g_pga = (SANE_Byte) long_value; break;
case 4: afe->b_offset = (SANE_Byte) long_value; break;
case 5: afe->b_pga = (SANE_Byte) long_value; break;
}
free (word);
word = 0;
}
}
else
{
DBG (5, "get_afe_values: option `afe' needs 6 parameters\n");
return SANE_STATUS_INVAL;
}
}
return SANE_STATUS_GOOD;
}
static SANE_Status
setup_scan_request (GT68xx_Scanner * s, GT68xx_Scan_Request * scan_request)
{
@ -506,111 +580,6 @@ init_options (GT68xx_Scanner * s)
s->opt[OPT_QUALITY_CAL].constraint_type = SANE_CONSTRAINT_NONE;
s->val[OPT_QUALITY_CAL].w = SANE_TRUE;
/* exposure time red */
s->opt[OPT_SCAN_EXPOS_TIME_R].name = SANE_NAME_SCAN_EXPOS_TIME_R;
s->opt[OPT_SCAN_EXPOS_TIME_R].title = SANE_TITLE_SCAN_EXPOS_TIME_R;
s->opt[OPT_SCAN_EXPOS_TIME_R].desc = SANE_DESC_SCAN_EXPOS_TIME_R;
s->opt[OPT_SCAN_EXPOS_TIME_R].type = SANE_TYPE_INT;
s->opt[OPT_SCAN_EXPOS_TIME_R].unit = SANE_UNIT_NONE;
s->opt[OPT_SCAN_EXPOS_TIME_R].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[OPT_SCAN_EXPOS_TIME_R].constraint.range = &exposure_range;
s->val[OPT_SCAN_EXPOS_TIME_R].w = s->dev->exposure->r_time;
DISABLE (OPT_SCAN_EXPOS_TIME_R);
/* exposure time green */
s->opt[OPT_SCAN_EXPOS_TIME_G].name = SANE_NAME_SCAN_EXPOS_TIME_G;
s->opt[OPT_SCAN_EXPOS_TIME_G].title = SANE_TITLE_SCAN_EXPOS_TIME_G;
s->opt[OPT_SCAN_EXPOS_TIME_G].desc = SANE_DESC_SCAN_EXPOS_TIME_G;
s->opt[OPT_SCAN_EXPOS_TIME_G].type = SANE_TYPE_INT;
s->opt[OPT_SCAN_EXPOS_TIME_G].unit = SANE_UNIT_NONE;
s->opt[OPT_SCAN_EXPOS_TIME_G].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[OPT_SCAN_EXPOS_TIME_G].constraint.range = &exposure_range;
s->val[OPT_SCAN_EXPOS_TIME_G].w = s->dev->exposure->g_time;
DISABLE (OPT_SCAN_EXPOS_TIME_G);
/* exposure time blue */
s->opt[OPT_SCAN_EXPOS_TIME_B].name = SANE_NAME_SCAN_EXPOS_TIME_B;
s->opt[OPT_SCAN_EXPOS_TIME_B].title = SANE_TITLE_SCAN_EXPOS_TIME_B;
s->opt[OPT_SCAN_EXPOS_TIME_B].desc = SANE_DESC_SCAN_EXPOS_TIME_B;
s->opt[OPT_SCAN_EXPOS_TIME_B].type = SANE_TYPE_INT;
s->opt[OPT_SCAN_EXPOS_TIME_B].unit = SANE_UNIT_NONE;
s->opt[OPT_SCAN_EXPOS_TIME_B].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[OPT_SCAN_EXPOS_TIME_B].constraint.range = &exposure_range;
s->val[OPT_SCAN_EXPOS_TIME_B].w = s->dev->exposure->b_time;
DISABLE (OPT_SCAN_EXPOS_TIME_B);
/* offset red */
s->opt[OPT_OFFSET_R].name = "offset-r";
s->opt[OPT_OFFSET_R].title = SANE_I18N ("Offset red");
s->opt[OPT_OFFSET_R].desc =
SANE_I18N ("Offset (brightness) of the red channel.");
s->opt[OPT_OFFSET_R].type = SANE_TYPE_INT;
s->opt[OPT_OFFSET_R].unit = SANE_UNIT_NONE;
s->opt[OPT_OFFSET_R].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[OPT_OFFSET_R].constraint.range = &offset_range;
s->val[OPT_OFFSET_R].w = s->dev->afe->r_offset;
DISABLE (OPT_OFFSET_R);
/* offset green */
s->opt[OPT_OFFSET_G].name = "offset-g";
s->opt[OPT_OFFSET_G].title = SANE_I18N ("Offset green");
s->opt[OPT_OFFSET_G].desc =
SANE_I18N ("Offset (brightness) of the green (and gray) channel.");
s->opt[OPT_OFFSET_G].type = SANE_TYPE_INT;
s->opt[OPT_OFFSET_G].unit = SANE_UNIT_NONE;
s->opt[OPT_OFFSET_G].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[OPT_OFFSET_G].constraint.range = &offset_range;
s->val[OPT_OFFSET_G].w = s->dev->afe->g_offset;
DISABLE (OPT_OFFSET_G);
/* offset blue */
s->opt[OPT_OFFSET_B].name = "offset-b";
s->opt[OPT_OFFSET_B].title = SANE_I18N ("Offset blue");
s->opt[OPT_OFFSET_B].desc =
SANE_I18N ("Offset (brightness) of the blue channel.");
s->opt[OPT_OFFSET_B].type = SANE_TYPE_INT;
s->opt[OPT_OFFSET_B].unit = SANE_UNIT_NONE;
s->opt[OPT_OFFSET_B].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[OPT_OFFSET_B].constraint.range = &offset_range;
s->val[OPT_OFFSET_B].w = s->dev->afe->b_offset;
DISABLE (OPT_OFFSET_B);
/* gain red */
s->opt[OPT_GAIN_R].name = "gain-r";
s->opt[OPT_GAIN_R].title = SANE_I18N ("Gain red");
s->opt[OPT_GAIN_R].desc =
SANE_I18N ("Gain (contrast) of the red channel.");
s->opt[OPT_GAIN_R].type = SANE_TYPE_INT;
s->opt[OPT_GAIN_R].unit = SANE_UNIT_NONE;
s->opt[OPT_GAIN_R].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[OPT_GAIN_R].constraint.range = &offset_range;
s->val[OPT_GAIN_R].w = s->dev->afe->r_pga;
DISABLE (OPT_GAIN_R);
/* gain green */
s->opt[OPT_GAIN_G].name = "gain-g";
s->opt[OPT_GAIN_G].title = SANE_I18N ("Gain green");
s->opt[OPT_GAIN_G].desc =
SANE_I18N ("Gain (contrast) of the green (and gray) channel.");
s->opt[OPT_GAIN_G].type = SANE_TYPE_INT;
s->opt[OPT_GAIN_G].unit = SANE_UNIT_NONE;
s->opt[OPT_GAIN_G].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[OPT_GAIN_G].constraint.range = &offset_range;
s->val[OPT_GAIN_G].w = s->dev->afe->g_pga;
DISABLE (OPT_GAIN_G);
/* gain blue */
s->opt[OPT_GAIN_B].name = "gain-b";
s->opt[OPT_GAIN_B].title = SANE_I18N ("Gain blue");
s->opt[OPT_GAIN_B].desc =
SANE_I18N ("Gain (contrast) of the blue channel.");
s->opt[OPT_GAIN_B].type = SANE_TYPE_INT;
s->opt[OPT_GAIN_B].unit = SANE_UNIT_NONE;
s->opt[OPT_GAIN_B].constraint_type = SANE_CONSTRAINT_RANGE;
s->opt[OPT_GAIN_B].constraint.range = &offset_range;
s->val[OPT_GAIN_B].w = s->dev->afe->b_pga;
DISABLE (OPT_GAIN_B);
/* "Enhancement" group: */
s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement");
s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
@ -630,7 +599,6 @@ init_options (GT68xx_Scanner * s)
s->opt[OPT_GAMMA_VALUE].cap |= SANE_CAP_EMULATED;
s->val[OPT_GAMMA_VALUE].w = s->dev->gamma_value;
/* threshold */
s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
@ -987,7 +955,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
}
else
{
DBG (5, "sane_init: option `firmware' needs a parameter\n");
DBG (3, "sane_init: option `firmware' needs a parameter\n");
}
}
else if (strcmp (word, "vendor") == 0)
@ -1011,7 +979,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
}
else
{
DBG (5, "sane_init: option `vendor' needs a parameter\n");
DBG (3, "sane_init: option `vendor' needs a parameter\n");
}
}
else if (strcmp (word, "model") == 0)
@ -1034,7 +1002,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
}
else
{
DBG (5, "sane_init: option `model' needs a parameter\n");
DBG (3, "sane_init: option `model' needs a parameter\n");
}
}
else if (strcmp (word, "override") == 0)
@ -1072,9 +1040,33 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
}
else
{
DBG (5, "sane_init: option `override' needs a parameter\n");
DBG (3, "sane_init: option `override' needs a parameter\n");
}
}
else if (strcmp (word, "afe") == 0)
{
GT68xx_AFE_Parameters afe;
SANE_Status status;
free (word);
word = 0;
status = get_afe_values (cp, &afe);
if (status == SANE_STATUS_GOOD)
{
int i;
for (i = 0; i < new_dev_len; i++)
{
new_dev[i]->model->afe_params = afe;
DBG (5, "sane_init: device %s: setting new afe values\n",
new_dev[i]->model->name);
}
if (i == 0)
DBG (5, "sane_init: can't set afe values, set device first\n");
}
else
DBG (3, "sane_init: can't set afe values\n");
}
else
{
new_dev_len = 0;
@ -1355,15 +1347,6 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
case OPT_AUTO_WARMUP:
case OPT_GAMMA_VALUE:
case OPT_THRESHOLD:
case OPT_SCAN_EXPOS_TIME_R:
case OPT_SCAN_EXPOS_TIME_G:
case OPT_SCAN_EXPOS_TIME_B:
case OPT_OFFSET_R:
case OPT_OFFSET_G:
case OPT_OFFSET_B:
case OPT_GAIN_R:
case OPT_GAIN_G:
case OPT_GAIN_B:
case OPT_TL_X:
case OPT_TL_Y:
case OPT_BR_X:
@ -1419,15 +1402,6 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
case OPT_QUALITY_CAL:
case OPT_GAMMA_VALUE:
case OPT_THRESHOLD:
case OPT_SCAN_EXPOS_TIME_R:
case OPT_SCAN_EXPOS_TIME_G:
case OPT_SCAN_EXPOS_TIME_B:
case OPT_OFFSET_R:
case OPT_OFFSET_G:
case OPT_OFFSET_B:
case OPT_GAIN_R:
case OPT_GAIN_G:
case OPT_GAIN_B:
s->val[option].w = *(SANE_Word *) val;
break;
case OPT_SOURCE:
@ -1484,29 +1458,11 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
if (s->val[option].w == SANE_TRUE)
{
ENABLE (OPT_COARSE_CAL_ONCE);
DISABLE (OPT_SCAN_EXPOS_TIME_R);
DISABLE (OPT_SCAN_EXPOS_TIME_G);
DISABLE (OPT_SCAN_EXPOS_TIME_B);
DISABLE (OPT_OFFSET_R);
DISABLE (OPT_OFFSET_G);
DISABLE (OPT_OFFSET_B);
DISABLE (OPT_GAIN_R);
DISABLE (OPT_GAIN_G);
DISABLE (OPT_GAIN_B);
s->first_scan = SANE_TRUE;
}
else
{
DISABLE (OPT_COARSE_CAL_ONCE);
ENABLE (OPT_SCAN_EXPOS_TIME_R);
ENABLE (OPT_SCAN_EXPOS_TIME_G);
ENABLE (OPT_SCAN_EXPOS_TIME_B);
ENABLE (OPT_OFFSET_R);
ENABLE (OPT_OFFSET_G);
ENABLE (OPT_OFFSET_B);
ENABLE (OPT_GAIN_R);
ENABLE (OPT_GAIN_G);
ENABLE (OPT_GAIN_B);
}
myinfo |= SANE_INFO_RELOAD_OPTIONS;
break;
@ -1579,20 +1535,6 @@ sane_start (SANE_Handle handle)
else
s->auto_afe = s->val[OPT_COARSE_CAL].w;
if (s->val[OPT_COARSE_CAL].w == SANE_FALSE)
{
s->dev->exposure->r_time = s->val[OPT_SCAN_EXPOS_TIME_R].w;
s->dev->exposure->g_time = s->val[OPT_SCAN_EXPOS_TIME_G].w;
s->dev->exposure->b_time = s->val[OPT_SCAN_EXPOS_TIME_B].w;
s->dev->afe->r_offset = s->val[OPT_OFFSET_R].w;
s->dev->afe->g_offset = s->val[OPT_OFFSET_G].w;
s->dev->afe->b_offset = s->val[OPT_OFFSET_B].w;
s->dev->afe->r_pga = s->val[OPT_GAIN_R].w;
s->dev->afe->g_pga = s->val[OPT_GAIN_G].w;
s->dev->afe->b_pga = s->val[OPT_GAIN_B].w;
}
s->dev->gamma_value = s->val[OPT_GAMMA_VALUE].w;
gamma_size = s->params.depth == 16 ? 65536 : 256;
s->gamma_table = malloc (sizeof (SANE_Int) * gamma_size);
@ -1634,8 +1576,8 @@ sane_start (SANE_Handle handle)
s->line = 0;
s->byte_count = s->reader->params.pixel_xs;
s->total_bytes = 0;
s->scanning = SANE_TRUE;
s->first_scan = SANE_FALSE;
s->scanning = SANE_TRUE;
DBG (5, "sane_start: exit\n");
return SANE_STATUS_GOOD;
}

Wyświetl plik

@ -607,44 +607,44 @@ static GT68xx_Model mustek_scanexpress2400usb_model = {
&mustek_gt6801_command_set, /* Command set used by this scanner */
600, /* maximum optical sensor resolution */
1200, /* maximum optical sensor resolution */
1200, /* maximum motor resolution */
1200, /* base x-res used to calculate geometry */
600, /* base y-res used to calculate geometry */
1200, /* base y-res used to calculate geometry */
1200, /* if ydpi is equal or higher, use linemode */
SANE_TRUE, /* Use base_ydpi for all resolutions */
{600, 300, 150, 100, 50, 0}, /* possible x-resolutions */
{1200, 600, 300, 150, 100, 50, 0}, /* possible y-resolutions */
{8, 0}, /* possible depths in gray mode */
{8, 0}, /* possible depths in color mode */
{12, 8, 0}, /* possible depths in gray mode */
{12, 8, 0}, /* possible depths in color mode */
SANE_FIX (15.0), /* Start of scan area in mm (x) */
SANE_FIX (25.0), /* Start of scan area in mm (y) */
SANE_FIX (220.0), /* Size of scan area in mm (x) */
SANE_FIX (299.0), /* Size of scan area in mm (y) */
SANE_FIX (5.0), /* Start of scan area in mm (x) */
SANE_FIX (12.0), /* Start of scan area in mm (y) */
SANE_FIX (224.0), /* Size of scan area in mm (x) */
SANE_FIX (300.0), /* Size of scan area in mm (y) */
SANE_FIX (0.0), /* Start of white strip in mm (y) */
SANE_FIX (7.0), /* Start of black mark in mm (x) */
SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */
SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */
SANE_FIX (100.9), /* Size of scan area in TA mode in mm (x) */
SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */
SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */
SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */
0, 16, 32, /* RGB CCD Line-distance correction in pixel */
24, 12, 0, /* RGB CCD Line-distance correction in pixel */
0, /* CCD distcance for CCD with 6 lines) */
COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */
{0x16, 0x06, 0x16, 0x06, 0x16, 0x06}, /* Default offset/gain */
{0x12, 0x06, 0x0e, 0x03, 0x19, 0x25}, /* Default offset/gain */
{0x157, 0x157, 0x157}, /* Default exposure parameters */
SANE_FIX (2.0), /* Default gamma value */
SANE_FALSE, /* Is this a CIS scanner? */
GT68XX_FLAG_UNTESTED /* Which flags are needed for this scanner? */
/* only partly tested */
GT68XX_FLAG_UNTESTED | GT68XX_FLAG_SE_2400 /* Which flags are needed for this scanner? */
/* only partly tested, from "Fan Dan" <dan_fancn@hotmail.com> */
};
static GT68xx_Model mustek_a3usb_model = {
@ -769,7 +769,7 @@ static GT68xx_Model plustek_op1248u_model = {
{12, 8, 0}, /* possible depths in gray mode */
{12, 8, 0}, /* possible depths in color mode */
SANE_FIX (5.6), /* Start of scan area in mm (x) */
SANE_FIX (3.5), /* Start of scan area in mm (x) */
SANE_FIX (7.5), /* Start of scan area in mm (y) */
SANE_FIX (218.0), /* Size of scan area in mm (x) */
SANE_FIX (299.0), /* Size of scan area in mm (y) */
@ -788,12 +788,13 @@ static GT68xx_Model plustek_op1248u_model = {
0, /* CCD distcance for CCD with 6 lines) */
COLOR_ORDER_BGR, /* Order of the CCD/CIS colors */
{31, 25, 31, 25, 31, 25}, /* Default offset/gain */
{0x1c, 0x29, 0x1c, 0x2c, 0x1c, 0x2b}, /* Default offset/gain */
{0x157, 0x157, 0x157}, /* Default exposure parameters */
SANE_FIX (2.0), /* Default gamma value */
SANE_FALSE, /* Is this a CIS scanner? */
GT68XX_FLAG_UNTESTED | GT68XX_FLAG_OFFSET_INV /* Which flags are needed for this scanner? */
GT68XX_FLAG_OFFSET_INV /* Which flags are needed for this scanner? */
/* tested */
};
static GT68xx_USB_Device_Entry gt68xx_usb_device_list[] = {

Wyświetl plik

@ -215,11 +215,20 @@ SANE_Status
gt6801_lamp_control (GT68xx_Device * dev, SANE_Bool fb_lamp,
SANE_Bool ta_lamp)
{
/* this seems not to be supported by the scanner */
(void) dev;
(void) fb_lamp;
(void) ta_lamp;
if (!dev->model->is_cis)
{
GT68xx_Packet req;
memset (req, 0, sizeof (req));
req[0] = 0x25;
req[1] = 0x01;
req[2] = 0;
if (fb_lamp)
req[2] |= 0x01;
if (ta_lamp)
req[2] |= 0x02;
return gt68xx_device_req (dev, req, req);
}
return SANE_STATUS_GOOD;
}
@ -283,9 +292,6 @@ gt6801_stop_scan (GT68xx_Device * dev)
return SANE_STATUS_GOOD;
}
/* 3.0 mm of calibration */
#define CALIBRATION_HEIGHT 3.0
SANE_Status
gt6801_setup_scan (GT68xx_Device * dev,
GT68xx_Scan_Request * request,
@ -359,7 +365,7 @@ gt6801_setup_scan (GT68xx_Device * dev,
y0 = model->y_offset_calib;
else
y0 = 0;
ys = SANE_FIX (CALIBRATION_HEIGHT); /* use 3 mm for calibration */
ys = SANE_FIX (CALIBRATION_HEIGHT);
xs = request->xs;
color = request->color;
break;
@ -474,12 +480,13 @@ gt6801_setup_scan (GT68xx_Device * dev,
bits_per_line = depth * scan_xs;
/*
if (xdpi != base_xdpi)
scan_xs -= 2;
*/
if (xdpi != base_xdpi)
abs_xs = (scan_xs - 2) * base_xdpi / xdpi;
{
if (dev->model->flags & GT68XX_FLAG_SE_2400)
abs_xs = (scan_xs - 1) * base_xdpi / xdpi;
else
abs_xs = (scan_xs - 2) * base_xdpi / xdpi;
}
else
abs_xs = scan_xs * base_xdpi / xdpi;
@ -517,8 +524,10 @@ gt6801_setup_scan (GT68xx_Device * dev,
}
}
if (color && line_mode)
scan_ys *= 3;
if (color)
if (line_mode || dev->model->flags & GT68XX_FLAG_SE_2400) /* ??? */
scan_ys *= 3;
XDBG ((5, "%s: scan_xs=%d, scan_ys=%d\n", function_name, scan_xs, scan_ys));

Wyświetl plik

@ -228,9 +228,6 @@ gt6816_stop_scan (GT68xx_Device * dev)
return gt68xx_device_small_req (dev, req, req);
}
/* 3.0 mm of calibration */
#define CALIBRATION_HEIGHT 3.0
SANE_Status
gt6816_setup_scan (GT68xx_Device * dev,
GT68xx_Scan_Request * request,

Wyświetl plik

@ -1028,79 +1028,78 @@ gt68xx_afe_ccd_calc (GT68xx_Afe_Values * values, unsigned int *buffer)
function_name, values->white, values->black));
}
static void
gt68xx_afe_ccd_adjust_channel_offset (GT68xx_Afe_Values * values,
unsigned int *buffer, SANE_Int off_dist,
SANE_Byte * offset)
static SANE_Bool
gt68xx_afe_ccd_adjust_offset_gain (GT68xx_Afe_Values * values,
unsigned int *buffer, SANE_Byte * offset,
SANE_Byte * pga)
{
SANE_Int avg;
SANE_Int black_low = 3, black_high = 18;
SANE_Int white_low = 234, white_high = 252;
SANE_Bool done = SANE_TRUE;
gt68xx_afe_ccd_calc (values, buffer);
avg = (values->white + values->black) / 2;
if (avg <= 122)
*offset -= (off_dist * values->offset_direction);
else if (avg >= 130)
*offset += (off_dist * values->offset_direction);
DBG (5, "Offset: white=%d, black=%d, avg=%d, offset=%d\n",
values->white, values->black, avg, *offset);
}
static int
gt68xx_afe_ccd_adjust_channel_white (GT68xx_Afe_Values * values,
unsigned int *buffer, SANE_Byte * offset,
SANE_Byte * pga)
{
int done = 0;
gt68xx_afe_ccd_calc (values, buffer);
if ((values->white - values->black) < 230)
if (values->white > white_high)
{
if (values->white > 253)
(*offset) += values->offset_direction;
if (values->black > black_high)
*offset += values->offset_direction;
else if (values->black < black_low)
(*pga)--;
else
{
*offset += values->offset_direction;
(*pga)--;
}
done = SANE_FALSE;
goto finish;
}
else if (values->white < white_low)
{
if (values->black < black_low)
*offset -= values->offset_direction;
else if (values->black > black_high)
(*pga)++;
else
{
*offset -= values->offset_direction;
(*pga)++;
}
done = SANE_FALSE;
goto finish;
}
else
done = 1;
if ((values->white - values->black) > 240)
if (values->black > black_high)
{
(*pga)--;
if (values->white > white_high)
*offset += values->offset_direction;
else if (values->white < white_low)
(*pga)++;
else
{
*offset += values->offset_direction;
(*pga)++;
}
done = SANE_FALSE;
goto finish;
}
DBG (5, "White: white=%d, black=%d, diff=%d, offset=%d, pga=%d\n",
values->white, values->black, values->white - values->black, *offset,
*pga);
return done;
}
static int
gt68xx_afe_ccd_adjust_channel_black (GT68xx_Afe_Values * values,
unsigned int *buffer, SANE_Byte * offset,
SANE_Byte * pga)
{
int done = 0;
gt68xx_afe_ccd_calc (values, buffer);
if (values->black < 5) /* too low */
else if (values->black < black_low)
{
if (values->white > 250)
if (values->white < white_low)
*offset -= values->offset_direction;
else if (values->white > white_high)
(*pga)--;
else
(*offset) -= values->offset_direction;
{
*offset -= values->offset_direction;
(*pga)--;
}
done = SANE_FALSE;
goto finish;
}
else if (values->black < 15) /* just right */
{
if (values->white > 250)
(*pga)--;
else
done = 1;
}
else
(*offset) += values->offset_direction; /* too high */
DBG (5, "Black: white=%d, black=%d, offset=%d, pga=%d\n",
values->white, values->black, *offset, *pga);
finish:
DBG (5, "%swhite=%d, black=%d, offset=%d, gain=%d\n",
done ? "DONE: " : "", values->white, values->black, *offset, *pga);
return done;
}
/** Select best AFE gain and offset parameters.
@ -1127,13 +1126,9 @@ gt68xx_afe_ccd_auto (GT68xx_Scanner * scanner,
GT68xx_Afe_Values values;
unsigned int *buffer_pointers[3];
GT68xx_AFE_Parameters *afe = scanner->dev->afe;
SANE_Int off_dist = 32;
SANE_Int done;
SANE_Bool done;
SANE_Int last_white = 0;
afe->r_pga = afe->g_pga = afe->b_pga = 0x00;
afe->r_offset = afe->g_offset = afe->b_offset = 0x20;
values.offset_direction = 1;
if (scanner->dev->model->flags & GT68XX_FLAG_OFFSET_INV)
values.offset_direction = -1;
@ -1171,7 +1166,6 @@ gt68xx_afe_ccd_auto (GT68xx_Scanner * scanner,
function_name, sane_strstatus (status)));
return status;
}
values.scan_dpi = params.xdpi;
values.calwidth = params.pixel_xs;
values.max_width =
@ -1243,56 +1237,11 @@ gt68xx_afe_ccd_auto (GT68xx_Scanner * scanner,
last_white = values.total_white;
}
for (i = 0; i < 6; i++)
{
/* set afe */
IF_DBG (gt68xx_afe_dump ("scan1", i, afe));
/* read line */
status =
gt68xx_scanner_start_scan_extended (scanner, &request,
SA_CALIBRATE_ONE_LINE, &params);
if (status != SANE_STATUS_GOOD)
{
XDBG ((3, "%s: gt68xx_scanner_start_scan_extended failed: %s\n",
function_name, sane_strstatus (status)));
return status;
}
status = gt68xx_line_reader_read (scanner->reader, buffer_pointers);
if (status != SANE_STATUS_GOOD)
{
XDBG ((3, "%s: gt68xx_line_reader_read failed: %s\n",
function_name, sane_strstatus (status)));
return status;
}
off_dist /= 2;
if (params.color)
{
gt68xx_afe_ccd_adjust_channel_offset (&values, buffer_pointers[0],
off_dist, &afe->r_offset);
gt68xx_afe_ccd_adjust_channel_offset (&values, buffer_pointers[1],
off_dist, &afe->g_offset);
gt68xx_afe_ccd_adjust_channel_offset (&values, buffer_pointers[2],
off_dist, &afe->b_offset);
}
else
{
gt68xx_afe_ccd_adjust_channel_offset (&values, buffer_pointers[0],
off_dist, &afe->g_offset);
}
gt68xx_scanner_stop_scan (scanner);
} /* loop 6 times to do offsets */
i = 0;
do
{
i++;
if (i == 48)
break;
IF_DBG (gt68xx_afe_dump ("scan2", i, afe));
IF_DBG (gt68xx_afe_dump ("scan", i, afe));
/* read line */
status = gt68xx_scanner_start_scan_extended (scanner, &request,
SA_CALIBRATE_ONE_LINE,
@ -1315,76 +1264,26 @@ gt68xx_afe_ccd_auto (GT68xx_Scanner * scanner,
if (params.color)
{
done =
gt68xx_afe_ccd_adjust_channel_white (&values, buffer_pointers[0],
gt68xx_afe_ccd_adjust_offset_gain (&values, buffer_pointers[0],
&afe->r_offset, &afe->r_pga);
done &=
gt68xx_afe_ccd_adjust_channel_white (&values, buffer_pointers[1],
gt68xx_afe_ccd_adjust_offset_gain (&values, buffer_pointers[1],
&afe->g_offset, &afe->g_pga);
done &=
gt68xx_afe_ccd_adjust_channel_white (&values, buffer_pointers[2],
gt68xx_afe_ccd_adjust_offset_gain (&values, buffer_pointers[2],
&afe->b_offset, &afe->b_pga);
}
else
{
done =
gt68xx_afe_ccd_adjust_channel_white (&values, buffer_pointers[0],
gt68xx_afe_ccd_adjust_offset_gain (&values, buffer_pointers[0],
&afe->g_offset, &afe->g_pga);
}
gt68xx_scanner_stop_scan (scanner);
}
while (!done);
while (!done && i < 100);
/* Now loop for dark levels */
do
{
i++;
if (i == 68)
break;
IF_DBG (gt68xx_afe_dump ("scan3", i, afe));
/* read line */
status = gt68xx_scanner_start_scan_extended (scanner, &request,
SA_CALIBRATE_ONE_LINE,
&params);
if (status != SANE_STATUS_GOOD)
{
XDBG ((3, "%s: gt68xx_scanner_start_scan_extended failed: %s\n",
function_name, sane_strstatus (status)));
return status;
}
status = gt68xx_line_reader_read (scanner->reader, buffer_pointers);
if (status != SANE_STATUS_GOOD)
{
XDBG ((3, "%s: gt68xx_line_reader_read failed: %s\n",
function_name, sane_strstatus (status)));
return status;
}
if (params.color)
{
done =
gt68xx_afe_ccd_adjust_channel_black (&values, buffer_pointers[0],
&afe->r_offset, &afe->r_pga);
done &=
gt68xx_afe_ccd_adjust_channel_black (&values, buffer_pointers[1],
&afe->g_offset, &afe->g_pga);
done &=
gt68xx_afe_ccd_adjust_channel_black (&values, buffer_pointers[2],
&afe->b_offset, &afe->b_pga);
}
else
{
done =
gt68xx_afe_ccd_adjust_channel_black (&values, buffer_pointers[0],
&afe->g_offset, &afe->g_pga);
}
gt68xx_scanner_stop_scan (scanner);
}
while (!done);
IF_DBG (gt68xx_afe_dump ("final", i, afe));
return status;
}
@ -1729,6 +1628,7 @@ gt68xx_afe_cis_auto (GT68xx_Scanner * scanner)
free (g_buffer);
free (b_buffer);
XDBG ((4, "%s: total_count: %d\n", function_name, total_count));
return SANE_STATUS_GOOD;
}

Wyświetl plik

@ -199,15 +199,6 @@ enum GT68xx_Option
OPT_COARSE_CAL,
OPT_COARSE_CAL_ONCE,
OPT_QUALITY_CAL,
OPT_SCAN_EXPOS_TIME_R,
OPT_SCAN_EXPOS_TIME_G,
OPT_SCAN_EXPOS_TIME_B,
OPT_OFFSET_R,
OPT_OFFSET_G,
OPT_OFFSET_B,
OPT_GAIN_R,
OPT_GAIN_G,
OPT_GAIN_B,
OPT_ENHANCEMENT_GROUP,
OPT_GAMMA_VALUE,

Wyświetl plik

@ -134,6 +134,7 @@
#define GT68XX_FLAG_MOTOR_HOME (1 << 1) /* Use motor_home command (0x34) */
#define GT68XX_FLAG_OFFSET_INV (1 << 2) /* Offset control is inverted */
#define GT68XX_FLAG_UNTESTED (1 << 3) /* Print a warning for these scanners */
#define GT68XX_FLAG_SE_2400 (1 << 4) /* Special quirks for SE 2400USB */
/* Forward typedefs */
typedef struct GT68xx_USB_Device_Entry GT68xx_USB_Device_Entry;

Wyświetl plik

@ -1,6 +1,6 @@
:backend "gt68xx"
:status :beta
:version "1.0-32"
:version "1.0-35"
:new :yes
:manpage "sane-gt68xx"
:url "http://www.meier-geinitz.de/sane/gt68xx-backend/"
@ -78,13 +78,13 @@
:model "OpticPro 1248U"
:interface "USB"
:status :alpha
:comment "Works up to 600 dpi in gray mode, try disabling calibration"
:status :beta
:comment "Works up to 600 dpi"
:model "OpticPro UT16B"
:interface "USB"
:status :untested
:comment "Isn't detected yet mut may work some time in future. Testers welcome."
:comment "Isn't detected yet but may work some time in future. Testers welcome."
:mfg "Artec"
:url "http://www.artecusa.com/"

Wyświetl plik

@ -1,5 +1,25 @@
gt68xx.CHANGES -*-text-*-
V 1.0-35 (2002-12-23)
- Added "afe" option for gt68xx.conf for selecting default afe values.
- Removed AFE and exposure SANE options.
- Added documentation for afe option in gt68xx.conf.
V 1.0-34 (2002-12-18)
- fixed gt68xx_gt6801 -> lamp control.
- adjusted Plustek 1248U geometry and afe values.
- CCD gross calibration changed: start with the default value from module struct.
Is faster now for most cases.
- Only 2.5 mm of calibration for GT-6801 scanners.
V 1.0-33 (2002-12-10)
- Updated ScanExpress 2400 USB values (from "Fan Dan" <dan_fancn@hotmail.com>).
- Added implementation of gt6801 lamp control for CCD scanners.
- Added flag for SE 2400 USB, added some quirks in gt68xx_gt6801.c.
V 1.0-32 (2002-12-08)
- "Coarse calibration for first scan only" is off by default now. As at least
@ -22,7 +42,7 @@ V 1.0-31 (2002-11-21)
- Changed 150 to 200 dpi for Mustek BearPaw 2400 TA.
- Fixed warnings in gt68xx_low.c
- Used DBG instead of XDBG ing gt68xx_low.c
- Used DBG instead of XDBG in gt68xx_low.c
- Minor manpage fixes. Added man page links to other backends.
- gt68xx_low.h: Fixed __FUNCTION__ bug on non-gcc compilers.
- Added more details about the BSDs in the manpage.

Wyświetl plik

@ -1,4 +1,4 @@
.TH sane-gt68xx 5 "13 Nov 2002" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.TH sane-gt68xx 5 "23 Dec 2002" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.IX sane-gt68xx
.SH NAME
sane-gt68xx \- SANE backend for GT-68XX based USB flatbed scanners
@ -117,8 +117,9 @@ The
.BR override ,
.BR firmware ,
.BR vendor ,
.BR model ,
and
.B model
.B afe
options must be placed after the
.B usb
line they refer to.
@ -137,7 +138,11 @@ is used for the Artec Ultima 2000, the Boeder SmartScan Slim Edition, the
Medion/ Lifetec/ Tevion/ Cytron MD/LT 9385, the Medion/ Lifetec/ Tevion MD
9458, and the Trust Flat Scan USB 19200.
.B override "mustek-bearpaw-2400-cu"
is necessary for the Mustek BearPaw 2400 CU.
is necessary for the Mustek BearPaw 2400 CU. The
.B override
option must be the first one after the
.B usb
line.
.PP
Option
.B firmware
@ -157,6 +162,17 @@ options are not absolutely necessary but for convenience. Quite a lot of
scanners from different manufacturers share the same vendor/product ids so you
can set the "correct" name here.
.PP
The
.B afe
option allows to set custom offset and gain values for the Analog FrontEnd of
the scanner. This option can be either used to select the AFE values if
automatic coarse calibration is disabled, or to make automatic coarse
calibration faster. For the latter usage, enable debug level 3 (see below),
scan an image and look for debug line string with "afe". Copy this line to
.IR gt68xx.conf .
The option has six parameters: res offset, red gain, green offset, green gain,
blue offset, and blue gain.
.PP
A sample configuration file is shown below:
.PP
.RS
@ -169,6 +185,8 @@ firmware "/opt/gt68xx/SBfw.usb"
vendor "Trust"
.br
product "Compact Scan USB 19200"
.br
afe 0x20 0x02 0x22 0x03 0x1f 0x04
.RE
.SH FILES
@ -229,7 +247,7 @@ David Stevenson. Thanks for sending patches and answering questions to them
and all the other contributors.
.SH BUGS
Currently scanning seems to only work reliably under Linux. With the FreeBSD,
Currently scanning seems to only work reliably under Linux. With FreeBSD,
NetBSD and OpenBSD scanning works only once. Then either the scanner has to be
replugged or even a reboot is necessary. That's most probably a kernel issue.
.PP