Merge branch 'genesys-canoscan-8600f' into 'master'

genesys: Preparation for infrared channel support on 8600F (part 2)

See merge request sane-project/backends!84
merge-requests/87/head
Povilas Kanapickas 2019-06-30 23:16:47 +00:00
commit 72d68c7367
11 zmienionych plików z 550 dodań i 368 usunięć

Wyświetl plik

@ -3026,32 +3026,24 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen
* search calibration cache list for an entry matching required scan.
* If one is found, set device calibration with it
* @param dev scanner's device
* @return SANE_STATUS_UNSUPPORTED if no matching cache entry has been
* found, SANE_STATUS_GOOD if one has been found and used.
* @return false if no matching cache entry has been
* found, true if one has been found and used.
*/
static SANE_Status
static bool
genesys_restore_calibration(Genesys_Device * dev, Genesys_Sensor& sensor)
{
// TODO: reindent
SANE_Status status;
DBGSTART;
/* if no cache or no function to evaluate cache entry ther can be no match */
if (!dev->model->cmd_set->is_compatible_calibration
|| dev->calibration_cache.empty())
return SANE_STATUS_UNSUPPORTED;
return false;
/* we walk the link list of calibration cache in search for a
* matching one */
for (auto& cache : dev->calibration_cache)
{
status = dev->model->cmd_set->is_compatible_calibration(dev, sensor, &cache, SANE_FALSE);
/* SANE_STATUS_GOOD, a matching cache has been found
* so we use it to populate calibration data
*/
if (status == SANE_STATUS_GOOD)
if (dev->model->cmd_set->is_compatible_calibration(dev, sensor, &cache, SANE_FALSE))
{
dev->frontend = cache.frontend;
/* we don't restore the gamma fields */
@ -3066,38 +3058,21 @@ genesys_restore_calibration(Genesys_Device * dev, Genesys_Sensor& sensor)
if(dev->model->cmd_set->send_shading_data==NULL)
{
status = genesys_send_shading_coefficient(dev, sensor);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to send shading calibration coefficients: %s\n",
__func__, sane_strstatus(status));
return status;
}
TIE(genesys_send_shading_coefficient(dev, sensor));
}
DBG(DBG_proc, "%s: restored\n", __func__);
return SANE_STATUS_GOOD;
}
/* here status is either SANE_STATUS_UNSUPPORTED which mean tested cache
* entry doesn't match, or an fatal error */
if (status != SANE_STATUS_UNSUPPORTED)
{
DBG(DBG_error, "%s: fail while checking compatibility: %s\n", __func__,
sane_strstatus(status));
return status;
return true;
}
}
DBG(DBG_proc, "%s: completed(nothing found)\n", __func__);
return SANE_STATUS_UNSUPPORTED;
return false;
}
static SANE_Status
genesys_save_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor)
{
SANE_Status status = SANE_STATUS_UNSUPPORTED;
#ifdef HAVE_SYS_TIME_H
struct timeval time;
#endif
@ -3111,19 +3086,11 @@ genesys_save_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor)
for (auto cache_it = dev->calibration_cache.begin(); cache_it != dev->calibration_cache.end();
cache_it++)
{
status = dev->model->cmd_set->is_compatible_calibration(dev, sensor, &*cache_it, SANE_TRUE);
if (status == SANE_STATUS_UNSUPPORTED)
if (dev->model->cmd_set->is_compatible_calibration(dev, sensor, &*cache_it, SANE_TRUE))
{
continue;
found_cache_it = cache_it;
break;
}
else if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: fail while checking compatibility: %s\n", __func__,
sane_strstatus(status));
return status;
}
found_cache_it = cache_it;
break;
}
/* if we found on overridable cache, we reuse it */
@ -3290,6 +3257,10 @@ genesys_flatbed_calibration(Genesys_Device * dev, Genesys_Sensor& sensor)
return status;
}
if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) {
RIE(dev->model->cmd_set->move_to_ta(dev));
}
/* shading calibration */
status = dev->model->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg);
if (status != SANE_STATUS_GOOD)
@ -3393,12 +3364,17 @@ static SANE_Status genesys_sheetfed_calibration(Genesys_Device * dev, Genesys_Se
/* the afe needs to sends valid data even before calibration */
/* go to a white area */
status = dev->model->cmd_set->search_strip(dev, sensor, forward, SANE_FALSE);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to find white strip: %s\n", __func__, sane_strstatus(status));
dev->model->cmd_set->eject_document (dev);
return status;
try {
status = dev->model->cmd_set->search_strip(dev, sensor, forward, SANE_FALSE);
if (status != SANE_STATUS_GOOD) {
DBG(DBG_error, "%s: failed to find white strip: %s\n", __func__,
sane_strstatus(status));
dev->model->cmd_set->eject_document (dev);
return status;
}
} catch (...) {
dev->model->cmd_set->eject_document(dev);
throw;
}
if (dev->model->is_cis)
@ -3455,13 +3431,18 @@ static SANE_Status genesys_sheetfed_calibration(Genesys_Device * dev, Genesys_Se
if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)
{
/* seek black/white reverse/forward */
status = dev->model->cmd_set->search_strip(dev, sensor, forward, SANE_TRUE);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to find black strip: %s\n", __func__, sane_strstatus(status));
dev->model->cmd_set->eject_document (dev);
return status;
}
try {
status = dev->model->cmd_set->search_strip(dev, sensor, forward, SANE_TRUE);
if (status != SANE_STATUS_GOOD) {
DBG(DBG_error, "%s: failed to find black strip: %s\n", __func__,
sane_strstatus(status));
dev->model->cmd_set->eject_document(dev);
return status;
}
} catch (...) {
dev->model->cmd_set->eject_document(dev);
throw;
}
status = dev->model->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg);
if (status != SANE_STATUS_GOOD)
@ -3470,25 +3451,34 @@ static SANE_Status genesys_sheetfed_calibration(Genesys_Device * dev, Genesys_Se
__func__, sane_strstatus(status));
return status;
}
status = genesys_dark_shading_calibration(dev, sensor);
if (status != SANE_STATUS_GOOD)
{
dev->model->cmd_set->eject_document (dev);
DBG(DBG_error, "%s: failed to do dark shading calibration: %s\n", __func__,
sane_strstatus(status));
return status;
}
try {
status = genesys_dark_shading_calibration(dev, sensor);
if (status != SANE_STATUS_GOOD) {
dev->model->cmd_set->eject_document(dev);
DBG(DBG_error, "%s: failed to do dark shading calibration: %s\n", __func__,
sane_strstatus(status));
return status;
}
} catch (...) {
dev->model->cmd_set->eject_document(dev);
throw;
}
forward = SANE_FALSE;
}
/* go to a white area */
status = dev->model->cmd_set->search_strip(dev, sensor, forward, SANE_FALSE);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to find white strip: %s\n", __func__, sane_strstatus(status));
dev->model->cmd_set->eject_document (dev);
return status;
try {
status = dev->model->cmd_set->search_strip(dev, sensor, forward, SANE_FALSE);
if (status != SANE_STATUS_GOOD) {
DBG(DBG_error, "%s: failed to find white strip: %s\n", __func__,
sane_strstatus(status));
dev->model->cmd_set->eject_document (dev);
return status;
}
} catch (...) {
dev->model->cmd_set->eject_document (dev);
throw;
}
status = dev->model->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg);
@ -3498,12 +3488,17 @@ static SANE_Status genesys_sheetfed_calibration(Genesys_Device * dev, Genesys_Se
sane_strstatus(status));
return status;
}
status = genesys_white_shading_calibration(dev, sensor);
if (status != SANE_STATUS_GOOD)
{
dev->model->cmd_set->eject_document (dev);
DBG(DBG_error, "%s: failed eject target: %s\n", __func__, sane_strstatus(status));
return status;
try {
status = genesys_white_shading_calibration(dev, sensor);
if (status != SANE_STATUS_GOOD) {
dev->model->cmd_set->eject_document(dev);
DBG(DBG_error, "%s: failed eject target: %s\n", __func__, sane_strstatus(status));
return status;
}
} catch (...) {
dev->model->cmd_set->eject_document (dev);
throw;
}
/* in case we haven't black shading data, build it from black pixels
@ -3642,11 +3637,14 @@ genesys_warmup_lamp (Genesys_Device * dev)
}
while (empty);
status = sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size);
if (status != SANE_STATUS_GOOD)
{
RIE(sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size));
}
try {
status = sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size);
if (status != SANE_STATUS_GOOD) {
RIE(sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size));
}
} catch (...) {
RIE(sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size));
}
RIE(dev->model->cmd_set->end_scan(dev, &dev->reg, SANE_TRUE));
@ -3853,8 +3851,7 @@ genesys_start_scan (Genesys_Device * dev, SANE_Bool lamp_off)
}
/* try to use cached calibration first */
status = genesys_restore_calibration (dev, sensor);
if (status == SANE_STATUS_UNSUPPORTED)
if (!genesys_restore_calibration (dev, sensor))
{
/* calibration : sheetfed scanners can't calibrate before each scan */
/* and also those who have the NO_CALIBRATION flag */
@ -3876,11 +3873,6 @@ genesys_start_scan (Genesys_Device * dev, SANE_Bool lamp_off)
DBG(DBG_warn, "%s: no calibration done\n", __func__);
}
}
else if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to restore calibration: %s\n", __func__, sane_strstatus(status));
return status;
}
/* build look up table for dynamic lineart */
if(dev->settings.dynamic_lineart==SANE_TRUE)
@ -3895,6 +3887,21 @@ genesys_start_scan (Genesys_Device * dev, SANE_Bool lamp_off)
}
}
if (dev->model->cmd_set->wait_for_motor_stop) {
dev->model->cmd_set->wait_for_motor_stop(dev);
}
if (dev->model->cmd_set->needs_home_before_init_regs_for_scan &&
dev->model->cmd_set->needs_home_before_init_regs_for_scan(dev) &&
dev->model->cmd_set->slow_back_home)
{
RIE(dev->model->cmd_set->slow_back_home(dev, SANE_TRUE));
}
if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) {
RIE(dev->model->cmd_set->move_to_ta(dev));
}
status = dev->model->cmd_set->init_regs_for_scan(dev, sensor);
if (status != SANE_STATUS_GOOD)
{
@ -4364,28 +4371,8 @@ genesys_read_ordered_data (Genesys_Device * dev, SANE_Byte * destination,
return SANE_STATUS_INVAL;
}
DBG(DBG_info, "%s: dumping current_setup:\n"
"\tpixels: %d\n"
"\tlines: %d\n"
"\tdepth: %d\n"
"\tchannels: %d\n"
"\texposure_time: %d\n"
"\txres: %g\n"
"\tyres: %g\n"
"\tccd_size_divisor: %d\n"
"\tstagger: %d\n"
"\tmax_shift: %d\n",
__func__,
dev->current_setup.pixels,
dev->current_setup.lines,
dev->current_setup.depth,
dev->current_setup.channels,
dev->current_setup.exposure_time,
dev->current_setup.xres,
dev->current_setup.yres,
dev->current_setup.ccd_size_divisor,
dev->current_setup.stagger, dev->current_setup.max_shift);
DBG(DBG_info, "%s: ", __func__);
debug_dump(DBG_info, dev->current_setup);
/* prepare conversion */
/* current settings */
@ -6161,11 +6148,12 @@ genesys_buffer_image(Genesys_Scanner *s)
{
len = read_size;
}
status = genesys_read_ordered_data(dev, dev->img_buffer.data() + total, &len);
if (status != SANE_STATUS_EOF && status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: %s buffering failed\n", __func__, sane_strstatus(status));
return status;
{
DBG(DBG_error, "%s: %s buffering failed\n", __func__, sane_strstatus(status));
return status;
}
total += len;
@ -6348,7 +6336,7 @@ SANE_Status sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_
SANE_Status
sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle)
{
Genesys_Device *dev;
Genesys_Device *dev = nullptr;
SANE_Status status;
char *tmpstr;
@ -6753,8 +6741,7 @@ get_option_value (Genesys_Scanner * s, int option, void *val)
*(SANE_Bool *) val = SANE_TRUE;
for (auto& cache : s->dev->calibration_cache)
{
if (s->dev->model->
cmd_set->is_compatible_calibration(s->dev, sensor, &cache, SANE_FALSE) == SANE_STATUS_GOOD)
if (s->dev->model->cmd_set->is_compatible_calibration(s->dev, sensor, &cache, SANE_FALSE))
{
*(SANE_Bool *) val = SANE_FALSE;
}

Wyświetl plik

@ -346,7 +346,7 @@ genesys_crop(Genesys_Scanner *s)
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_info, "%s: bad or no edges, bailing\n", __func__);
goto cleanup;
return SANE_STATUS_GOOD;
}
DBG (DBG_io, "%s: t:%d b:%d l:%d r:%d\n", __func__, top, bottom, left,
right);
@ -357,13 +357,12 @@ genesys_crop(Genesys_Scanner *s)
if (status)
{
DBG (DBG_warn, "%s: failed to crop\n", __func__);
goto cleanup;
return SANE_STATUS_GOOD;
}
/* update counters to new image size */
dev->total_bytes_to_read = s->params.bytes_per_line * s->params.lines;
cleanup:
DBG (DBG_proc, "%s: completed\n", __func__);
return SANE_STATUS_GOOD;
}

