Merge branch 'genesys-deduplicate-shading-calibration' into 'master'

genesys: Deduplicate shading calibration

See merge request sane-project/backends!184
merge-requests/186/head
Povilas Kanapickas 2019-09-28 05:49:11 +00:00
commit 29580b08b5
1 zmienionych plików z 76 dodań i 123 usunięć

Wyświetl plik

@ -1587,7 +1587,9 @@ static void genesys_average_data(uint16_t* average_data,
* that will be used to compute shading coefficient
* @param dev scanner's device
*/
static void genesys_dark_shading_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor)
static void genesys_shading_calibration_impl(Genesys_Device* dev, const Genesys_Sensor& sensor,
std::vector<std::uint16_t>& out_average_data,
bool is_dark, const std::string& log_filename_prefix)
{
DBG_HELPER(dbg);
size_t size;
@ -1600,12 +1602,15 @@ static void genesys_dark_shading_calibration(Genesys_Device* dev, const Genesys_
channels = dev->calib_channels;
uint32_t out_pixels_per_line = pixels_per_line + dev->calib_pixels_offset;
// FIXME: we set this during both dark and white calibration. A cleaner approach should
// probably be used
dev->average_size = channels * out_pixels_per_line;
dev->dark_average_data.clear();
dev->dark_average_data.resize(dev->average_size);
out_average_data.clear();
out_average_data.resize(dev->average_size);
if (dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) {
if (is_dark && dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) {
// FIXME: dark shading currently not supported on infrared transparency scans
return;
}
@ -1628,45 +1633,55 @@ static void genesys_dark_shading_calibration(Genesys_Device* dev, const Genesys_
motor=SANE_FALSE;
}
/* turn off motor and lamp power for flatbed scanners, but not for sheetfed scanners
* because they have a calibration sheet with a sufficient black strip */
if (dev->model->is_sheetfed == SANE_FALSE)
{
// turn off motor and lamp power for flatbed scanners, but not for sheetfed scanners
// because they have a calibration sheet with a sufficient black strip
if (is_dark && dev->model->is_sheetfed == SANE_FALSE) {
sanei_genesys_set_lamp_power(dev, sensor, dev->calib_reg, false);
sanei_genesys_set_motor_power(dev->calib_reg, motor);
}
else
{
} else {
sanei_genesys_set_lamp_power(dev, sensor, dev->calib_reg, true);
sanei_genesys_set_motor_power(dev->calib_reg, motor);
}
dev->write_registers(dev->calib_reg);
// wait some time to let lamp to get dark
sanei_genesys_sleep_ms(200);
if (is_dark) {
// wait some time to let lamp to get dark
sanei_genesys_sleep_ms(200);
} else if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION) {
// make sure lamp is bright again
// FIXME: what about scanners that take a long time to warm the lamp?
sanei_genesys_sleep_ms(500);
}
dev->cmd_set->begin_scan(dev, sensor, &dev->calib_reg, SANE_FALSE);
dev->cmd_set->begin_scan(dev, sensor, &dev->calib_reg, is_dark ? SANE_FALSE : SANE_TRUE);
sanei_genesys_read_data_from_scanner(dev, calibration_data.data(), size);
dev->cmd_set->end_scan(dev, &dev->calib_reg, SANE_TRUE);
std::fill(dev->dark_average_data.begin(),
dev->dark_average_data.begin() + dev->calib_pixels_offset * channels, 0);
std::fill(out_average_data.begin(),
out_average_data.begin() + dev->calib_pixels_offset * channels, 0);
genesys_average_data(dev->dark_average_data.data() + dev->calib_pixels_offset * channels,
genesys_average_data(out_average_data.data() + dev->calib_pixels_offset * channels,
calibration_data.data(), dev->calib_lines, pixels_per_line * channels);
if (DBG_LEVEL >= DBG_data)
{
sanei_genesys_write_pnm_file("gl_black_shading.pnm", calibration_data.data(), 16,
channels, pixels_per_line, dev->calib_lines);
sanei_genesys_write_pnm_file16("gl_black_average.pnm", dev->dark_average_data.data(),
if (DBG_LEVEL >= DBG_data) {
sanei_genesys_write_pnm_file((log_filename_prefix + "_shading.pnm").c_str(),
calibration_data.data(), 16,
channels, pixels_per_line, dev->calib_lines);
sanei_genesys_write_pnm_file16((log_filename_prefix + "_average.pnm").c_str(),
out_average_data.data(),
channels, out_pixels_per_line, 1);
}
}
static void genesys_dark_shading_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor)
{
DBG_HELPER(dbg);
genesys_shading_calibration_impl(dev, sensor, dev->dark_average_data, true, "gl_black_");
}
/*
* this function builds dummy dark calibration data so that we can
* compute shading coefficient in a clean way
@ -1763,84 +1778,19 @@ static void genesys_repark_sensor_before_shading(Genesys_Device* dev)
}
}
static void genesys_white_shading_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor)
static void genesys_repark_sensor_after_white_shading(Genesys_Device* dev)
{
DBG_HELPER_ARGS(dbg, "lines = %d", (unsigned int)dev->calib_lines);
size_t size;
uint32_t pixels_per_line;
uint8_t channels;
SANE_Bool motor;
pixels_per_line = dev->calib_pixels;
channels = dev->calib_channels;
uint32_t out_pixels_per_line = pixels_per_line + dev->calib_pixels_offset;
dev->white_average_data.clear();
dev->white_average_data.resize(channels * out_pixels_per_line);
// FIXME: the current calculation is likely incorrect on non-GL843 implementations,
// but this needs checking
if (dev->calib_total_bytes_to_read > 0) {
size = dev->calib_total_bytes_to_read;
} else if (dev->model->asic_type == AsicType::GL843) {
size = channels * 2 * pixels_per_line * dev->calib_lines;
} else {
size = channels * 2 * pixels_per_line * (dev->calib_lines + 1);
}
std::vector<uint8_t> calibration_data(size);
motor=SANE_TRUE;
if (dev->model->flags & GENESYS_FLAG_SHADING_NO_MOVE)
{
motor=SANE_FALSE;
}
// turn on motor and lamp power
sanei_genesys_set_lamp_power(dev, sensor, dev->calib_reg, true);
sanei_genesys_set_motor_power(dev->calib_reg, motor);
dev->write_registers(dev->calib_reg);
if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION) {
sanei_genesys_sleep_ms(500); // make sure lamp is bright again
}
dev->cmd_set->begin_scan(dev, sensor, &dev->calib_reg, SANE_TRUE);
sanei_genesys_read_data_from_scanner(dev, calibration_data.data(), size);
dev->cmd_set->end_scan(dev, &dev->calib_reg, SANE_TRUE);
if (DBG_LEVEL >= DBG_data) {
sanei_genesys_write_pnm_file("gl_white_shading.pnm", calibration_data.data(), 16,
channels, pixels_per_line, dev->calib_lines);
}
std::fill(dev->dark_average_data.begin(),
dev->dark_average_data.begin() + dev->calib_pixels_offset * channels, 0);
genesys_average_data(dev->white_average_data.data() + dev->calib_pixels_offset * channels,
calibration_data.data(), dev->calib_lines, pixels_per_line * channels);
if (DBG_LEVEL >= DBG_data) {
sanei_genesys_write_pnm_file16("gl_white_average.pnm", dev->white_average_data.data(),
channels, out_pixels_per_line, 1);
}
/* in case we haven't done dark calibration, build dummy data from white_average */
if (!(dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION))
{
genesys_dummy_dark_shading(dev, sensor);
}
if (dev->model->flags & GENESYS_FLAG_SHADING_REPARK)
{
if (dev->model->flags & GENESYS_FLAG_SHADING_REPARK) {
dev->cmd_set->slow_back_home(dev, SANE_TRUE);
}
}
static void genesys_white_shading_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor)
{
DBG_HELPER(dbg);
genesys_shading_calibration_impl(dev, sensor, dev->white_average_data, false, "gl_white_");
}
// This calibration uses a scan over the calibration target, comprising a black and a white strip.
// (So the motor must be on.)
static void genesys_dark_white_shading_calibration(Genesys_Device* dev,
@ -2909,33 +2859,36 @@ static void genesys_flatbed_calibration(Genesys_Device* dev, Genesys_Sensor& sen
dev->cmd_set->move_to_ta(dev);
}
/* shading calibration */
sanei_usb_testing_record_message("init_regs_for_shading");
dev->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg);
if (dev->model->flags & GENESYS_FLAG_DARK_WHITE_CALIBRATION)
{
sanei_usb_testing_record_message("genesys_dark_white_shading_calibration");
genesys_dark_white_shading_calibration(dev, sensor);
}
else
{
DBG(DBG_proc, "%s : genesys_dark_shading_calibration dev->calib_reg ", __func__);
debug_dump(DBG_proc, dev->calib_reg);
if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)
{
sanei_usb_testing_record_message("genesys_dark_shading_calibration");
genesys_dark_shading_calibration(dev, sensor);
}
genesys_repark_sensor_before_shading(dev);
sanei_usb_testing_record_message("init_regs_for_shading2");
// shading calibration
if (dev->model->flags & GENESYS_FLAG_DARK_WHITE_CALIBRATION) {
sanei_usb_testing_record_message("init_regs_for_shading");
dev->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg);
sanei_usb_testing_record_message("genesys_white_shading_calibration");
sanei_usb_testing_record_message("genesys_dark_white_shading_calibration");
genesys_dark_white_shading_calibration(dev, sensor);
} else {
DBG(DBG_proc, "%s : genesys_dark_shading_calibration dev->calib_reg ", __func__);
debug_dump(DBG_proc, dev->calib_reg);
if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION) {
sanei_usb_testing_record_message("init_regs_for_shading");
dev->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg);
sanei_usb_testing_record_message("genesys_dark_shading_calibration");
genesys_dark_shading_calibration(dev, sensor);
genesys_repark_sensor_before_shading(dev);
}
sanei_usb_testing_record_message("init_regs_for_shading2");
dev->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg);
sanei_usb_testing_record_message("genesys_white_shading_calibration");
genesys_white_shading_calibration(dev, sensor);
genesys_repark_sensor_after_white_shading(dev);
if (!(dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)) {
genesys_dummy_dark_shading(dev, sensor);
}
}
if (dev->cmd_set->send_shading_data == nullptr) {
@ -3044,15 +2997,15 @@ static void genesys_sheetfed_calibration(Genesys_Device* dev, Genesys_Sensor& se
try {
genesys_white_shading_calibration(dev, sensor);
genesys_repark_sensor_after_white_shading(dev);
} catch (...) {
catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); });
throw;
}
/* in case we haven't black shading data, build it from black pixels
* of white calibration */
if (!(dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION))
{
// in case we haven't black shading data, build it from black pixels of white calibration
// FIXME: shouldn't we use genesys_dummy_dark_shading() ?
if (!(dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)) {
dev->dark_average_data.clear();
dev->dark_average_data.resize(dev->average_size, 0x0f0f);
/* XXX STEF XXX