- calibration cache activation for gl646 scanners

merge-requests/1/head
Stéphane Voltz 2009-04-15 19:24:10 +00:00
rodzic 3654ff9d43
commit d32f758ce3
3 zmienionych plików z 148 dodań i 86 usunięć

Wyświetl plik

@ -1,3 +1,7 @@
2009-04-15 Stéphane Voltz <stef.dev@free.fr>
* backend/genesys.c backend/genesys_gl646.c: calibration cache
activation for gl646 based scanners
2009-04-15 m. allan noah <kitno455 a t gmail d o t com>
* backend/fujitsu.c, doc/descriptions/fujitsu.desc: backend v93
- return cmd status for reads of sensor options

Wyświetl plik

@ -2977,30 +2977,13 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
switch (dev->model->ccd_type)
{
case CCD_5345:
target_code = 0xfa00;
memset (shading_data, 0x00, pixels_per_line * 4 * channels);
o=2;
avgpixels = 1;
compute_coefficients(dev,
shading_data,
pixels_per_line,
channels,
avgpixels,
o,
coeff,
target_code);
break;
case CCD_HP2300:
case CCD_HP2400:
case CCD_HP3670:
target_code = 0xfa00;
memset (shading_data, 0x00, pixels_per_line * 4 * channels);
o = 2; /* when ~AVEENB, o=3 if AVEENB ? */
if(dev->settings.xres<=150)
avgpixels = 2;
else
avgpixels = 1;
/* TODO: if FASTMODE, shading data is 'color component line by line' */
o=2;
avgpixels = 1;
compute_coefficients(dev,
shading_data,
pixels_per_line,
@ -3279,17 +3262,22 @@ genesys_save_calibration (Genesys_Device * dev)
if (!dev->model->cmd_set->is_compatible_calibration)
return SANE_STATUS_UNSUPPORTED;
for(cache = dev->calibration_cache; cache && status==SANE_STATUS_UNSUPPORTED; cache = cache->next)
for(cache = dev->calibration_cache; cache; cache = cache->next)
{
status = dev->model->cmd_set->is_compatible_calibration(dev, cache,
SANE_TRUE);
if (status != SANE_STATUS_GOOD)
if (status == SANE_STATUS_UNSUPPORTED)
{
continue;
}
else if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"genesys_save_calibration: fail while checking compatibility: %s\n",
sane_strstatus (status));
return status;
}
break;
}
if(cache)
@ -3845,6 +3833,8 @@ genesys_start_scan (Genesys_Device * dev)
}
}
/* TODO: STEF we should move gamma table handling out of calibration, when cache
* is active, custom gamma tables don't seem to be sent */
status = genesys_restore_calibration (dev);
if(status == SANE_STATUS_UNSUPPORTED)
{

Wyświetl plik

@ -1338,6 +1338,7 @@ gl646_setup_registers (Genesys_Device * dev,
else
channels = 1;
/* R01 */
/* now setup other registers for final scan (ie with shading enabled) */
/* watch dog + shading + scan enable */
regs[reg_0x01].value |= REG01_DOGENB | REG01_DVDSET | REG01_SCAN;
@ -1351,6 +1352,7 @@ gl646_setup_registers (Genesys_Device * dev,
else
regs[reg_0x01].value &= ~REG01_FASTMOD;
/* R02 */
/* allow moving when buffer full by default */
if (dev->model->is_sheetfed == SANE_FALSE)
dev->reg[reg_0x02].value &= ~REG02_ACDCDIS;
@ -1628,10 +1630,10 @@ gl646_setup_registers (Genesys_Device * dev,
/* the 3670 seems to behave differently regarding GPIO */
/* TODO to be added in the sensor setting struct ?? */
if (dev->model->ccd_type==CCD_HP3670)
{
dev->reg[reg_0x66].value = 0;
}
if (dev->model->ccd_type == CCD_HP3670)
{
dev->reg[reg_0x66].value = 0;
}
RIE (write_control (dev, xresolution));
@ -2265,24 +2267,24 @@ gl646_set_fe (Genesys_Device * dev, uint8_t set)
/* here starts AFE_SET */
/* TODO : base this test on cfg reg3 or a CCD family flag to be created */
/* if (dev->model->ccd_type != CCD_HP2300
&& dev->model->ccd_type != CCD_HP3670
&& dev->model->ccd_type != CCD_HP2400) */
{
status = sanei_genesys_fe_write_data (dev, 0x00, dev->frontend.reg[0]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl646_set_fe: writing reg0 failed: %s\n",
sane_strstatus (status));
return status;
}
status = sanei_genesys_fe_write_data (dev, 0x02, dev->frontend.reg[2]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl646_set_fe: writing reg2 failed: %s\n",
sane_strstatus (status));
return status;
}
}
&& dev->model->ccd_type != CCD_HP3670
&& dev->model->ccd_type != CCD_HP2400) */
{
status = sanei_genesys_fe_write_data (dev, 0x00, dev->frontend.reg[0]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl646_set_fe: writing reg0 failed: %s\n",
sane_strstatus (status));
return status;
}
status = sanei_genesys_fe_write_data (dev, 0x02, dev->frontend.reg[2]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl646_set_fe: writing reg2 failed: %s\n",
sane_strstatus (status));
return status;
}
}
/* start with reg3 */
status = sanei_genesys_fe_write_data (dev, 0x03, dev->frontend.reg[3]);
@ -2330,28 +2332,28 @@ gl646_set_fe (Genesys_Device * dev, uint8_t set)
}
}
break;
/* just can't have it to work ....
case CCD_HP2300:
case CCD_HP2400:
case CCD_HP3670:
/* just can't have it to work ....
case CCD_HP2300:
case CCD_HP2400:
case CCD_HP3670:
status =
sanei_genesys_fe_write_data (dev, 0x23, dev->frontend.offset[1]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl646_set_fe: writing offset[1] failed: %s\n",
sane_strstatus (status));
return status;
}
status = sanei_genesys_fe_write_data (dev, 0x28, dev->frontend.gain[1]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl646_set_fe: writing gain[1] failed: %s\n",
sane_strstatus (status));
return status;
}
break; */
status =
sanei_genesys_fe_write_data (dev, 0x23, dev->frontend.offset[1]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl646_set_fe: writing offset[1] failed: %s\n",
sane_strstatus (status));
return status;
}
status = sanei_genesys_fe_write_data (dev, 0x28, dev->frontend.gain[1]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl646_set_fe: writing gain[1] failed: %s\n",
sane_strstatus (status));
return status;
}
break; */
}
/* end with reg1 */
@ -3382,7 +3384,7 @@ gl646_init_regs_for_shading (Genesys_Device * dev)
settings.yres = dev->sensor.optical_res / half_ccd;
settings.tl_x = 0;
settings.tl_y = 0;
settings.pixels = dev->sensor.sensor_pixels/half_ccd;
settings.pixels = dev->sensor.sensor_pixels / half_ccd;
settings.lines = dev->model->shading_lines;
settings.depth = 16;
settings.color_filter = dev->settings.color_filter;
@ -3394,7 +3396,7 @@ gl646_init_regs_for_shading (Genesys_Device * dev)
/* we don't want top offset, but we need right margin to be the same
* than the one for the final scan */
status = setup_for_scan (dev, settings, SANE_TRUE, SANE_FALSE, SANE_FALSE);
/* used when sending shading calibration data */
dev->calib_pixels = settings.pixels;
@ -3413,6 +3415,13 @@ gl646_init_regs_for_shading (Genesys_Device * dev)
memcpy (dev->calib_reg, dev->reg,
GENESYS_GL646_MAX_REGS * sizeof (Genesys_Register_Set));
/* 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 = dev->settings.xres;
DBG (DBG_info,
"gl646_init_register_for_shading:\n\tdev->settings.xres=%d\n\tdev->settings.yres=%d\n",dev->settings.xres,dev->settings.yres);
DBG (DBG_proc, "gl646_init_register_for_shading: end\n");
return status;
}
@ -3789,11 +3798,15 @@ gl646_offset_calibration (Genesys_Device * dev)
/* resolution is the one from the final scan */
if (dev->settings.xres > dev->sensor.optical_res)
{
resolution = get_closest_resolution (dev->model->ccd_type, dev->sensor.optical_res, SANE_TRUE);
resolution =
get_closest_resolution (dev->model->ccd_type, dev->sensor.optical_res,
SANE_TRUE);
}
else
{
resolution = get_closest_resolution (dev->model->ccd_type, dev->settings.xres, SANE_TRUE);
resolution =
get_closest_resolution (dev->model->ccd_type, dev->settings.xres,
SANE_TRUE);
}
channels = 3;
black_pixels =
@ -3823,9 +3836,9 @@ gl646_offset_calibration (Genesys_Device * dev)
/* scan with no move */
if (dev->model->ccd_type == CIS_XP200)
bottom = 4;
bottom = 4;
else
bottom = 90;
bottom = 90;
dev->frontend.offset[0] = bottom;
dev->frontend.offset[1] = bottom;
dev->frontend.offset[2] = bottom;
@ -3849,9 +3862,9 @@ gl646_offset_calibration (Genesys_Device * dev)
/* now top value */
if (dev->model->ccd_type == CIS_XP200)
top=0x80;
top = 0x80;
else
top = 231;
top = 231;
dev->frontend.offset[0] = top;
dev->frontend.offset[1] = top;
dev->frontend.offset[2] = top;
@ -3963,16 +3976,19 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi)
/* setup for a RGB scan, one full sensor's width line */
/* resolution is the one from the final scan */
channels = 3;
/* XXX STEF XXX resolution = get_closest_resolution (dev->model->ccd_type, 150, SANE_TRUE); */
/* we are searching a sensor resolution */
if (dev->settings.xres > dev->sensor.optical_res)
{
resolution = get_closest_resolution (dev->model->ccd_type, dev->sensor.optical_res, SANE_TRUE);
resolution =
get_closest_resolution (dev->model->ccd_type, dev->sensor.optical_res,
SANE_TRUE);
}
else
{
resolution = get_closest_resolution (dev->model->ccd_type, dev->settings.xres, SANE_TRUE);
resolution =
get_closest_resolution (dev->model->ccd_type, dev->settings.xres,
SANE_TRUE);
}
settings.scan_method = SCAN_METHOD_FLATBED;
@ -4013,9 +4029,9 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi)
pass = 0;
/* loop until each channel raises to acceptable level */
while ((average[0] < dev->sensor.gain_white_ref)
|| (average[1] < dev->sensor.gain_white_ref)
|| (average[2] < dev->sensor.gain_white_ref))
while (((average[0] < dev->sensor.gain_white_ref)
|| (average[1] < dev->sensor.gain_white_ref)
|| (average[2] < dev->sensor.gain_white_ref)) && (pass < 30))
{
/* scan with no move */
status = simple_scan (dev, settings, SANE_FALSE, &line);
@ -4034,6 +4050,7 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi)
channels, settings.pixels,
settings.lines);
}
pass++;
/* average high level for each channel and compute gain
to reach the target code
@ -4494,7 +4511,7 @@ gl646_init (Genesys_Device * dev)
#ifdef SANE_STATUS_HW_LOCKED
return SANE_STATUS_HW_LOCKED;
#else
return SANE_STATUS_JAMMED;
return SANE_STATUS_JAMMED;
#endif
}
else
@ -4547,13 +4564,13 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move,
/* allocate memory fo scan : LINCNT may have been adjusted for CCD reordering */
if (dev->model->is_cis == SANE_TRUE)
{
lines = gl646_get_triple_reg (dev->reg, REG_LINCNT) / 3;
}
{
lines = gl646_get_triple_reg (dev->reg, REG_LINCNT) / 3;
}
else
{
lines = gl646_get_triple_reg (dev->reg, REG_LINCNT) + 1;
}
{
lines = gl646_get_triple_reg (dev->reg, REG_LINCNT) + 1;
}
size = lines * settings.pixels;
if (settings.depth == 16)
bpp = 2;
@ -4894,6 +4911,57 @@ write_control (Genesys_Device * dev, int resolution)
return status;
}
/**
* check if a stored calibration is compatible with requested scan.
* @return SANE_STATUS_GOOD if compatible, SANE_STATUS_UNSUPPORTED if not.
* Whenever an error is met, it is returned.
* @param dev scanner device
* @param cache cache entry to test
* @for_overwrite reserved for future use ...
*/
static SANE_Status
gl646_is_compatible_calibration (Genesys_Device * dev,
Genesys_Calibration_Cache * cache,
int for_overwrite)
{
SANE_Int channels;
DBG (DBG_proc, "gl646_is_compatible_calibration: start\n");
/* build minimal current_setup for calibration cache use only, it will be better
* computed when during setup for scan
*/
if (dev->settings.scan_mode == SCAN_MODE_COLOR)
{
dev->current_setup.channels = 3;
}
else
{
dev->current_setup.channels = 1;
}
dev->current_setup.xres = dev->settings.xres;
DBG (DBG_info,
"gl646_is_compatible_calibration:\n\tdev->settings.xres=%d\n\tdev->settings.yres=%d\n",dev->settings.xres,dev->settings.yres);
DBG (DBG_info,
"gl646_is_compatible_calibration:\n\tcache->used_setup.channels=%d\n\tcache->used_setup.xres=%f\n",
cache->used_setup.channels, cache->used_setup.xres);
DBG (DBG_info,
"gl646_is_compatible_calibration:\n\tdev->current_setup.channels=%d\n\tdev->current_setup.xres=%f\n",
dev->current_setup.channels, dev->current_setup.xres);
if ((dev->current_setup.channels != cache->used_setup.channels)
|| (dev->current_setup.xres != cache->used_setup.xres))
{
DBG (DBG_proc,
"gl646_is_compatible_calibration: completed, non compatible cache\n");
return SANE_STATUS_UNSUPPORTED;
}
DBG (DBG_proc,
"gl646_is_compatible_calibration: completed, cache compatible\n");
return SANE_STATUS_GOOD;
}
/** the gl646 command set */
static Genesys_Command_Set gl646_cmd_set = {
"gl646-generic", /* the name of this set */
@ -4943,7 +5011,7 @@ static Genesys_Command_Set gl646_cmd_set = {
gl646_detect_document_end,
gl646_eject_document,
NULL,/*is_compatible_calibration*/
gl646_is_compatible_calibration
};
SANE_Status