Wyświetl plik

@ -1356,7 +1356,7 @@ void genesys_init_sensor_tables()
struct CustomSensorSettings {
int min_resolution;
int max_resolution;
int exposure;
int exposure_lperiod;
ScanMethod method;
GenesysRegisterSettingSet extra_custom_regs;
};
@ -1509,7 +1509,7 @@ void genesys_init_sensor_tables()
{
sensor.min_resolution = setting.min_resolution;
sensor.max_resolution = setting.max_resolution;
sensor.exposure_lperiod = setting.exposure;
sensor.exposure_lperiod = setting.exposure_lperiod;
sensor.method = setting.method;
sensor.custom_regs = base_custom_regs;
sensor.custom_regs.merge(setting.extra_custom_regs);
@ -1625,14 +1625,14 @@ void genesys_init_sensor_tables()
struct CustomSensorSettings {
int min_resolution;
int max_resolution;
int exposure;
int exposure_lperiod;
ScanMethod method;
GenesysRegisterSettingSet extra_custom_regs;
GenesysRegisterSettingSet custom_fe_regs;
};
CustomSensorSettings custom_settings[] = {
{ -1, 1200, 0x5dc0, ScanMethod::FLATBED, {
{ -1, 1200, 24000, ScanMethod::FLATBED, {
{ 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 },
{ 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 },
{ 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
@ -1661,7 +1661,7 @@ void genesys_init_sensor_tables()
},
{},
},
{ -1, 1200, 0x5dc0, ScanMethod::TRANSPARENCY, {
{ -1, 1200, 24000, ScanMethod::TRANSPARENCY, {
{ 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 },
{ 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 },
{ 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
@ -1690,7 +1690,7 @@ void genesys_init_sensor_tables()
},
{},
},
{ 2400, 2400, 0x5dc0, ScanMethod::TRANSPARENCY, {
{ 2400, 2400, 24000, ScanMethod::TRANSPARENCY, {
{ 0x74, 0x03 }, { 0x75, 0xfe }, { 0x76, 0x00 },
{ 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 },
{ 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
@ -1719,7 +1719,7 @@ void genesys_init_sensor_tables()
},
{},
},
{ 4800, 4800, 0x5dc0, ScanMethod::TRANSPARENCY, {
{ 4800, 4800, 24000, ScanMethod::TRANSPARENCY, {
{ 0x74, 0x03 }, { 0x75, 0xff }, { 0x76, 0xff },
{ 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff },
{ 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
@ -1759,7 +1759,7 @@ void genesys_init_sensor_tables()
sensor.min_resolution = setting.min_resolution;
sensor.max_resolution = setting.max_resolution;
sensor.method = setting.method;
sensor.exposure_lperiod = setting.exposure;
sensor.exposure_lperiod = setting.exposure_lperiod;
sensor.custom_regs = base_custom_regs;
sensor.custom_regs.merge(setting.extra_custom_regs);
sensor.custom_fe_regs = setting.custom_fe_regs;

Wyświetl plik

@ -1488,7 +1488,7 @@ gl124_init_scan_regs(Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys
return SANE_STATUS_GOOD;
}
static SANE_Status
static void
gl124_calculate_current_setup (Genesys_Device * dev, const Genesys_Sensor& sensor)
{
int channels;
@ -1597,7 +1597,6 @@ gl124_calculate_current_setup (Genesys_Device * dev, const Genesys_Sensor& senso
dev->current_setup.max_shift = max_shift + stagger;
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
/**
@ -2003,14 +2002,27 @@ gl124_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
RIE(gl124_setup_scan_gpio(dev,resolution));
status = gl124_start_action (dev);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
gl124_stop_action (dev);
/* restore original registers */
dev->model->cmd_set->bulk_write_register(dev, dev->reg);
return status;
try {
status = gl124_start_action (dev);
} catch (...) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl124_stop_action (dev);
} catch (...) {}
try {
// restore original registers
dev->model->cmd_set->bulk_write_register(dev, dev->reg);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl124_stop_action (dev);
} catch (...) {}
/* restore original registers */
dev->model->cmd_set->bulk_write_register(dev, dev->reg);
return status;
}
/* post scan gpio : without that HOMSNR is unreliable */
@ -2407,6 +2419,25 @@ gl124_init_regs_for_shading(Genesys_Device * dev, const Genesys_Sensor& sensor,
return SANE_STATUS_GOOD;
}
static void gl124_wait_for_motor_stop(Genesys_Device* dev)
{
DBG_HELPER(dbg);
uint8_t val40, val;
TIE(sanei_genesys_get_status(dev, &val));
TIE(sanei_genesys_read_register(dev, REG100, &val40));
if ((val & MOTORENB) == 0 && (val40 & REG100_MOTMFLG) == 0)
return;
do {
sanei_genesys_sleep_ms(10);
TIE(sanei_genesys_get_status(dev, &val));
TIE(sanei_genesys_read_register(dev, REG100, &val40));
} while ((val & MOTORENB) ||(val40 & REG100_MOTMFLG));
sanei_genesys_sleep_ms(50);
}
/** @brief set up registers for the actual scan
*/
static SANE_Status
@ -2418,54 +2449,12 @@ gl124_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor)
float move;
int move_dpi;
float start;
uint8_t val40,val;
SANE_Status status;
DBG(DBG_info, "%s ", __func__);
debug_dump(DBG_info, dev->settings);
/* wait for motor to stop first */
status = sanei_genesys_get_status (dev, &val);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "%s: failed to read status: %s\n", __func__, sane_strstatus (status));
DBGCOMPLETED;
return status;
}
status = sanei_genesys_read_register (dev, REG100, &val40);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "%s: failed to read reg100: %s\n", __func__, sane_strstatus (status));
DBGCOMPLETED;
return status;
}
if((val & MOTORENB) || (val40 & REG100_MOTMFLG))
{
do
{
sanei_genesys_sleep_ms(10);
status = sanei_genesys_get_status (dev, &val);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "%s: failed to read status: %s\n", __func__, sane_strstatus (status));
DBGCOMPLETED;
return status;
}
status = sanei_genesys_read_register (dev, REG100, &val40);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "%s: failed to read reg100: %s\n", __func__, sane_strstatus (status));
DBGCOMPLETED;
return status;
}
} while ((val & MOTORENB) || (val40 & REG100_MOTMFLG));
sanei_genesys_sleep_ms(50);
}
/* ensure head is parked in case of calibration */
RIE (gl124_slow_back_home (dev, SANE_TRUE));
/* channels */
if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS)
channels = 3;
@ -3153,7 +3142,14 @@ gl124_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
SCAN_FLAG_SINGLE_LINE |
SCAN_FLAG_IGNORE_LINE_DISTANCE;
status = gl124_init_scan_regs(dev, sensor, &regs, params);
try {
status = gl124_init_scan_regs(dev, sensor, &regs, params);
} catch (...) {
try {
sanei_genesys_set_motor_power(regs, false);
} catch (...) {}
throw;
}
sanei_genesys_set_motor_power(regs, false);
@ -3174,7 +3170,7 @@ gl124_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), total_size));
if (DBG_LEVEL >= DBG_data)
sanei_genesys_write_pnm_file("gl124_coarse.pnm", line.data(), bpp, channels, pixels, lines);
sanei_genesys_write_pnm_file("gl124_gain.pnm", line.data(), bpp, channels, pixels, lines);
/* average value on each channel */
for (j = 0; j < channels; j++)
@ -3534,6 +3530,8 @@ gl124_update_hardware_sensors (Genesys_Scanner * s)
static Genesys_Command_Set gl124_cmd_set = {
"gl124-generic", /* the name of this set */
[](Genesys_Device* dev) -> bool { (void) dev; return true; },
gl124_init,
gl124_init_regs_for_warmup,
gl124_init_regs_for_coarse_calibration,
@ -3563,6 +3561,7 @@ static Genesys_Command_Set gl124_cmd_set = {
gl124_coarse_gain_calibration,
gl124_led_calibration,
gl124_wait_for_motor_stop,
gl124_slow_back_home,
gl124_rewind,

Wyświetl plik

@ -93,12 +93,14 @@ static SANE_Status
gl646_bulk_read_data (Genesys_Device * dev, uint8_t addr,
uint8_t * data, size_t len)
{
SANE_Status status = sanei_genesys_bulk_read_data(dev, addr, data, len);
if (status == SANE_STATUS_GOOD && dev->model->is_sheetfed == SANE_TRUE)
{
gl646_detect_document_end (dev);
SANE_Status status = sanei_genesys_bulk_read_data(dev, addr, data, len);
if (status != SANE_STATUS_GOOD) {
return status;
}
return status;
if (dev->model->is_sheetfed == SANE_TRUE) {
gl646_detect_document_end (dev);
}
return status;
}
static SANE_Bool
@ -1854,8 +1856,10 @@ gl646_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ )
local_reg.find_reg(0x39).value = exposure_time & 255;
status = sanei_genesys_bulk_write_register(dev, local_reg);
if (status != SANE_STATUS_GOOD)
if (status != SANE_STATUS_GOOD) {
DBG(DBG_error, "%s: Failed to bulk write registers: %s\n", __func__, sane_strstatus(status));
return status;
}
DBG(DBG_proc, "%s: end\n", __func__);
return status;
@ -2229,12 +2233,12 @@ gl646_eject_document (Genesys_Device * dev)
do
{
status = sanei_genesys_get_status (dev, &state);
print_status (state);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to read status: %s\n", __func__, sane_strstatus(status));
return status;
}
print_status (state);
sanei_genesys_sleep_ms(200);
count++;
}
@ -2532,7 +2536,11 @@ gl646_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
}
/* write scan registers */
status = sanei_genesys_bulk_write_register(dev, dev->reg);
try {
status = sanei_genesys_bulk_write_register(dev, dev->reg);
} catch (...) {
DBG(DBG_error, "%s: failed to bulk write registers\n", __func__);
}
if (status != SANE_STATUS_GOOD)
DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status));
@ -2631,38 +2639,36 @@ gl646_search_start_position (Genesys_Device * dev)
status = simple_scan(dev, sensor, settings, SANE_TRUE, SANE_TRUE, SANE_FALSE, data);
/* process data if scan is OK */
if (status == SANE_STATUS_GOOD)
{
/* handle stagger case : reorder gray data and thus loose some lines */
if (dev->current_setup.stagger > 0)
{
DBG(DBG_proc, "%s: 'un-staggering'\n", __func__);
for (y = 0; y < settings.lines - dev->current_setup.stagger; y++)
{
/* one point out of 2 is 'unaligned' */
for (x = 0; x < settings.pixels; x += 2)
{
data[y * settings.pixels + x] =
data[(y + dev->current_setup.stagger) * settings.pixels +
x];
}
}
/* correct line number */
settings.lines -= dev->current_setup.stagger;
}
if (DBG_LEVEL >= DBG_data)
{
sanei_genesys_write_pnm_file("gl646_search_position.pnm", data.data(), settings.depth, 1,
settings.pixels, settings.lines);
}
}
else
{
DBG(DBG_error, "%s: simple_scan failed\n", __func__);
DBGCOMPLETED;
return status;
if (status != SANE_STATUS_GOOD) {
DBG(DBG_error, "%s: simple_scan failed\n", __func__);
DBGCOMPLETED;
return status;
}
/* handle stagger case : reorder gray data and thus loose some lines */
if (dev->current_setup.stagger > 0)
{
DBG(DBG_proc, "%s: 'un-staggering'\n", __func__);
for (y = 0; y < settings.lines - dev->current_setup.stagger; y++)
{
/* one point out of 2 is 'unaligned' */
for (x = 0; x < settings.pixels; x += 2)
{
data[y * settings.pixels + x] =
data[(y + dev->current_setup.stagger) * settings.pixels +
x];
}
}
/* correct line number */
settings.lines -= dev->current_setup.stagger;
}
if (DBG_LEVEL >= DBG_data)
{
sanei_genesys_write_pnm_file("gl646_search_position.pnm", data.data(), settings.depth, 1,
settings.pixels, settings.lines);
}
/* now search reference points on the data */
status =
sanei_genesys_search_reference_point (dev, sensor, data.data(),
@ -2807,6 +2813,11 @@ gl646_init_regs_for_shading(Genesys_Device * dev, const Genesys_Sensor& sensor,
return status;
}
static bool gl646_needs_home_before_init_regs_for_scan(Genesys_Device* dev)
{
return (dev->scanhead_position_in_steps > 0 &&
dev->settings.scan_method == ScanMethod::FLATBED);
}
/**
* set up registers for the actual scan. The scan's parameters are given
@ -2819,14 +2830,6 @@ gl646_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor)
DBGSTART;
/* park head after calibration if needed */
if (dev->scanhead_position_in_steps > 0
&& dev->settings.scan_method == ScanMethod::FLATBED)
{
RIE(gl646_slow_back_home (dev, SANE_TRUE));
dev->scanhead_position_in_steps = 0;
}
RIE(setup_for_scan(dev, sensor, &dev->reg, dev->settings, SANE_FALSE, SANE_TRUE, SANE_TRUE));
/* gamma is only enabled at final scan time */
@ -3576,7 +3579,7 @@ ad_fe_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
/* log scanning data */
if (DBG_LEVEL >= DBG_data)
{
sprintf (title, "gl646_alternative_coarse%02d.pnm", (int)pass);
sprintf (title, "gl646_alternative_gain%02d.pnm", (int)pass);
sanei_genesys_write_pnm_file(title, line.data(), 8, channels, settings.pixels,
settings.lines);
}
@ -3718,7 +3721,7 @@ gl646_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
/* log scanning data */
if (DBG_LEVEL >= DBG_data)
{
sprintf (title, "gl646_coarse_gain%02d.pnm", (int)pass);
sprintf (title, "gl646_gain%02d.pnm", (int)pass);
sanei_genesys_write_pnm_file(title, line.data(), 8, channels, settings.pixels,
settings.lines);
}
@ -4041,6 +4044,7 @@ gl646_init (Genesys_Device * dev)
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: GPO enable failed ... %s\n", __func__, sane_strstatus(status));
return status;
}
val = 0;
@ -4049,6 +4053,7 @@ gl646_init (Genesys_Device * dev)
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: GPO write failed ... %s\n", __func__, sane_strstatus(status));
return status;
}
/* clear GPIO enable */
@ -4056,6 +4061,7 @@ gl646_init (Genesys_Device * dev)
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: GPO disable failed ... %s\n", __func__, sane_strstatus(status));
return status;
}
sanei_genesys_write_register (dev, 0x66, 0x10);
sanei_genesys_write_register (dev, 0x66, 0x00);
@ -4132,11 +4138,7 @@ gl646_init (Genesys_Device * dev)
{
DBG(DBG_error0, "Your scanner is locked. Please move the lock switch to the "
"unlocked position\n");
#ifdef SANE_STATUS_HW_LOCKED
return SANE_STATUS_HW_LOCKED;
#else
return SANE_STATUS_JAMMED;
#endif
}
else
DBG(DBG_error, "%s: gl646_repark_head failed: %s\n", __func__,
@ -4648,13 +4650,13 @@ write_control (Genesys_Device * dev, const Genesys_Sensor& sensor, int resolutio
/**
* check if a stored calibration is compatible with requested scan.
* @return SANE_STATUS_GOOD if compatible, SANE_STATUS_UNSUPPORTED if not.
* @return true if compatible, false if not.
* Whenever an error is met, it is returned.
* @param dev scanner device
* @param cache cache entry to test
* @param for_overwrite reserved for future use ...
*/
static SANE_Status
static bool
gl646_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor,
Genesys_Calibration_Cache * cache,
int for_overwrite)
@ -4668,7 +4670,7 @@ gl646_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sen
DBG(DBG_proc, "%s: start (for_overwrite=%d)\n", __func__, for_overwrite);
if (cache == NULL)
return SANE_STATUS_UNSUPPORTED;
return false;
/* build minimal current_setup for calibration cache use only, it will be better
* computed when during setup for scan
@ -4710,7 +4712,7 @@ gl646_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sen
if (!compatible)
{
DBG(DBG_proc, "%s: completed, non compatible cache\n", __func__);
return SANE_STATUS_UNSUPPORTED;
return false;
}
/* a cache entry expires after 30 minutes for non sheetfed scanners */
@ -4723,13 +4725,13 @@ gl646_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sen
&& (dev->model->is_sheetfed == SANE_FALSE))
{
DBG(DBG_proc, "%s: expired entry, non compatible cache\n", __func__);
return SANE_STATUS_UNSUPPORTED;
return false;
}
}
#endif
DBG(DBG_proc, "%s: completed, cache compatible\n", __func__);
return SANE_STATUS_GOOD;
return true;
}
/**
@ -4902,6 +4904,8 @@ gl646_search_strip(Genesys_Device * dev, const Genesys_Sensor& sensor, SANE_Bool
static Genesys_Command_Set gl646_cmd_set = {
"gl646-generic", /* the name of this set */
gl646_needs_home_before_init_regs_for_scan,
gl646_init,
gl646_init_regs_for_warmup,
gl646_init_regs_for_coarse_calibration,
@ -4931,6 +4935,7 @@ static Genesys_Command_Set gl646_cmd_set = {
gl646_coarse_gain_calibration,
gl646_led_calibration,
NULL,
gl646_slow_back_home,
NULL,

Wyświetl plik

@ -1031,22 +1031,6 @@ gl841_set_fe(Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set)
{
DBG(DBG_error, "%s: reset fe failed: %s\n", __func__, sane_strstatus(status));
return status;
/*
if (dev->model->ccd_type == CCD_HP2300
|| dev->model->ccd_type == CCD_HP2400)
{
val = 0x07;
status =
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT,
REQUEST_REGISTER, GPIO_OUTPUT_ENABLE,
INDEX, 1, &val);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s failed resetting frontend: %s\n", __func__,
sane_strstatus(status));
return status;
}
}*/
}
DBG(DBG_proc, "%s(): frontend reset complete\n", __func__);
}
@ -1055,8 +1039,10 @@ gl841_set_fe(Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set)
if (set == AFE_POWER_SAVE)
{
status = sanei_genesys_fe_write_data (dev, 0x01, 0x02);
if (status != SANE_STATUS_GOOD)
if (status != SANE_STATUS_GOOD) {
DBG(DBG_error, "%s: writing data failed: %s\n", __func__, sane_strstatus(status));
return status;
}
return status;
}
@ -2487,7 +2473,7 @@ dummy \ scanned lines
return SANE_STATUS_GOOD;
}
static SANE_Status gl841_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor)
static void gl841_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor)
{
int channels;
int depth;
@ -2679,7 +2665,6 @@ dummy \ scanned lines
dev->current_setup.max_shift = max_shift + stagger;
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
/*for fast power saving methods only, like disabling certain amplifiers*/
@ -3010,8 +2995,21 @@ gl841_eject_document (Genesys_Device * dev)
return status;
}
status = gl841_start_action (dev);
if (status != SANE_STATUS_GOOD)
try {
status = gl841_start_action (dev);
} catch (...) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl841_stop_action(dev);
} catch (...) {}
try {
// restore original registers
sanei_genesys_bulk_write_register(dev, dev->reg);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
gl841_stop_action (dev);
@ -3170,8 +3168,15 @@ gl841_detect_document_end (Genesys_Device * dev)
* might have been slow to read data, so we re-evaluate the
* amount of data to scan form the hardware settings
*/
status=sanei_genesys_read_scancnt(dev,&scancnt);
if(status!=SANE_STATUS_GOOD)
try {
status = sanei_genesys_read_scancnt(dev, &scancnt);
} catch (...) {
dev->total_bytes_to_read = dev->total_bytes_read;
dev->read_bytes_left = 0;
throw;
}
if(status!=SANE_STATUS_GOOD)
{
dev->total_bytes_to_read = dev->total_bytes_read;
dev->read_bytes_left = 0;
@ -3327,7 +3332,20 @@ gl841_feed (Genesys_Device * dev, int steps)
return status;
}
status = gl841_start_action (dev);
try {
status = gl841_start_action (dev);
} catch (...) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl841_stop_action (dev);
} catch (...) {}
try {
// send original registers
sanei_genesys_bulk_write_register(dev, dev->reg);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
@ -3462,7 +3480,19 @@ gl841_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
RIE (sanei_genesys_bulk_write_register(dev, local_reg));
status = gl841_start_action (dev);
try {
status = gl841_start_action (dev);
} catch (...) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl841_stop_action(dev);
} catch (...) {}
try {
sanei_genesys_bulk_write_register(dev, dev->reg);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
@ -3777,8 +3807,6 @@ gl841_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor)
DBG(DBG_info, "%s ", __func__);
debug_dump(DBG_info, dev->settings);
gl841_slow_back_home(dev,SANE_TRUE);
/* channels */
if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS)
channels = 3;
@ -4728,7 +4756,7 @@ gl841_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), total_size));
if (DBG_LEVEL >= DBG_data)
sanei_genesys_write_pnm_file("gl841_coarse.pnm", line.data(), 16, channels, num_pixels, lines);
sanei_genesys_write_pnm_file("gl841_gain.pnm", line.data(), 16, channels, num_pixels, lines);
/* average high level for each channel and compute gain
to reach the target code
@ -4790,11 +4818,7 @@ gl841_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
DBG (DBG_error0, "**** ****\n");
DBG (DBG_error0, "**********************************************\n");
DBG (DBG_error0, "**********************************************\n");
#ifdef SANE_STATUS_HW_LOCKED
return SANE_STATUS_HW_LOCKED;
#else
return SANE_STATUS_JAMMED;
#endif
}
}
@ -4921,12 +4945,11 @@ sanei_gl841_repark_head (Genesys_Device * dev)
return status;
}
static SANE_Status
static bool
gl841_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor,
Genesys_Calibration_Cache *cache,
int for_overwrite)
{
SANE_Status status;
#ifdef HAVE_SYS_TIME_H
struct timeval time;
#endif
@ -4936,22 +4959,15 @@ gl841_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sen
/* calibration cache not working yet for this model */
if (dev->model->ccd_type == CCD_PLUSTEK_3600)
{
return SANE_STATUS_UNSUPPORTED;
return false;
}
status = gl841_calculate_current_setup (dev, sensor);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to calculate current setup: %s\n", __func__,
sane_strstatus(status));
return status;
}
gl841_calculate_current_setup (dev, sensor);
DBG(DBG_proc, "%s: checking\n", __func__);
if (dev->current_setup.ccd_size_divisor != cache->used_setup.ccd_size_divisor)
return SANE_STATUS_UNSUPPORTED;
return false;
/* a cache entry expires after 30 minutes for non sheetfed scanners */
/* this is not taken into account when overwriting cache entries */
@ -4963,13 +4979,13 @@ gl841_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sen
&& (dev->model->is_sheetfed == SANE_FALSE))
{
DBG(DBG_proc, "%s: expired entry, non compatible cache\n", __func__);
return SANE_STATUS_UNSUPPORTED;
return false;
}
}
#endif
DBGCOMPLETED;
return SANE_STATUS_GOOD;
return true;
}
/*
@ -5547,6 +5563,8 @@ gl841_send_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor,
static Genesys_Command_Set gl841_cmd_set = {
"gl841-generic", /* the name of this set */
[](Genesys_Device* dev) -> bool { (void) dev; return true; },
gl841_init,
gl841_init_regs_for_warmup,
gl841_init_regs_for_coarse_calibration,
@ -5576,6 +5594,7 @@ static Genesys_Command_Set gl841_cmd_set = {
gl841_coarse_gain_calibration,
gl841_led_calibration,
NULL,
gl841_slow_back_home,
NULL,

Wyświetl plik

@ -1106,11 +1106,7 @@ gl843_init_optical_regs_scan (Genesys_Device * dev,
depth, ccd_size_divisor, flags);
/* tgtime */
tgtime=1;
if (dev->model->ccd_type == CCD_G4050 && used_res>2400)
{
tgtime=2;
}
tgtime = exposure / 65536 + 1;
DBG(DBG_io2, "%s: tgtime=%d\n", __func__, tgtime);
/* to manage high resolution device while keeping good
@ -1129,7 +1125,7 @@ gl843_init_optical_regs_scan (Genesys_Device * dev,
dpiset = used_res * cksel;
/* start and end coordinate in optical dpi coordinates */
startx = (start + sensor.dummy_pixel * tgtime)/cksel;
startx = (start + sensor.dummy_pixel)/cksel;
used_pixels=pixels/cksel;
endx = startx + used_pixels;
@ -1267,8 +1263,8 @@ gl843_init_optical_regs_scan (Genesys_Device * dev,
sanei_genesys_set_double(reg, REG_DPISET, dpiset * ccd_size_divisor);
DBG(DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset * ccd_size_divisor);
sanei_genesys_set_double(reg,REG_STRPIXEL,startx/tgtime);
sanei_genesys_set_double(reg,REG_ENDPIXEL,endx/tgtime);
sanei_genesys_set_double(reg, REG_STRPIXEL, startx);
sanei_genesys_set_double(reg, REG_ENDPIXEL, endx);
/* words(16bit) before gamma, conversion to 8 bit or lineart */
words_per_line = (used_pixels * dpiset) / dpihw;
@ -1303,7 +1299,7 @@ gl843_init_optical_regs_scan (Genesys_Device * dev,
DBG(DBG_io2, "%s: exposure used=%d\n", __func__, exposure/tgtime);
r = sanei_genesys_get_address (reg, REG_DUMMY);
r->value = sensor.dummy_pixel * tgtime;
r->value = sensor.dummy_pixel;
DBGCOMPLETED;
return SANE_STATUS_GOOD;
@ -1616,7 +1612,7 @@ static SANE_Status gl843_init_scan_regs(Genesys_Device* dev, const Genesys_Senso
return SANE_STATUS_GOOD;
}
static SANE_Status
static void
gl843_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor)
{
int channels;
@ -1743,7 +1739,6 @@ gl843_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor
dev->current_setup.max_shift = max_shift + stagger;
DBG(DBG_proc, "%s: completed\n", __func__);
return SANE_STATUS_GOOD;
}
/**
@ -1949,7 +1944,11 @@ gl843_detect_document_end (Genesys_Device * dev)
DBG(DBG_io, "%s: read_bytes_left=%d\n", __func__, read_bytes_left);
/* get lines read */
status = sanei_genesys_read_scancnt (dev, &scancnt);
try {
status = sanei_genesys_read_scancnt(dev, &scancnt);
} catch (...) {
flines = 0;
}
if (status != SANE_STATUS_GOOD)
{
flines = 0;
@ -2331,7 +2330,19 @@ static SANE_Status gl843_park_xpa_lamp (Genesys_Device * dev)
/* write to scanner and start action */
RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg));
RIE(gl843_set_xpa_motor_power(dev, true));
status = gl843_start_action (dev);
try {
status = gl843_start_action (dev);
} catch (...) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl843_stop_action(dev);
} catch (...) {}
try {
// restore original registers
dev->model->cmd_set->bulk_write_register(dev, dev->reg);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
@ -2465,7 +2476,19 @@ gl843_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg));
status = gl843_start_action (dev);
try {
status = gl843_start_action (dev);
} catch (...) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl843_stop_action(dev);
} catch (...) {}
try {
// restore original registers
dev->model->cmd_set->bulk_write_register(dev, dev->reg);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
@ -2748,7 +2771,19 @@ gl843_feed (Genesys_Device * dev, unsigned int steps)
/* send registers */
RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg));
status = gl843_start_action (dev);
try {
status = gl843_start_action (dev);
} catch (...) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl843_stop_action(dev);
} catch (...) {}
try {
// restore original registers
dev->model->cmd_set->bulk_write_register(dev, dev->reg);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
@ -2833,9 +2868,8 @@ gl843_init_regs_for_shading(Genesys_Device * dev, const Genesys_Sensor& sensor,
if (dev->settings.scan_method == ScanMethod::TRANSPARENCY)
{
// FIXME: we should handle moving to TA in the caller, this function should only setup the
// registers.
gl843_move_to_ta(dev);
// note: move_to_ta() function has already been called and the sensor is at the
// transparency adapter
move = 0; // already at dev->model->y_offset_calib_ta implicitly
flags |= SCAN_FLAG_USE_XPA;
}
@ -2904,9 +2938,6 @@ gl843_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor)
DBG(DBG_info, "%s ", __func__);
debug_dump(DBG_info, dev->settings);
/* ensure head is parked in case of calibration */
gl843_slow_back_home (dev, SANE_TRUE);
/* channels */
if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS)
channels = 3;
@ -2923,9 +2954,8 @@ gl843_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor)
flags = 0;
if (dev->settings.scan_method == ScanMethod::TRANSPARENCY)
{
// FIXME: we should handle moving to TA in the caller, this function should only setup the
// registers.
gl843_move_to_ta(dev);
// note: move_to_ta() function has already been called and the sensor is at the
// transparency adapter
move = SANE_UNFIX(dev->model->y_offset_ta) - SANE_UNFIX(dev->model->y_offset_calib_ta);
flags |= SCAN_FLAG_USE_XPA;
}
@ -3555,7 +3585,15 @@ gl843_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
gl843_compute_session(dev, session, calib_sensor);
pixels = session.output_pixels;
status = gl843_init_scan_regs(dev, calib_sensor, &regs, session);
try {
status = gl843_init_scan_regs(dev, calib_sensor, &regs, session);
} catch (...) {
try {
sanei_genesys_set_motor_power(regs, false);
} catch (...) {}
throw;
}
sanei_genesys_set_motor_power(regs, false);
if (status != SANE_STATUS_GOOD)
@ -3576,7 +3614,7 @@ gl843_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
RIE(gl843_stop_action_no_move(dev, &regs));
if (DBG_LEVEL >= DBG_data)
sanei_genesys_write_pnm_file("gl843_coarse.pnm", line.data(), bpp, channels, pixels, lines);
sanei_genesys_write_pnm_file("gl843_gain.pnm", line.data(), bpp, channels, pixels, lines);
/* average value on each channel */
for (j = 0; j < channels; j++)
@ -4230,7 +4268,6 @@ gl843_send_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor,
uint32_t final_size, length, i;
uint8_t *buffer;
int count,offset;
unsigned int tgtime;
unsigned int cksel;
GenesysRegister *r;
uint16_t dpiset, strpixel, endpixel, startx, factor;
@ -4247,22 +4284,15 @@ gl843_send_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor,
r = sanei_genesys_get_address(&dev->reg, REG18);
cksel= (r->value & REG18_CKSEL)+1;
sanei_genesys_get_double(&dev->reg,REG_DPISET,&strpixel);
tgtime=1;
sanei_genesys_get_double(&dev->reg,REG_DPISET,&dpiset);
factor=sensor.optical_res/sanei_genesys_compute_dpihw(dev, sensor, dpiset);
if (dev->model->ccd_type == CCD_G4050 && dpiset>2400)
{
tgtime=2;
}
/* start coordinate in optical dpi coordinates */
startx = ((sensor.dummy_pixel * tgtime)/cksel)/factor;
startx = (sensor.dummy_pixel / cksel) / factor;
/* current scan coordinates */
sanei_genesys_get_double(&dev->reg,REG_STRPIXEL,&strpixel);
sanei_genesys_get_double(&dev->reg,REG_ENDPIXEL,&endpixel);
strpixel*=tgtime;
endpixel*=tgtime;
if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F)
{
@ -4324,6 +4354,8 @@ gl843_send_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor,
static Genesys_Command_Set gl843_cmd_set = {
"gl843-generic", /* the name of this set */
[](Genesys_Device* dev) -> bool { (void) dev; return true; },
gl843_init,
gl843_init_regs_for_warmup,
gl843_init_regs_for_coarse_calibration,
@ -4353,6 +4385,7 @@ static Genesys_Command_Set gl843_cmd_set = {
gl843_coarse_gain_calibration,
gl843_led_calibration,
NULL,
gl843_slow_back_home,
NULL,

Wyświetl plik

@ -1337,7 +1337,7 @@ gl846_init_scan_regs(Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys
return SANE_STATUS_GOOD;
}
static SANE_Status
static void
gl846_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor)
{
int channels;
@ -1454,7 +1454,6 @@ gl846_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor
dev->current_setup.max_shift = max_shift + stagger;
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
/*for fast power saving methods only, like disabling certain amplifiers*/
@ -1732,7 +1731,19 @@ gl846_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg));
status = gl846_start_action (dev);
try {
status = gl846_start_action(dev);
} catch (...) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl846_stop_action(dev);
} catch (...) {}
try {
// restore original registers
dev->model->cmd_set->bulk_write_register(dev, dev->reg);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
@ -2017,7 +2028,19 @@ gl846_feed (Genesys_Device * dev, unsigned int steps)
/* send registers */
RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg));
status = gl846_start_action (dev);
try {
status = gl846_start_action (dev);
} catch (...) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl846_stop_action(dev);
} catch (...) {}
try {
// restore original registers
dev->model->cmd_set->bulk_write_register(dev, dev->reg);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
@ -3226,9 +3249,14 @@ gl846_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
SCAN_FLAG_SINGLE_LINE |
SCAN_FLAG_IGNORE_LINE_DISTANCE;
status = gl846_init_scan_regs(dev, sensor, &regs, params);
sanei_genesys_set_motor_power(regs, false);
try {
status = gl846_init_scan_regs(dev, sensor, &regs, params);
} catch (...) {
try {
sanei_genesys_set_motor_power(regs, false);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD)
{
@ -3247,7 +3275,7 @@ gl846_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), total_size));
if (DBG_LEVEL >= DBG_data)
sanei_genesys_write_pnm_file("gl846_coarse.pnm", line.data(), bpp, channels, pixels, lines);
sanei_genesys_write_pnm_file("gl846_gain.pnm", line.data(), bpp, channels, pixels, lines);
/* average value on each channel */
for (j = 0; j < channels; j++)
@ -3304,6 +3332,8 @@ gl846_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
static Genesys_Command_Set gl846_cmd_set = {
"gl846-generic", /* the name of this set */
nullptr,
gl846_init,
NULL,
gl846_init_regs_for_coarse_calibration,
@ -3333,6 +3363,7 @@ static Genesys_Command_Set gl846_cmd_set = {
gl846_coarse_gain_calibration,
gl846_led_calibration,
NULL,
gl846_slow_back_home,
NULL,

Wyświetl plik

@ -1354,7 +1354,7 @@ gl847_init_scan_regs(Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys
return SANE_STATUS_GOOD;
}
static SANE_Status
static void
gl847_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor)
{
int channels;
@ -1472,7 +1472,6 @@ gl847_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor
dev->current_setup.max_shift = max_shift + stagger;
DBGCOMPLETED;
return SANE_STATUS_GOOD;
}
/*for fast power saving methods only, like disabling certain amplifiers*/
@ -1798,7 +1797,19 @@ gl847_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg));
status = gl847_start_action (dev);
try {
status = gl847_start_action (dev);
} catch (...) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl847_stop_action(dev);
} catch (...) {}
try {
// restore original registers
dev->model->cmd_set->bulk_write_register(dev, dev->reg);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
@ -2083,7 +2094,19 @@ gl847_feed (Genesys_Device * dev, unsigned int steps)
/* send registers */
RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg));
status = gl847_start_action (dev);
try {
status = gl847_start_action (dev);
} catch (...) {
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
try {
gl847_stop_action(dev);
} catch (...) {}
try {
// restore original registers
dev->model->cmd_set->bulk_write_register(dev, dev->reg);
} catch (...) {}
throw;
}
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status));
@ -3329,7 +3352,14 @@ gl847_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
SCAN_FLAG_SINGLE_LINE |
SCAN_FLAG_IGNORE_LINE_DISTANCE;
status = gl847_init_scan_regs(dev, sensor, &regs, params);
try {
status = gl847_init_scan_regs(dev, sensor, &regs, params);
} catch (...) {
try {
sanei_genesys_set_motor_power(regs, false);
} catch (...) {}
throw;
}
sanei_genesys_set_motor_power(regs, false);
@ -3350,7 +3380,7 @@ gl847_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), total_size));
if (DBG_LEVEL >= DBG_data)
sanei_genesys_write_pnm_file("gl847_coarse.pnm", line.data(), bpp, channels, pixels, lines);
sanei_genesys_write_pnm_file("gl847_gain.pnm", line.data(), bpp, channels, pixels, lines);
/* average value on each channel */
for (j = 0; j < channels; j++)
@ -3426,6 +3456,8 @@ gl847_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor
static Genesys_Command_Set gl847_cmd_set = {
"gl847-generic", /* the name of this set */
nullptr,
gl847_init,
NULL, /*gl847_init_regs_for_warmup*/
gl847_init_regs_for_coarse_calibration,
@ -3455,6 +3487,7 @@ static Genesys_Command_Set gl847_cmd_set = {
gl847_coarse_gain_calibration,
gl847_led_calibration,
NULL,
gl847_slow_back_home,
NULL, /* disable gl847_rewind, see #7 */

Wyświetl plik

@ -1189,7 +1189,7 @@ SANE_Status sanei_genesys_bulk_write_register(Genesys_Device * dev, Genesys_Regi
for (const auto& r : reg) {
status = sanei_genesys_write_register (dev, r.address, r.value);
if (status != SANE_STATUS_GOOD)
break;
return status;
}
}
@ -1870,33 +1870,23 @@ int sanei_genesys_get_lowest_dpi(Genesys_Device *dev)
* flatbed cache entries are considred too old and then expires if they
* are older than the expiration time option, forcing calibration at least once
* then given time. */
SANE_Status
sanei_genesys_is_compatible_calibration (Genesys_Device * dev,
const Genesys_Sensor& sensor,
Genesys_Calibration_Cache * cache,
int for_overwrite)
bool sanei_genesys_is_compatible_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor,
Genesys_Calibration_Cache * cache, int for_overwrite)
{
#ifdef HAVE_SYS_TIME_H
struct timeval time;
#endif
int compatible = 1, resolution;
SANE_Status status;
DBGSTART;
if(dev->model->cmd_set->calculate_current_setup==NULL)
{
DBG (DBG_proc, "%s: no calculate_setup, non compatible cache\n", __func__);
return SANE_STATUS_UNSUPPORTED;
return false;
}
status = dev->model->cmd_set->calculate_current_setup(dev, sensor);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "%s: failed to calculate current setup: %s\n", __func__,
sane_strstatus (status));
return status;
}
dev->model->cmd_set->calculate_current_setup(dev, sensor);
DBG (DBG_proc, "%s: checking\n", __func__);
@ -1933,7 +1923,7 @@ sanei_genesys_is_compatible_calibration (Genesys_Device * dev,
if (!compatible)
{
DBG (DBG_proc, "%s: completed, non compatible cache\n", __func__);
return SANE_STATUS_UNSUPPORTED;
return false;
}
/* a cache entry expires after afetr expiration time for non sheetfed scanners */
@ -1947,13 +1937,13 @@ sanei_genesys_is_compatible_calibration (Genesys_Device * dev,
&& (dev->settings.scan_method == ScanMethod::FLATBED))
{
DBG (DBG_proc, "%s: expired entry, non compatible cache\n", __func__);
return SANE_STATUS_UNSUPPORTED;
return false;
}
}
#endif
DBGCOMPLETED;
return SANE_STATUS_GOOD;
return true;
}
@ -2125,6 +2115,45 @@ void run_functions_at_backend_exit()
s_functions_run_at_backend_exit.release();
}
#if (defined(__GNUC__) || defined(__CLANG__)) && (defined(__linux__) || defined(__APPLE__))
extern "C" char* __cxa_get_globals();
#endif
static unsigned num_uncaught_exceptions()
{
#if __cplusplus >= 201703L
int count = std::uncaught_exceptions();
return count >= 0 ? count : 0;
#elif (defined(__GNUC__) || defined(__CLANG__)) && (defined(__linux__) || defined(__APPLE__))
// the format of the __cxa_eh_globals struct is enshrined into the Itanium C++ ABI and it's
// very unlikely we'll get issues referencing it directly
char* cxa_eh_globals_ptr = __cxa_get_globals();
return *reinterpret_cast<unsigned*>(cxa_eh_globals_ptr + sizeof(void*));
#else
return std::uncaught_exception() ? 1 : 0;
#endif
}
DebugMessageHelper::DebugMessageHelper(const char* func)
{
func_ = func;
num_exceptions_on_enter_ = num_uncaught_exceptions();
DBG(DBG_proc, "%s: start", func_);
}
DebugMessageHelper::~DebugMessageHelper()
{
if (num_exceptions_on_enter_ < num_uncaught_exceptions()) {
if (status_) {
DBG(DBG_error, "%s: failed during %s", func_, status_);
} else {
DBG(DBG_error, "%s: failed", func_);
}
} else {
DBG(DBG_proc, "%s: completed", func_);
}
}
void debug_dump(unsigned level, const Genesys_Settings& settings)
{
DBG(level, "settings:\n"
@ -2160,3 +2189,26 @@ void debug_dump(unsigned level, const SetupParams& params)
static_cast<unsigned>(params.color_filter),
params.flags);
}
void debug_dump(unsigned level, const Genesys_Current_Setup& setup)
{
DBG(level, "current_setup:\n"
"Pixels: %d\n"
"Lines: %d\n"
"Depth: %d\n"
"Channels: %d\n"
"exposure_time: %d\n"
"Resolution X/Y: %g %g\n"
"ccd_size_divisor: %d\n"
"stagger: %d\n"
"max_shift: %d\n",
setup.pixels,
setup.lines,
setup.depth,
setup.channels,
setup.exposure_time,
setup.xres, setup.yres,
setup.ccd_size_divisor,
setup.stagger,
setup.max_shift);
}

