working version for KV-SS080

- offset and gain calibration are tuned
merge-requests/1/head
Stphane Voltz 2010-08-31 21:39:21 +02:00
rodzic bee968b93d
commit e72d6c1007
3 zmienionych plików z 462 dodań i 79 usunięć

Wyświetl plik

@ -1511,7 +1511,7 @@ genesys_send_offset_and_shading (Genesys_Device * dev, uint8_t * data,
sane_strstatus (status));
return status;
}
status = dev->model->cmd_set->bulk_write_data (dev, 0x3c, data, size);
if (status != SANE_STATUS_GOOD)
{
@ -2548,14 +2548,8 @@ genesys_dummy_dark_shading (Genesys_Device * dev)
DBG (DBG_proc, "genesys_dummy_dark_shading \n");
pixels_per_line =
(genesys_pixels_per_line (dev->calib_reg)
* genesys_dpiset (dev->calib_reg)) / dev->sensor.optical_res;
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
channels = 3;
else
channels = 1;
pixels_per_line = dev->calib_pixels;
channels = dev->calib_channels;
FREE_IFNOT_NULL (dev->dark_average_data);
@ -2583,8 +2577,8 @@ genesys_dummy_dark_shading (Genesys_Device * dev)
}
if(dev->model->ccd_type==CCD_KVSS080)
{
skip = 0;
xend = 40;
skip = 2;
xend = dev->sensor.black_pixels;
}
/* average each channels on half left margin */
@ -3102,7 +3096,6 @@ compute_averaged_planar (Genesys_Device * dev,
}
}
/**
* Computes shading coefficient using formula in data sheet. 16bit data values
* manipulated here are little endian. For now we assume deletion scanning type
@ -3135,7 +3128,7 @@ compute_coefficients (Genesys_Device * dev,
DBG (DBG_io,
"compute_coefficients: pixels_per_line=%d, coeff=0x%04x\n", pixels_per_line, coeff);
/* compute start & end values depending of the offset */
if (offset < 0)
{
@ -3171,6 +3164,7 @@ compute_coefficients (Genesys_Device * dev,
ptr[1] = dk / 256;
ptr[2] = val & 0xff;
ptr[3] = val / 256;
}
}
}
@ -3268,9 +3262,10 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
{
SANE_Status status;
uint16_t pixels_per_line;
uint16_t *fixup,*shading;
uint8_t *shading_data; /**> contains 16bit words in little endian */
uint8_t channels;
unsigned int x, j;
unsigned int x, j, src, dst;
int o;
unsigned int length; /**> number of shading calibration data words */
unsigned int i, res, factor;
@ -3459,11 +3454,32 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
compute_coefficients (dev,
shading_data,
pixels_per_line,
3,
3,
cmat,
o,
coeff,
target_code);
/* shading data fixup */
shading=(uint16_t *)shading_data;
fixup = malloc ((length*256)/252+512);
if (!shading_data)
{
DBG (DBG_error, "%s: failed to allocate memory for shading fixup\n",__FUNCTION__);
return SANE_STATUS_NO_MEM;
}
src=0;
dst=0;
while(src<length/2)
{
fixup[dst]=shading[src];
if((dst%256)==252)
dst+=4;
dst++;
src++;
}
free(shading_data);
shading_data=fixup;
length = ((length*256)/252+512);
break;
case CIS_CANONLIDE100:
case CIS_CANONLIDE200:
@ -6397,6 +6413,7 @@ static SANE_Status
check_present (SANE_String_Const devname)
{
present=SANE_TRUE;
return SANE_STATUS_GOOD;
}
static SANE_Status
@ -6460,7 +6477,6 @@ attach (SANE_String_Const devname, Genesys_Device ** devp, SANE_Bool may_wait)
sanei_usb_find_devices (vendor, 0x1006, check_present);
sanei_usb_find_devices (vendor, 0x1007, check_present);
sanei_usb_find_devices (vendor, 0x1010, check_present);
sanei_usb_find_devices (vendor, 0x100f, check_present);
if(present==SANE_FALSE)
{
DBG (DBG_error,"attach: master device not present\n");

Wyświetl plik

@ -470,12 +470,12 @@ static Genesys_Sensor Sensor[] = {
,
{CCD_KVSS080,
600,
64, /* 48 */
36,
38, /* black pixels on left */
38, /* 36 dummy pixels */
152,
5100,
210,
230,
5200, /* 5100 */
160, /* TAU white ref */
160, /* gain white ref */
/* 08 09 0a 0b */
{0x00, 0x00, 0x00, 0x6a} ,
/* 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d */
@ -1009,11 +1009,11 @@ static Genesys_Model panasonic_kvss080_model = {
{16, 8, 0}, /* possible depths in color mode */
SANE_FIX (7.6), /* Start of scan area in mm (x) */
SANE_FIX (12.6), /* Start of scan area in mm (y) */
SANE_FIX (12.5), /* Start of scan area in mm (y) */
SANE_FIX (218.5), /* Size of scan area in mm (x) */
SANE_FIX (297.0), /* Size of scan area in mm (y) */
SANE_FIX (0.0), /* Start of white strip in mm (y) */
SANE_FIX (9.0), /* Start of white strip in mm (y) */
SANE_FIX (0.0), /* Start of black mark in mm (x) */
SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */
@ -1039,12 +1039,14 @@ static Genesys_Model panasonic_kvss080_model = {
GPO_KVSS080,
MOTOR_KVSS080,
GENESYS_FLAG_LAZY_INIT |
GENESYS_FLAG_NO_CALIBRATION |
GENESYS_FLAG_SKIP_WARMUP |
/* GENESYS_FLAG_NO_CALIBRATION | */
/* GENESYS_FLAG_DARK_CALIBRATION | */
GENESYS_FLAG_OFFSET_CALIBRATION |
GENESYS_FLAG_CUSTOM_GAMMA,
GENESYS_HAS_SCAN_SW ,
280,
400
100,
100
};
static Genesys_Model hpg4050_model = {

Wyświetl plik

@ -148,6 +148,8 @@ gl843_bulk_write_data (Genesys_Device * dev, uint8_t addr,
return status;
}
/* recreate data buffer to take care of memory layout */
status = sanei_usb_write_bulk (dev->dn, data, &size);
if (status != SANE_STATUS_GOOD)
{
@ -979,7 +981,6 @@ gl843_init_motor_regs_scan (Genesys_Device * dev,
{
dist += fast_steps*2;
}
/* dist <<= scan_step_type; */
DBG (DBG_io2, "%s: acceleration distance=%d\n", __FUNCTION__, dist);
/* get sure when don't insane value */
@ -1068,7 +1069,7 @@ gl843_get_dpihw (Genesys_Device * dev)
/** @brief setup optical related registers
* start and pixels are expressed in optical sensor resolution coordinate
* space. To handle odd/even case we double the resolution and
* use only first logival half the sensor whic maps to effectice CCD.
* use only first logival half the sensor whic maps to effective CCD.
* @param start logical start pixel coordinate
* @param pixels logical number of pixels to use
* @return SANE_STATUS_GOOD if OK
@ -1133,6 +1134,7 @@ gl843_init_optical_regs_scan (Genesys_Device * dev,
{
r->value |= REG01_DVDSET;
}
r->value &= ~REG01_DVDSET;
r = sanei_genesys_get_address (reg, REG03);
r->value &= ~REG03_AVEENB;
@ -2291,8 +2293,7 @@ gl843_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
SCAN_FLAG_DISABLE_SHADING |
SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_SINGLE_LINE |
SCAN_FLAG_IGNORE_LINE_DISTANCE |
SCAN_FLAG_USE_OPTICAL_RES);
SCAN_FLAG_IGNORE_LINE_DISTANCE);
gl843_init_motor_regs_scan (dev,
local_reg,
8000,
@ -2480,10 +2481,9 @@ gl843_init_regs_for_coarse_calibration (Genesys_Device * dev)
SANE_Status status;
uint8_t channels;
uint8_t cksel;
Genesys_Register_Set *r;
DBG (DBG_proc, "gl843_init_regs_for_coarse_calibration\n");
DBGSTART;
cksel = (dev->calib_reg[reg_0x18].value & REG18_CKSEL) + 1; /* clock speed = 1..4 clocks */
/* set line size */
@ -2510,10 +2510,12 @@ gl843_init_regs_for_coarse_calibration (Genesys_Device * dev)
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl843_init_register_for_coarse_calibration: Failed to setup scan: %s\n",
"gl843_init_register_for_coarse_calibration: failed to setup scan: %s\n",
sane_strstatus (status));
return status;
}
r = sanei_genesys_get_address (dev->calib_reg, REG02);
r->value &= ~REG02_MTRPWR;
DBG (DBG_info,
"gl843_init_register_for_coarse_calibration: optical sensor res: %d dpi, actual res: %d\n",
@ -2524,17 +2526,12 @@ gl843_init_regs_for_coarse_calibration (Genesys_Device * dev)
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl843_init_register_for_coarse_calibration: Failed to bulk write registers: %s\n",
"gl843_init_register_for_coarse_calibration: failed to bulk write registers: %s\n",
sane_strstatus (status));
return status;
}
DBG (DBG_proc, "gl843_init_register_for_coarse_calibration: completed\n");
/* if (DBG_LEVEL >= DBG_info)
sanei_gl843_print_registers (dev->calib_reg);*/
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
@ -2544,24 +2541,33 @@ static SANE_Status
gl843_init_regs_for_shading (Genesys_Device * dev)
{
SANE_Status status;
int move,resolution;
DBG (DBG_proc, "gl843_init_regs_for_shading: lines = %d\n",
dev->model->shading_lines);
dev->calib_channels = 3;
/* initial calibration reg values */
memcpy (dev->calib_reg, dev->reg,
GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
dev->calib_channels = 3;
/* follow CKSEL */
if(dev->settings.xres<dev->sensor.optical_res)
resolution=dev->sensor.optical_res/2;
else
resolution=dev->sensor.optical_res;
dev->calib_pixels = dev->sensor.sensor_pixels;
/* distance to move to reach white target */
move = SANE_UNFIX (dev->model->y_offset_calib);
move = (move * dev->sensor.optical_res) / MM_PER_INCH;
status = gl843_init_scan_regs (dev,
dev->calib_reg,
resolution,
dev->sensor.optical_res,
dev->motor.base_ydpi,
0,
0,
move,
dev->calib_pixels,
dev->model->shading_lines,
16,
@ -2570,32 +2576,34 @@ gl843_init_regs_for_shading (Genesys_Device * dev)
SCAN_FLAG_DISABLE_SHADING |
SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE |
SCAN_FLAG_IGNORE_LINE_DISTANCE |
SCAN_FLAG_USE_OPTICAL_RES);
SCAN_FLAG_IGNORE_LINE_DISTANCE);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl843_init_registers_for_shading: Failed to setup scan: %s\n",
"gl843_init_registers_for_shading: failed to setup scan: %s\n",
sane_strstatus (status));
return status;
}
dev->scanhead_position_in_steps += dev->model->shading_lines;
dev->scanhead_position_in_steps += dev->model->shading_lines + move;
status =
gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl843_init_registers_for_shading: Failed to bulk write registers: %s\n",
"gl843_init_registers_for_shading: failed to bulk write registers: %s\n",
sane_strstatus (status));
return status;
}
DBG (DBG_proc, "gl843_init_regs_for_shading: completed\n");
/* this is an hack to make calibration cache working .... */
/* if we don't do this, cache will be identified at the shading calibration
* dpi which is diferent from calibration one */
dev->current_setup.xres = resolution;
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
@ -2619,8 +2627,11 @@ gl843_init_regs_for_scan (Genesys_Device * dev)
dev->settings.yres, dev->settings.lines, dev->settings.pixels,
dev->settings.tl_x, dev->settings.tl_y, dev->settings.scan_mode);
/* ensure head is parked in case of calibration */
gl843_slow_back_home (dev, SANE_TRUE);
/* channels */
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
if (dev->settings.scan_mode == SCAN_MODE_COLOR)
channels = 3;
else
channels = 1;
@ -2871,8 +2882,7 @@ gl843_led_calibration (Genesys_Device * dev)
SCAN_FLAG_DISABLE_SHADING |
SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_SINGLE_LINE |
SCAN_FLAG_IGNORE_LINE_DISTANCE |
SCAN_FLAG_USE_OPTICAL_RES);
SCAN_FLAG_IGNORE_LINE_DISTANCE);
if (status != SANE_STATUS_GOOD)
{
@ -3017,19 +3027,198 @@ gl843_led_calibration (Genesys_Device * dev)
return status;
}
/* this function does the offset calibration by scanning one line of the calibration
area below scanner's top. There is a black margin and the remaining is white.
sanei_genesys_search_start() must have been called so that the offsets and margins
are allready known.
this function expects the slider to be where?
*/
/**
* average dark pixels of a 8 bits scan
*/
static int
dark_average (uint8_t * data, unsigned int pixels, unsigned int lines,
unsigned int channels, unsigned int black)
{
unsigned int i, j, k, average, count;
unsigned int avg[3];
uint8_t val;
/* computes average value on black margin */
for (k = 0; k < channels; k++)
{
avg[k] = 0;
count = 0;
for (i = 0; i < lines; i++)
{
for (j = 0; j < black; j++)
{
val = data[i * channels * pixels + j + k];
avg[k] += val;
count++;
}
}
if (count)
avg[k] /= count;
DBG (DBG_info, "dark_average: avg[%d] = %d\n", k, avg[k]);
}
average = 0;
for (i = 0; i < channels; i++)
average += avg[i];
average /= channels;
DBG (DBG_info, "dark_average: average = %d\n", average);
return average;
}
static SANE_Status
gl843_offset_calibration (Genesys_Device * dev)
{
DBG (DBG_proc, "%s: not implemented \n", __FUNCTION__);
if (dev == NULL)
return SANE_STATUS_INVAL;
Genesys_Register_Set *r;
SANE_Status status = SANE_STATUS_GOOD;
uint8_t *first_line, *second_line;
unsigned int channels, bpp;
char title[32];
int pass = 0, avg, total_size;
int topavg, bottomavg, resolution, lines;
int top, bottom, black_pixels, pixels;
DBGSTART;
/* offset calibration is always done in color mode */
channels = 3;
/* follow CKSEL */
if(dev->settings.xres<dev->sensor.optical_res)
resolution=dev->sensor.optical_res/2;
else
resolution=dev->sensor.optical_res;
dev->calib_pixels = dev->sensor.sensor_pixels;
lines=1;
bpp=8;
pixels= (dev->sensor.sensor_pixels*resolution) / dev->sensor.optical_res;
black_pixels = (dev->sensor.black_pixels * resolution) / dev->sensor.optical_res;
DBG (DBG_io2, "gl843_offset_calibration: black_pixels=%d\n", black_pixels);
status = gl843_init_scan_regs (dev,
dev->calib_reg,
resolution,
resolution,
0,
0,
pixels,
lines,
bpp,
channels,
dev->settings.color_filter,
SCAN_FLAG_DISABLE_SHADING |
SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_SINGLE_LINE |
SCAN_FLAG_IGNORE_LINE_DISTANCE);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl843_offset_calibration: failed to setup scan: %s\n",
sane_strstatus (status));
return status;
}
r = sanei_genesys_get_address (dev->calib_reg, REG02);
r->value &= ~REG02_MTRPWR;
/* allocate memory for scans */
total_size = pixels * channels * lines * (bpp/8); /* colors * bytes_per_color * scan lines */
first_line = malloc (total_size);
if (!first_line)
return SANE_STATUS_NO_MEM;
second_line = malloc (total_size);
if (!second_line)
{
free (first_line);
return SANE_STATUS_NO_MEM;
}
/* init gain */
dev->frontend.gain[0] = 0;
dev->frontend.gain[1] = 0;
dev->frontend.gain[2] = 0;
/* scan with no move */
bottom = 10;
dev->frontend.offset[0] = bottom;
dev->frontend.offset[1] = bottom;
dev->frontend.offset[2] = bottom;
RIE (gl843_set_fe(dev, AFE_SET));
RIE (gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
DBG (DBG_info, "gl843_offset_calibration: starting first line reading\n");
RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
RIE (sanei_genesys_read_data_from_scanner (dev, first_line, total_size));
if (DBG_LEVEL >= DBG_data)
{
snprintf(title,20,"offset%03d.pnm",bottom);
sanei_genesys_write_pnm_file (title, first_line, bpp, channels, pixels, lines);
}
bottomavg = dark_average (first_line, pixels, lines, channels, black_pixels);
DBG (DBG_io2, "gl843_offset_calibration: bottom avg=%d\n", bottomavg);
/* now top value */
top = 255;
dev->frontend.offset[0] = top;
dev->frontend.offset[1] = top;
dev->frontend.offset[2] = top;
RIE (gl843_set_fe(dev, AFE_SET));
RIE (gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
DBG (DBG_info, "gl843_offset_calibration: starting second line reading\n");
RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
RIE (sanei_genesys_read_data_from_scanner (dev, second_line, total_size));
topavg = dark_average (second_line, pixels, lines, channels, black_pixels);
DBG (DBG_io2, "gl843_offset_calibration: top avg=%d\n", topavg);
/* loop until acceptable level */
while ((pass < 32) && (top - bottom > 1))
{
pass++;
/* settings for new scan */
dev->frontend.offset[0] = (top + bottom) / 2;
dev->frontend.offset[1] = (top + bottom) / 2;
dev->frontend.offset[2] = (top + bottom) / 2;
/* scan with no move */
RIE(gl843_set_fe(dev, AFE_SET));
RIE (gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
DBG (DBG_info, "gl843_offset_calibration: starting second line reading\n");
RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
RIE (sanei_genesys_read_data_from_scanner (dev, second_line, total_size));
if (DBG_LEVEL >= DBG_data)
{
sprintf (title, "offset%03d.pnm", dev->frontend.offset[1]);
sanei_genesys_write_pnm_file (title, second_line, bpp, channels, pixels, lines);
}
avg = dark_average (second_line, pixels, lines, channels, black_pixels);
DBG (DBG_info, "gl843_offset_calibration: avg=%d offset=%d\n", avg,
dev->frontend.offset[1]);
/* compute new boundaries */
if (topavg == avg)
{
topavg = avg;
top = dev->frontend.offset[1];
}
else
{
bottomavg = avg;
bottom = dev->frontend.offset[1];
}
}
DBG (DBG_info, "gl843_offset_calibration: offset=(%d,%d,%d)\n", dev->frontend.offset[0], dev->frontend.offset[1], dev->frontend.offset[2]);
top = dev->frontend.offset[1];
/* cleanup before return */
free (first_line);
free (second_line);
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
@ -3046,10 +3235,145 @@ gl843_offset_calibration (Genesys_Device * dev)
static SANE_Status
gl843_coarse_gain_calibration (Genesys_Device * dev, int dpi)
{
int pixels;
int total_size;
uint8_t *line;
int i, j, channels;
SANE_Status status = SANE_STATUS_GOOD;
int max[3];
float gain[3],coeff;
int val, code, lines;
int resolution;
Genesys_Register_Set *r;
int bpp;
DBG (DBG_proc, "gl843_coarse_gain_calibration: dpi = %d\n", dpi);
DBG (DBG_proc, "%s: not implemented \n", __FUNCTION__);
if (dev == NULL)
return SANE_STATUS_INVAL;
/* coarse gain calibration is always done in color mode */
channels = 3;
/* follow CKSEL */
if(dev->settings.xres<dev->sensor.optical_res)
{
coeff=0.9;
resolution=dev->sensor.optical_res/2;
resolution=dev->sensor.optical_res;
}
else
{
resolution=dev->sensor.optical_res;
coeff=1.0;
}
lines=10;
bpp=8;
pixels = (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res,
status = gl843_init_scan_regs (dev,
dev->calib_reg,
resolution,
resolution,
0,
0,
pixels,
lines,
bpp,
channels,
dev->settings.color_filter,
SCAN_FLAG_DISABLE_SHADING |
SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_SINGLE_LINE |
SCAN_FLAG_IGNORE_LINE_DISTANCE);
r = sanei_genesys_get_address (dev->calib_reg, REG02);
r->value &= ~REG02_MTRPWR;
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl843_coarse_calibration: failed to setup scan: %s\n",
sane_strstatus (status));
return status;
}
RIE (gl843_bulk_write_register
(dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
total_size = pixels * channels * (16/bpp) * lines;
line = malloc (total_size);
if (!line)
return SANE_STATUS_NO_MEM;
RIE (gl843_set_fe(dev, AFE_SET));
RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
RIE (sanei_genesys_read_data_from_scanner (dev, line, total_size));
if (DBG_LEVEL >= DBG_data)
sanei_genesys_write_pnm_file ("coarse.pnm", line, bpp, channels, pixels, lines);
/* average value on each channel */
for (j = 0; j < channels; j++)
{
max[j] = 0;
for (i = pixels/4; i < (pixels*3/4); i++)
{
if(bpp==16)
{
if (dev->model->is_cis)
val =
line[i * 2 + j * 2 * pixels + 1] * 256 +
line[i * 2 + j * 2 * pixels];
else
val =
line[i * 2 * channels + 2 * j + 1] * 256 +
line[i * 2 * channels + 2 * j];
}
else
{
if (dev->model->is_cis)
val = line[i + j * pixels];
else
val = line[i * channels + j];
}
max[j] += val;
}
max[j] = max[j] / (pixels/2);
gain[j] = ((float) dev->sensor.gain_white_ref*coeff) / max[j];
/* turn logical gain value into gain code, checking for overflow */
code = 283 - 208 / gain[j];
if (code > 255)
code = 255;
else if (code < 0)
code = 0;
dev->frontend.gain[j] = code;
DBG (DBG_proc,
"gl843_coarse_gain_calibration: channel %d, max=%d, gain = %f, setting:%d\n",
j, max[j], gain[j], dev->frontend.gain[j]);
}
if (dev->model->is_cis)
{
if (dev->frontend.gain[0] > dev->frontend.gain[1])
dev->frontend.gain[0] = dev->frontend.gain[1];
if (dev->frontend.gain[0] > dev->frontend.gain[2])
dev->frontend.gain[0] = dev->frontend.gain[2];
dev->frontend.gain[2] = dev->frontend.gain[1] = dev->frontend.gain[0];
}
if (channels == 1)
{
dev->frontend.gain[0] = dev->frontend.gain[1];
dev->frontend.gain[2] = dev->frontend.gain[1];
}
free (line);
RIE (gl843_stop_action (dev));
gl843_slow_back_home (dev, SANE_TRUE);
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
@ -3088,9 +3412,7 @@ gl843_init_regs_for_warmup (Genesys_Device * dev,
SCAN_FLAG_DISABLE_SHADING |
SCAN_FLAG_DISABLE_GAMMA |
SCAN_FLAG_SINGLE_LINE |
SCAN_FLAG_IGNORE_LINE_DISTANCE |
SCAN_FLAG_USE_OPTICAL_RES
);
SCAN_FLAG_IGNORE_LINE_DISTANCE);
if (status != SANE_STATUS_GOOD)
{
@ -3117,12 +3439,18 @@ gl843_is_compatible_calibration (Genesys_Device * dev,
Genesys_Calibration_Cache * cache,
int for_overwrite)
{
#ifdef HAVE_SYS_TIME_H
struct timeval time;
#endif
int compatible = 1, resolution;
SANE_Status status;
DBG (DBG_proc, "gl843_is_compatible_calibration\n");
DBGSTART;
if (cache == NULL || for_overwrite)
return SANE_STATUS_UNSUPPORTED;
status = gl843_calculate_current_setup (dev);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
@ -3130,14 +3458,51 @@ gl843_is_compatible_calibration (Genesys_Device * dev,
sane_strstatus (status));
return status;
}
if(dev->settings.xres<dev->sensor.optical_res)
resolution=dev->sensor.optical_res/2;
else
resolution=dev->sensor.optical_res;
dev->current_setup.scan_method = dev->settings.scan_method;
DBG (DBG_proc, "gl843_is_compatible_calibration: checking\n");
/* a calibration cache is compatible if color mode and x dpi match the user
* requested scan. In the case of CIS scanners, dpi isn't a criteria */
if (dev->model->is_cis == SANE_FALSE)
{
compatible = (resolution == ((int) cache->used_setup.xres));
compatible = 0;
}
else
{
compatible = (dev->current_setup.channels == cache->used_setup.channels);
}
if (dev->current_setup.scan_method != cache->used_setup.scan_method)
{
DBG (DBG_io,
"gl843_is_compatible_calibration: current method=%d, used=%d\n",
dev->current_setup.scan_method, cache->used_setup.scan_method);
compatible = 0;
}
if (!compatible)
{
DBG (DBG_proc,
"gl843_is_compatible_calibration: completed, non compatible cache\n");
return SANE_STATUS_UNSUPPORTED;
}
if (dev->current_setup.half_ccd != cache->used_setup.half_ccd)
return SANE_STATUS_UNSUPPORTED;
if (for_overwrite)
return SANE_STATUS_UNSUPPORTED;
/* a cache entry expires after 30 minutes for non CIS scanners */
#ifdef HAVE_SYS_TIME_H
gettimeofday (&time, NULL);
if ((time.tv_sec - cache->last_calibration > 30 * 60)
&& (dev->model->is_cis == SANE_FALSE)
&& (dev->settings.scan_method == SCAN_METHOD_FLATBED))
{
DBG (DBG_proc,
"gl843_is_compatible_calibration: expired entry, non compatible cache\n");
return SANE_STATUS_UNSUPPORTED;
}
#endif
DBGCOMPLETED;
return SANE_STATUS_GOOD;
@ -3579,7 +3944,7 @@ gl843_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl843_search_strip: Failed to bulk write registers: %s\n",
"gl843_search_strip: failed to bulk write registers: %s\n",
sane_strstatus (status));
return status;
}