Wyświetl plik

@ -102,6 +102,16 @@
#define DBG_io2 7 /* io functions that are called very often */
#define DBG_data 8 /* log image data */
class SaneException : std::exception {
public:
SaneException(SANE_Status status) : status_(status) {}
SANE_Status status() const { return status_; }
virtual const char* what() const noexcept override { return sane_strstatus(status_); }
private:
SANE_Status status_;
};
/**
* call a function and return on error
*/
@ -114,6 +124,15 @@
} \
} while (SANE_FALSE)
// call a function and throw an exception on error
#define TIE(function) \
do { \
SANE_Status tmp_status = function; \
if (tmp_status != SANE_STATUS_GOOD) { \
throw SaneException(tmp_status); \
} \
} while (false)
#define DBGSTART DBG (DBG_proc, "%s start\n", __func__);
#define DBGCOMPLETED DBG (DBG_proc, "%s completed\n", __func__);
@ -956,6 +975,8 @@ typedef struct Genesys_Command_Set
/*@} */
bool (*needs_home_before_init_regs_for_scan) (Genesys_Device* dev);
/** For ASIC initialization */
SANE_Status (*init) (Genesys_Device * dev);
@ -1005,6 +1026,7 @@ typedef struct Genesys_Command_Set
SANE_Status (*led_calibration) (Genesys_Device * dev, Genesys_Sensor& sensor,
Genesys_Register_Set& regs);
void (*wait_for_motor_stop) (Genesys_Device* dev);
SANE_Status (*slow_back_home) (Genesys_Device * dev, SANE_Bool wait_until_home);
SANE_Status (*rewind) (Genesys_Device * dev);
@ -1041,11 +1063,8 @@ typedef struct Genesys_Command_Set
SANE_Status (*search_strip) (Genesys_Device * dev, const Genesys_Sensor& sensor,
SANE_Bool forward, SANE_Bool black);
SANE_Status (*is_compatible_calibration) (
Genesys_Device * dev,
const Genesys_Sensor& sensor,
Genesys_Calibration_Cache *cache,
SANE_Bool for_overwrite);
bool (*is_compatible_calibration) (Genesys_Device* dev, const Genesys_Sensor& sensor,
Genesys_Calibration_Cache* cache, SANE_Bool for_overwrite);
/* functions for transparency adapter */
/**
@ -1059,10 +1078,8 @@ typedef struct Genesys_Command_Set
SANE_Status (*send_shading_data) (Genesys_Device * dev, const Genesys_Sensor& sensor,
uint8_t * data, int size);
/**
* calculate current scan setup
*/
SANE_Status (*calculate_current_setup) (Genesys_Device * dev, const Genesys_Sensor& sensor);
// calculate current scan setup
void (*calculate_current_setup) (Genesys_Device * dev, const Genesys_Sensor& sensor);
/**
* cold boot init function
@ -1781,7 +1798,7 @@ int sanei_genesys_get_lowest_dpi(Genesys_Device *dev);
extern SANE_Status
sanei_genesys_read_calibration (Genesys_Device * dev);
extern SANE_Status
extern bool
sanei_genesys_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor,
Genesys_Calibration_Cache * cache,
int for_overwrite);
@ -1837,16 +1854,22 @@ extern void sanei_genesys_usleep(unsigned int useconds);
// same as sanei_genesys_usleep just that the duration is in milliseconds
extern void sanei_genesys_sleep_ms(unsigned int milliseconds);
class SaneException : std::exception {
class DebugMessageHelper {
public:
SaneException(SANE_Status status) : status_(status) {}
DebugMessageHelper(const char* func);
~DebugMessageHelper();
void status(const char* status) { status_ = status; }
void clear() { status_ = nullptr; }
SANE_Status status() const { return status_; }
virtual const char* what() const noexcept override { return sane_strstatus(status_); }
private:
SANE_Status status_;
const char* func_ = nullptr;
const char* status_ = nullptr;
unsigned num_exceptions_on_enter_ = 0;
};
#define DBG_HELPER(var) DebugMessageHelper var(__func__)
template<class F>
SANE_Status wrap_exceptions_to_status_code(const char* func, F&& function)
{
@ -1928,5 +1951,6 @@ void genesys_init_frontend_tables();
void debug_dump(unsigned level, const Genesys_Settings& settings);
void debug_dump(unsigned level, const SetupParams& params);
void debug_dump(unsigned level, const Genesys_Current_Setup& setup);
#endif /* not GENESYS_LOW_H */