kopia lustrzana https://gitlab.com/sane-project/backends
Merge branch 'genesys-simplify-param-calculation' into 'master'
genesys: Simplify scan parameter calculation See merge request sane-project/backends!462merge-requests/463/merge
commit
4ee035983c
|
|
@ -185,7 +185,7 @@ static const SANE_Range expiration_range = {
|
|||
1 /* quantization */
|
||||
};
|
||||
|
||||
const Genesys_Sensor& sanei_genesys_find_sensor_any(Genesys_Device* dev)
|
||||
const Genesys_Sensor& sanei_genesys_find_sensor_any(const Genesys_Device* dev)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
for (const auto& sensor : *s_sensors) {
|
||||
|
|
@ -196,7 +196,7 @@ const Genesys_Sensor& sanei_genesys_find_sensor_any(Genesys_Device* dev)
|
|||
throw std::runtime_error("Given device does not have sensor defined");
|
||||
}
|
||||
|
||||
Genesys_Sensor* find_sensor_impl(Genesys_Device* dev, unsigned dpi, unsigned channels,
|
||||
Genesys_Sensor* find_sensor_impl(const Genesys_Device* dev, unsigned dpi, unsigned channels,
|
||||
ScanMethod scan_method)
|
||||
{
|
||||
DBG_HELPER_ARGS(dbg, "dpi: %d, channels: %d, scan_method: %d", dpi, channels,
|
||||
|
|
@ -211,7 +211,7 @@ Genesys_Sensor* find_sensor_impl(Genesys_Device* dev, unsigned dpi, unsigned cha
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool sanei_genesys_has_sensor(Genesys_Device* dev, unsigned dpi, unsigned channels,
|
||||
bool sanei_genesys_has_sensor(const Genesys_Device* dev, unsigned dpi, unsigned channels,
|
||||
ScanMethod scan_method)
|
||||
{
|
||||
DBG_HELPER_ARGS(dbg, "dpi: %d, channels: %d, scan_method: %d", dpi, channels,
|
||||
|
|
@ -219,8 +219,8 @@ bool sanei_genesys_has_sensor(Genesys_Device* dev, unsigned dpi, unsigned channe
|
|||
return find_sensor_impl(dev, dpi, channels, scan_method) != nullptr;
|
||||
}
|
||||
|
||||
const Genesys_Sensor& sanei_genesys_find_sensor(Genesys_Device* dev, unsigned dpi, unsigned channels,
|
||||
ScanMethod scan_method)
|
||||
const Genesys_Sensor& sanei_genesys_find_sensor(const Genesys_Device* dev, unsigned dpi,
|
||||
unsigned channels, ScanMethod scan_method)
|
||||
{
|
||||
DBG_HELPER_ARGS(dbg, "dpi: %d, channels: %d, scan_method: %d", dpi, channels,
|
||||
static_cast<unsigned>(scan_method));
|
||||
|
|
@ -244,12 +244,14 @@ Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, unsigne
|
|||
|
||||
|
||||
std::vector<std::reference_wrapper<const Genesys_Sensor>>
|
||||
sanei_genesys_find_sensors_all(Genesys_Device* dev, ScanMethod scan_method)
|
||||
sanei_genesys_find_sensors_all(const Genesys_Device* dev, ScanMethod scan_method)
|
||||
{
|
||||
DBG_HELPER_ARGS(dbg, "scan_method: %d", static_cast<unsigned>(scan_method));
|
||||
std::vector<std::reference_wrapper<const Genesys_Sensor>> ret;
|
||||
for (const Genesys_Sensor& sensor : sanei_genesys_find_sensors_all_for_write(dev, scan_method)) {
|
||||
ret.push_back(sensor);
|
||||
for (auto& sensor : *s_sensors) {
|
||||
if (dev->model->sensor_id == sensor.sensor_id && sensor.method == scan_method) {
|
||||
ret.push_back(sensor);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -4246,71 +4248,63 @@ static unsigned pick_resolution(const std::vector<unsigned>& resolutions, unsign
|
|||
return best_res;
|
||||
}
|
||||
|
||||
static void calc_parameters(Genesys_Scanner* s)
|
||||
static Genesys_Settings calculate_scan_settings(Genesys_Scanner* s)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
float tl_x = 0, tl_y = 0, br_x = 0, br_y = 0;
|
||||
|
||||
tl_x = fixed_to_float(s->pos_top_left_x);
|
||||
tl_y = fixed_to_float(s->pos_top_left_y);
|
||||
br_x = fixed_to_float(s->pos_bottom_right_x);
|
||||
br_y = fixed_to_float(s->pos_bottom_right_y);
|
||||
const auto* dev = s->dev;
|
||||
Genesys_Settings settings;
|
||||
settings.scan_method = s->scan_method;
|
||||
settings.scan_mode = option_string_to_scan_color_mode(s->mode);
|
||||
|
||||
s->params.last_frame = true; /* only single pass scanning supported */
|
||||
|
||||
if (s->mode == SANE_VALUE_SCAN_MODE_GRAY || s->mode == SANE_VALUE_SCAN_MODE_LINEART) {
|
||||
s->params.format = SANE_FRAME_GRAY;
|
||||
} else {
|
||||
s->params.format = SANE_FRAME_RGB;
|
||||
settings.depth = s->bit_depth;
|
||||
if (settings.depth > 8) {
|
||||
settings.depth = 16;
|
||||
}
|
||||
settings.disable_interpolation = s->disable_interpolation;
|
||||
|
||||
if (s->mode == SANE_VALUE_SCAN_MODE_LINEART) {
|
||||
s->params.depth = 1;
|
||||
} else {
|
||||
s->params.depth = s->bit_depth;
|
||||
}
|
||||
const auto& resolutions = dev->model->get_resolution_settings(settings.scan_method);
|
||||
|
||||
s->dev->settings.scan_method = s->scan_method;
|
||||
const auto& resolutions = s->dev->model->get_resolution_settings(s->dev->settings.scan_method);
|
||||
|
||||
s->dev->settings.depth = s->bit_depth;
|
||||
|
||||
/* interpolation */
|
||||
s->dev->settings.disable_interpolation = s->disable_interpolation;
|
||||
|
||||
// FIXME: use correct sensor
|
||||
const auto& sensor = sanei_genesys_find_sensor_any(s->dev);
|
||||
// FIXME: use correct sensor
|
||||
const auto& sensor = sanei_genesys_find_sensor_any(dev);
|
||||
|
||||
// hardware settings
|
||||
if (static_cast<unsigned>(s->resolution) > sensor.full_resolution &&
|
||||
s->dev->settings.disable_interpolation)
|
||||
settings.disable_interpolation)
|
||||
{
|
||||
s->dev->settings.xres = sensor.full_resolution;
|
||||
settings.xres = sensor.full_resolution;
|
||||
} else {
|
||||
s->dev->settings.xres = s->resolution;
|
||||
settings.xres = s->resolution;
|
||||
}
|
||||
s->dev->settings.yres = s->resolution;
|
||||
settings.yres = s->resolution;
|
||||
|
||||
s->dev->settings.xres = pick_resolution(resolutions.resolutions_x, s->dev->settings.xres, "X");
|
||||
s->dev->settings.yres = pick_resolution(resolutions.resolutions_y, s->dev->settings.yres, "Y");
|
||||
settings.xres = pick_resolution(resolutions.resolutions_x, settings.xres, "X");
|
||||
settings.yres = pick_resolution(resolutions.resolutions_y, settings.yres, "Y");
|
||||
|
||||
s->params.lines = static_cast<unsigned>(((br_y - tl_y) * s->dev->settings.yres) /
|
||||
settings.tl_x = fixed_to_float(s->pos_top_left_x);
|
||||
settings.tl_y = fixed_to_float(s->pos_top_left_y);
|
||||
float br_x = fixed_to_float(s->pos_bottom_right_x);
|
||||
float br_y = fixed_to_float(s->pos_bottom_right_y);
|
||||
|
||||
settings.lines = static_cast<unsigned>(((br_y - settings.tl_y) * settings.yres) /
|
||||
MM_PER_INCH);
|
||||
unsigned pixels_per_line = static_cast<unsigned>(((br_x - tl_x) * s->dev->settings.xres) /
|
||||
|
||||
|
||||
unsigned pixels_per_line = static_cast<unsigned>(((br_x - settings.tl_x) * settings.xres) /
|
||||
MM_PER_INCH);
|
||||
|
||||
/* we need an even pixels number
|
||||
* TODO invert test logic or generalize behaviour across all ASICs */
|
||||
if (has_flag(s->dev->model->flags, ModelFlag::SIS_SENSOR) ||
|
||||
s->dev->model->asic_type == AsicType::GL847 ||
|
||||
s->dev->model->asic_type == AsicType::GL124 ||
|
||||
s->dev->model->asic_type == AsicType::GL845 ||
|
||||
s->dev->model->asic_type == AsicType::GL846 ||
|
||||
s->dev->model->asic_type == AsicType::GL843)
|
||||
// we need an even pixels number
|
||||
// TODO invert test logic or generalize behaviour across all ASICs
|
||||
if (has_flag(dev->model->flags, ModelFlag::SIS_SENSOR) ||
|
||||
dev->model->asic_type == AsicType::GL847 ||
|
||||
dev->model->asic_type == AsicType::GL124 ||
|
||||
dev->model->asic_type == AsicType::GL845 ||
|
||||
dev->model->asic_type == AsicType::GL846 ||
|
||||
dev->model->asic_type == AsicType::GL843)
|
||||
{
|
||||
if (s->dev->settings.xres <= 1200) {
|
||||
if (settings.xres <= 1200) {
|
||||
pixels_per_line = (pixels_per_line / 4) * 4;
|
||||
} else if (s->dev->settings.xres < s->dev->settings.yres) {
|
||||
} else if (settings.xres < settings.yres) {
|
||||
// BUG: this is an artifact of the fact that the resolution was twice as large than
|
||||
// the actual resolution when scanning above the supported scanner X resolution
|
||||
pixels_per_line = (pixels_per_line / 8) * 8;
|
||||
|
|
@ -4319,14 +4313,14 @@ static void calc_parameters(Genesys_Scanner* s)
|
|||
}
|
||||
}
|
||||
|
||||
/* corner case for true lineart for sensor with several segments
|
||||
* or when xres is doubled to match yres */
|
||||
if (s->dev->settings.xres >= 1200 && (
|
||||
s->dev->model->asic_type == AsicType::GL124 ||
|
||||
s->dev->model->asic_type == AsicType::GL847 ||
|
||||
s->dev->session.params.xres < s->dev->session.params.yres))
|
||||
// corner case for true lineart for sensor with several segments or when xres is doubled
|
||||
// to match yres */
|
||||
if (settings.xres >= 1200 && (
|
||||
dev->model->asic_type == AsicType::GL124 ||
|
||||
dev->model->asic_type == AsicType::GL847 ||
|
||||
dev->session.params.xres < dev->session.params.yres))
|
||||
{
|
||||
if (s->dev->settings.xres < s->dev->settings.yres) {
|
||||
if (settings.xres < settings.yres) {
|
||||
// FIXME: this is an artifact of the fact that the resolution was twice as large than
|
||||
// the actual resolution when scanning above the supported scanner X resolution
|
||||
pixels_per_line = (pixels_per_line / 8) * 8;
|
||||
|
|
@ -4335,78 +4329,110 @@ static void calc_parameters(Genesys_Scanner* s)
|
|||
}
|
||||
}
|
||||
|
||||
unsigned xres_factor = s->resolution / s->dev->settings.xres;
|
||||
|
||||
unsigned bytes_per_line = 0;
|
||||
|
||||
if (s->params.depth > 8)
|
||||
{
|
||||
s->params.depth = 16;
|
||||
bytes_per_line = 2 * pixels_per_line;
|
||||
}
|
||||
else if (s->params.depth == 1)
|
||||
{
|
||||
if (s->mode == SANE_VALUE_SCAN_MODE_LINEART || settings.depth == 1) {
|
||||
// round down pixel number. This will is lossy operation, at most 7 pixels will be lost
|
||||
pixels_per_line = (pixels_per_line / 8) * 8;
|
||||
}
|
||||
|
||||
unsigned xres_factor = s->resolution / settings.xres;
|
||||
settings.pixels = pixels_per_line;
|
||||
settings.requested_pixels = pixels_per_line * xres_factor;
|
||||
|
||||
if (s->color_filter == "Red") {
|
||||
settings.color_filter = ColorFilter::RED;
|
||||
} else if (s->color_filter == "Green") {
|
||||
settings.color_filter = ColorFilter::GREEN;
|
||||
} else if (s->color_filter == "Blue") {
|
||||
settings.color_filter = ColorFilter::BLUE;
|
||||
} else {
|
||||
settings.color_filter = ColorFilter::NONE;
|
||||
}
|
||||
|
||||
if (s->color_filter == "None") {
|
||||
settings.true_gray = 1;
|
||||
} else {
|
||||
settings.true_gray = 0;
|
||||
}
|
||||
|
||||
settings.threshold = static_cast<int>(2.55f * (fixed_to_float(s->threshold)));
|
||||
settings.threshold_curve = s->threshold_curve;
|
||||
|
||||
// brigthness and contrast only for for 8 bit scans
|
||||
if (s->bit_depth <= 8) {
|
||||
settings.contrast = (s->contrast * 127) / 100;
|
||||
settings.brightness = (s->brightness * 127) / 100;
|
||||
} else {
|
||||
settings.contrast = 0;
|
||||
settings.brightness = 0;
|
||||
}
|
||||
|
||||
settings.expiration_time = s->expiration_time;
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
static SANE_Parameters calculate_scan_parameters(const Genesys_Device& dev,
|
||||
const Genesys_Settings& settings)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
|
||||
auto sensor = sanei_genesys_find_sensor(&dev, settings.xres, settings.get_channels(),
|
||||
settings.scan_method);
|
||||
auto session = dev.cmd_set->calculate_scan_session(&dev, sensor, settings);
|
||||
|
||||
SANE_Parameters params;
|
||||
if (settings.scan_mode == ScanColorMode::GRAY ||
|
||||
settings.scan_mode == ScanColorMode::LINEART)
|
||||
{
|
||||
params.format = SANE_FRAME_GRAY;
|
||||
} else {
|
||||
params.format = SANE_FRAME_RGB;
|
||||
}
|
||||
// only single-pass scanning supported
|
||||
params.last_frame = true;
|
||||
|
||||
params.depth = settings.depth;
|
||||
if (settings.scan_mode == ScanColorMode::LINEART) {
|
||||
params.depth = 1;
|
||||
}
|
||||
|
||||
// FIXME: add the data needed to perform the data conversion to the format used by the user
|
||||
// to ScanSession.
|
||||
unsigned pixels_per_line = settings.requested_pixels;
|
||||
unsigned pixels_per_line_session = session.output_pixels * settings.requested_pixels / settings.pixels;
|
||||
if (pixels_per_line != pixels_per_line_session) {
|
||||
dbg.vlog(DBG_info, "The number of scanned pixels does not match "
|
||||
"the number of requested pixels (%d vs %d), image will be stretched",
|
||||
pixels_per_line_session, pixels_per_line);
|
||||
}
|
||||
|
||||
unsigned bytes_per_line = 0;
|
||||
if (params.depth == 16) {
|
||||
bytes_per_line = 2 * pixels_per_line;
|
||||
} else if (params.depth == 1) {
|
||||
bytes_per_line = pixels_per_line / 8;
|
||||
} else {
|
||||
bytes_per_line = pixels_per_line;
|
||||
}
|
||||
|
||||
if (s->params.format == SANE_FRAME_RGB) {
|
||||
if (params.format == SANE_FRAME_RGB) {
|
||||
bytes_per_line *= 3;
|
||||
}
|
||||
|
||||
s->dev->settings.scan_mode = option_string_to_scan_color_mode(s->mode);
|
||||
params.lines = settings.lines;
|
||||
params.pixels_per_line = pixels_per_line;
|
||||
params.bytes_per_line = bytes_per_line;
|
||||
|
||||
s->dev->settings.lines = s->params.lines;
|
||||
s->dev->settings.pixels = pixels_per_line;
|
||||
s->dev->settings.requested_pixels = pixels_per_line * xres_factor;
|
||||
s->params.pixels_per_line = pixels_per_line * xres_factor;
|
||||
s->params.bytes_per_line = bytes_per_line * xres_factor;
|
||||
s->dev->settings.tl_x = tl_x;
|
||||
s->dev->settings.tl_y = tl_y;
|
||||
|
||||
// threshold setting
|
||||
s->dev->settings.threshold = static_cast<int>(2.55f * (fixed_to_float(s->threshold)));
|
||||
|
||||
// color filter
|
||||
if (s->color_filter == "Red") {
|
||||
s->dev->settings.color_filter = ColorFilter::RED;
|
||||
} else if (s->color_filter == "Green") {
|
||||
s->dev->settings.color_filter = ColorFilter::GREEN;
|
||||
} else if (s->color_filter == "Blue") {
|
||||
s->dev->settings.color_filter = ColorFilter::BLUE;
|
||||
} else {
|
||||
s->dev->settings.color_filter = ColorFilter::NONE;
|
||||
}
|
||||
|
||||
// true gray
|
||||
if (s->color_filter == "None") {
|
||||
s->dev->settings.true_gray = 1;
|
||||
} else {
|
||||
s->dev->settings.true_gray = 0;
|
||||
}
|
||||
|
||||
// threshold curve for dynamic rasterization
|
||||
s->dev->settings.threshold_curve = s->threshold_curve;
|
||||
|
||||
/* brigthness and contrast only for for 8 bit scans */
|
||||
if(s->bit_depth <= 8)
|
||||
{
|
||||
s->dev->settings.contrast = (s->contrast * 127) / 100;
|
||||
s->dev->settings.brightness = (s->brightness * 127) / 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->dev->settings.contrast=0;
|
||||
s->dev->settings.brightness=0;
|
||||
}
|
||||
|
||||
/* cache expiration time */
|
||||
s->dev->settings.expiration_time = s->expiration_time;
|
||||
return params;
|
||||
}
|
||||
|
||||
static void calc_parameters(Genesys_Scanner* s)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
|
||||
s->dev->settings = calculate_scan_settings(s);
|
||||
s->params = calculate_scan_parameters(*s->dev, s->dev->settings);
|
||||
}
|
||||
|
||||
static void create_bpp_list (Genesys_Scanner * s, const std::vector<unsigned>& bpp)
|
||||
{
|
||||
|
|
@ -5536,12 +5562,12 @@ static void sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle)
|
|||
s_scanners->push_back(Genesys_Scanner());
|
||||
auto* s = &s_scanners->back();
|
||||
|
||||
s->dev = dev;
|
||||
s->dev = dev;
|
||||
s->scanning = false;
|
||||
s->dev->parking = false;
|
||||
s->dev->read_active = false;
|
||||
s->dev->force_calibration = 0;
|
||||
s->dev->line_count = 0;
|
||||
dev->parking = false;
|
||||
dev->read_active = false;
|
||||
dev->force_calibration = 0;
|
||||
dev->line_count = 0;
|
||||
|
||||
*handle = s;
|
||||
|
||||
|
|
@ -5549,18 +5575,18 @@ static void sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle)
|
|||
sanei_genesys_init_structs (dev);
|
||||
}
|
||||
|
||||
dev->cmd_set = create_cmd_set(dev->model->asic_type);
|
||||
|
||||
init_options(s);
|
||||
|
||||
DBG_INIT();
|
||||
|
||||
s->dev->cmd_set = create_cmd_set(s->dev->model->asic_type);
|
||||
|
||||
// FIXME: we create sensor tables for the sensor, this should happen when we know which sensor
|
||||
// we will select
|
||||
dev->cmd_set->init(dev);
|
||||
|
||||
// some hardware capabilities are detected through sensors
|
||||
s->dev->cmd_set->update_hardware_sensors (s);
|
||||
dev->cmd_set->update_hardware_sensors (s);
|
||||
}
|
||||
|
||||
SANE_GENESYS_API_LINKAGE
|
||||
|
|
@ -5592,46 +5618,42 @@ sane_close_impl(SANE_Handle handle)
|
|||
return; /* oops, not a handle we know about */
|
||||
}
|
||||
|
||||
Genesys_Scanner* s = &*it;
|
||||
auto* dev = it->dev;
|
||||
|
||||
/* eject document for sheetfed scanners */
|
||||
if (s->dev->model->is_sheetfed) {
|
||||
catch_all_exceptions(__func__, [&](){ s->dev->cmd_set->eject_document(s->dev); });
|
||||
}
|
||||
else
|
||||
{
|
||||
/* in case scanner is parking, wait for the head
|
||||
* to reach home position */
|
||||
if (s->dev->parking) {
|
||||
sanei_genesys_wait_for_home(s->dev);
|
||||
// eject document for sheetfed scanners
|
||||
if (dev->model->is_sheetfed) {
|
||||
catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); });
|
||||
} else {
|
||||
// in case scanner is parking, wait for the head to reach home position
|
||||
if (dev->parking) {
|
||||
sanei_genesys_wait_for_home(dev);
|
||||
}
|
||||
}
|
||||
|
||||
// enable power saving before leaving
|
||||
s->dev->cmd_set->save_power(s->dev, true);
|
||||
dev->cmd_set->save_power(dev, true);
|
||||
|
||||
// here is the place to store calibration cache
|
||||
if (s->dev->force_calibration == 0 && !is_testing_mode()) {
|
||||
catch_all_exceptions(__func__, [&](){ write_calibration(s->dev->calibration_cache,
|
||||
s->dev->calib_file); });
|
||||
if (dev->force_calibration == 0 && !is_testing_mode()) {
|
||||
catch_all_exceptions(__func__, [&](){ write_calibration(dev->calibration_cache,
|
||||
dev->calib_file); });
|
||||
}
|
||||
|
||||
s->dev->already_initialized = false;
|
||||
|
||||
s->dev->clear();
|
||||
dev->already_initialized = false;
|
||||
dev->clear();
|
||||
|
||||
// LAMP OFF : same register across all the ASICs */
|
||||
s->dev->interface->write_register(0x03, 0x00);
|
||||
dev->interface->write_register(0x03, 0x00);
|
||||
|
||||
catch_all_exceptions(__func__, [&](){ s->dev->interface->get_usb_device().clear_halt(); });
|
||||
catch_all_exceptions(__func__, [&](){ dev->interface->get_usb_device().clear_halt(); });
|
||||
|
||||
// we need this to avoid these ASIC getting stuck in bulk writes
|
||||
catch_all_exceptions(__func__, [&](){ s->dev->interface->get_usb_device().reset(); });
|
||||
catch_all_exceptions(__func__, [&](){ dev->interface->get_usb_device().reset(); });
|
||||
|
||||
// not freeing s->dev because it's in the dev list
|
||||
catch_all_exceptions(__func__, [&](){ s->dev->interface->get_usb_device().close(); });
|
||||
// not freeing dev because it's in the dev list
|
||||
catch_all_exceptions(__func__, [&](){ dev->interface->get_usb_device().close(); });
|
||||
|
||||
s_scanners->erase(it);
|
||||
s_scanners->erase(it);
|
||||
}
|
||||
|
||||
SANE_GENESYS_API_LINKAGE
|
||||
|
|
@ -5696,18 +5718,19 @@ static void print_option(DebugMessageHelper& dbg, const Genesys_Scanner& s, int
|
|||
static void get_option_value(Genesys_Scanner* s, int option, void* val)
|
||||
{
|
||||
DBG_HELPER_ARGS(dbg, "option: %s (%d)", s->opt[option].name, option);
|
||||
auto* dev = s->dev;
|
||||
unsigned int i;
|
||||
SANE_Word* table = nullptr;
|
||||
std::vector<uint16_t> gamma_table;
|
||||
unsigned option_size = 0;
|
||||
|
||||
const Genesys_Sensor* sensor = nullptr;
|
||||
if (sanei_genesys_has_sensor(s->dev, s->dev->settings.xres, s->dev->settings.get_channels(),
|
||||
s->dev->settings.scan_method))
|
||||
if (sanei_genesys_has_sensor(dev, dev->settings.xres, dev->settings.get_channels(),
|
||||
dev->settings.scan_method))
|
||||
{
|
||||
sensor = &sanei_genesys_find_sensor(s->dev, s->dev->settings.xres,
|
||||
s->dev->settings.get_channels(),
|
||||
s->dev->settings.scan_method);
|
||||
sensor = &sanei_genesys_find_sensor(dev, dev->settings.xres,
|
||||
dev->settings.get_channels(),
|
||||
dev->settings.scan_method);
|
||||
}
|
||||
|
||||
switch (option)
|
||||
|
|
@ -5786,13 +5809,13 @@ static void get_option_value(Genesys_Scanner* s, int option, void* val)
|
|||
throw SaneException("Unsupported scanner mode selected");
|
||||
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
if (s->color_filter == "Red") {
|
||||
gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_RED);
|
||||
} else if (s->color_filter == "Blue") {
|
||||
gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_BLUE);
|
||||
} else {
|
||||
gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_GREEN);
|
||||
}
|
||||
if (s->color_filter == "Red") {
|
||||
gamma_table = get_gamma_table(dev, *sensor, GENESYS_RED);
|
||||
} else if (s->color_filter == "Blue") {
|
||||
gamma_table = get_gamma_table(dev, *sensor, GENESYS_BLUE);
|
||||
} else {
|
||||
gamma_table = get_gamma_table(dev, *sensor, GENESYS_GREEN);
|
||||
}
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
if (gamma_table.size() != option_size) {
|
||||
throw std::runtime_error("The size of the gamma tables does not match");
|
||||
|
|
@ -5806,7 +5829,7 @@ static void get_option_value(Genesys_Scanner* s, int option, void* val)
|
|||
throw SaneException("Unsupported scanner mode selected");
|
||||
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_RED);
|
||||
gamma_table = get_gamma_table(dev, *sensor, GENESYS_RED);
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
if (gamma_table.size() != option_size) {
|
||||
throw std::runtime_error("The size of the gamma tables does not match");
|
||||
|
|
@ -5820,7 +5843,7 @@ static void get_option_value(Genesys_Scanner* s, int option, void* val)
|
|||
throw SaneException("Unsupported scanner mode selected");
|
||||
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_GREEN);
|
||||
gamma_table = get_gamma_table(dev, *sensor, GENESYS_GREEN);
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
if (gamma_table.size() != option_size) {
|
||||
throw std::runtime_error("The size of the gamma tables does not match");
|
||||
|
|
@ -5834,7 +5857,7 @@ static void get_option_value(Genesys_Scanner* s, int option, void* val)
|
|||
throw SaneException("Unsupported scanner mode selected");
|
||||
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_BLUE);
|
||||
gamma_table = get_gamma_table(dev, *sensor, GENESYS_BLUE);
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
if (gamma_table.size() != option_size) {
|
||||
throw std::runtime_error("The size of the gamma tables does not match");
|
||||
|
|
@ -5866,11 +5889,10 @@ static void get_option_value(Genesys_Scanner* s, int option, void* val)
|
|||
|
||||
bool result = true;
|
||||
|
||||
auto session = s->dev->cmd_set->calculate_scan_session(s->dev, *sensor,
|
||||
s->dev->settings);
|
||||
auto session = dev->cmd_set->calculate_scan_session(dev, *sensor, dev->settings);
|
||||
|
||||
for (auto& cache : s->dev->calibration_cache) {
|
||||
if (sanei_genesys_is_compatible_calibration(s->dev, session, &cache, false)) {
|
||||
for (auto& cache : dev->calibration_cache) {
|
||||
if (sanei_genesys_is_compatible_calibration(dev, session, &cache, false)) {
|
||||
*reinterpret_cast<SANE_Bool*>(val) = SANE_FALSE;
|
||||
}
|
||||
}
|
||||
|
|
@ -5889,6 +5911,7 @@ static void get_option_value(Genesys_Scanner* s, int option, void* val)
|
|||
static void set_calibration_value(Genesys_Scanner* s, const char* val)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
auto dev = s->dev;
|
||||
|
||||
std::string new_calib_path = val;
|
||||
Genesys_Device::Calibration new_calibration;
|
||||
|
|
@ -5903,8 +5926,8 @@ static void set_calibration_value(Genesys_Scanner* s, const char* val)
|
|||
return;
|
||||
}
|
||||
|
||||
s->dev->calibration_cache = std::move(new_calibration);
|
||||
s->dev->calib_file = new_calib_path;
|
||||
dev->calibration_cache = std::move(new_calibration);
|
||||
dev->calib_file = new_calib_path;
|
||||
s->calibration_file = new_calib_path;
|
||||
DBG(DBG_info, "%s: Calibration filename set to '%s':\n", __func__, new_calib_path.c_str());
|
||||
}
|
||||
|
|
@ -5915,12 +5938,13 @@ static void set_option_value(Genesys_Scanner* s, int option, void *val, SANE_Int
|
|||
DBG_HELPER_ARGS(dbg, "option: %s (%d)", s->opt[option].name, option);
|
||||
print_option(dbg, *s, option, val);
|
||||
|
||||
auto* dev = s->dev;
|
||||
|
||||
SANE_Word *table;
|
||||
unsigned int i;
|
||||
unsigned option_size = 0;
|
||||
|
||||
switch (option)
|
||||
{
|
||||
switch (option) {
|
||||
case OPT_TL_X:
|
||||
s->pos_top_left_x = *reinterpret_cast<SANE_Word*>(val);
|
||||
calc_parameters(s);
|
||||
|
|
@ -6015,7 +6039,7 @@ static void set_option_value(Genesys_Scanner* s, int option, void *val, SANE_Int
|
|||
ENABLE (OPT_THRESHOLD);
|
||||
ENABLE (OPT_THRESHOLD_CURVE);
|
||||
DISABLE (OPT_BIT_DEPTH);
|
||||
if (s->dev->model->asic_type != AsicType::GL646 || !s->dev->model->is_cis) {
|
||||
if (dev->model->asic_type != AsicType::GL646 || !dev->model->is_cis) {
|
||||
ENABLE(OPT_COLOR_FILTER);
|
||||
}
|
||||
}
|
||||
|
|
@ -6023,22 +6047,19 @@ static void set_option_value(Genesys_Scanner* s, int option, void *val, SANE_Int
|
|||
{
|
||||
DISABLE (OPT_THRESHOLD);
|
||||
DISABLE (OPT_THRESHOLD_CURVE);
|
||||
if (s->mode == SANE_VALUE_SCAN_MODE_GRAY)
|
||||
{
|
||||
if (s->dev->model->asic_type != AsicType::GL646 || !s->dev->model->is_cis) {
|
||||
if (s->mode == SANE_VALUE_SCAN_MODE_GRAY) {
|
||||
if (dev->model->asic_type != AsicType::GL646 || !dev->model->is_cis) {
|
||||
ENABLE(OPT_COLOR_FILTER);
|
||||
}
|
||||
create_bpp_list (s, s->dev->model->bpp_gray_values);
|
||||
s->bit_depth = s->dev->model->bpp_gray_values[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
DISABLE (OPT_COLOR_FILTER);
|
||||
create_bpp_list (s, s->dev->model->bpp_color_values);
|
||||
s->bit_depth = s->dev->model->bpp_color_values[0];
|
||||
}
|
||||
}
|
||||
calc_parameters(s);
|
||||
create_bpp_list(s, dev->model->bpp_gray_values);
|
||||
s->bit_depth = dev->model->bpp_gray_values[0];
|
||||
} else {
|
||||
DISABLE(OPT_COLOR_FILTER);
|
||||
create_bpp_list(s, dev->model->bpp_color_values);
|
||||
s->bit_depth = dev->model->bpp_color_values[0];
|
||||
}
|
||||
}
|
||||
calc_parameters(s);
|
||||
|
||||
/* if custom gamma, toggle gamma table options according to the mode */
|
||||
if (s->custom_gamma)
|
||||
|
|
@ -6065,24 +6086,26 @@ static void set_option_value(Genesys_Scanner* s, int option, void *val, SANE_Int
|
|||
s->color_filter = reinterpret_cast<const char*>(val);
|
||||
calc_parameters(s);
|
||||
break;
|
||||
case OPT_CALIBRATION_FILE:
|
||||
if (s->dev->force_calibration == 0) {
|
||||
case OPT_CALIBRATION_FILE: {
|
||||
if (dev->force_calibration == 0) {
|
||||
set_calibration_value(s, reinterpret_cast<const char*>(val));
|
||||
}
|
||||
break;
|
||||
case OPT_LAMP_OFF_TIME:
|
||||
if (*reinterpret_cast<SANE_Word*>(val) != s->lamp_off_time) {
|
||||
s->lamp_off_time = *reinterpret_cast<SANE_Word*>(val);
|
||||
s->dev->cmd_set->set_powersaving(s->dev, s->lamp_off_time);
|
||||
}
|
||||
break;
|
||||
case OPT_EXPIRATION_TIME:
|
||||
if (*reinterpret_cast<SANE_Word*>(val) != s->expiration_time) {
|
||||
s->expiration_time = *reinterpret_cast<SANE_Word*>(val);
|
||||
case OPT_LAMP_OFF_TIME: {
|
||||
if (*reinterpret_cast<SANE_Word*>(val) != s->lamp_off_time) {
|
||||
s->lamp_off_time = *reinterpret_cast<SANE_Word*>(val);
|
||||
dev->cmd_set->set_powersaving(dev, s->lamp_off_time);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case OPT_CUSTOM_GAMMA:
|
||||
case OPT_EXPIRATION_TIME: {
|
||||
if (*reinterpret_cast<SANE_Word*>(val) != s->expiration_time) {
|
||||
s->expiration_time = *reinterpret_cast<SANE_Word*>(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OPT_CUSTOM_GAMMA: {
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||
s->custom_gamma = *reinterpret_cast<SANE_Bool*>(val);
|
||||
|
||||
|
|
@ -6108,88 +6131,96 @@ static void set_option_value(Genesys_Scanner* s, int option, void *val, SANE_Int
|
|||
DISABLE (OPT_GAMMA_VECTOR_R);
|
||||
DISABLE (OPT_GAMMA_VECTOR_G);
|
||||
DISABLE (OPT_GAMMA_VECTOR_B);
|
||||
for (auto& table : s->dev->gamma_override_tables) {
|
||||
table.clear();
|
||||
for (auto& table : dev->gamma_override_tables) {
|
||||
table.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case OPT_GAMMA_VECTOR:
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
case OPT_GAMMA_VECTOR: {
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
|
||||
s->dev->gamma_override_tables[GENESYS_RED].resize(option_size);
|
||||
s->dev->gamma_override_tables[GENESYS_GREEN].resize(option_size);
|
||||
s->dev->gamma_override_tables[GENESYS_BLUE].resize(option_size);
|
||||
for (i = 0; i < option_size; i++) {
|
||||
s->dev->gamma_override_tables[GENESYS_RED][i] = table[i];
|
||||
s->dev->gamma_override_tables[GENESYS_GREEN][i] = table[i];
|
||||
s->dev->gamma_override_tables[GENESYS_BLUE][i] = table[i];
|
||||
dev->gamma_override_tables[GENESYS_RED].resize(option_size);
|
||||
dev->gamma_override_tables[GENESYS_GREEN].resize(option_size);
|
||||
dev->gamma_override_tables[GENESYS_BLUE].resize(option_size);
|
||||
for (i = 0; i < option_size; i++) {
|
||||
dev->gamma_override_tables[GENESYS_RED][i] = table[i];
|
||||
dev->gamma_override_tables[GENESYS_GREEN][i] = table[i];
|
||||
dev->gamma_override_tables[GENESYS_BLUE][i] = table[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OPT_GAMMA_VECTOR_R:
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
s->dev->gamma_override_tables[GENESYS_RED].resize(option_size);
|
||||
for (i = 0; i < option_size; i++) {
|
||||
s->dev->gamma_override_tables[GENESYS_RED][i] = table[i];
|
||||
case OPT_GAMMA_VECTOR_R: {
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
dev->gamma_override_tables[GENESYS_RED].resize(option_size);
|
||||
for (i = 0; i < option_size; i++) {
|
||||
dev->gamma_override_tables[GENESYS_RED][i] = table[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OPT_GAMMA_VECTOR_G:
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
s->dev->gamma_override_tables[GENESYS_GREEN].resize(option_size);
|
||||
for (i = 0; i < option_size; i++) {
|
||||
s->dev->gamma_override_tables[GENESYS_GREEN][i] = table[i];
|
||||
case OPT_GAMMA_VECTOR_G: {
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
dev->gamma_override_tables[GENESYS_GREEN].resize(option_size);
|
||||
for (i = 0; i < option_size; i++) {
|
||||
dev->gamma_override_tables[GENESYS_GREEN][i] = table[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OPT_GAMMA_VECTOR_B:
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
s->dev->gamma_override_tables[GENESYS_BLUE].resize(option_size);
|
||||
for (i = 0; i < option_size; i++) {
|
||||
s->dev->gamma_override_tables[GENESYS_BLUE][i] = table[i];
|
||||
case OPT_GAMMA_VECTOR_B: {
|
||||
table = reinterpret_cast<SANE_Word*>(val);
|
||||
option_size = s->opt[option].size / sizeof (SANE_Word);
|
||||
dev->gamma_override_tables[GENESYS_BLUE].resize(option_size);
|
||||
for (i = 0; i < option_size; i++) {
|
||||
dev->gamma_override_tables[GENESYS_BLUE][i] = table[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OPT_CALIBRATE: {
|
||||
auto& sensor = sanei_genesys_find_sensor_for_write(s->dev, s->dev->settings.xres,
|
||||
s->dev->settings.get_channels(),
|
||||
s->dev->settings.scan_method);
|
||||
auto& sensor = sanei_genesys_find_sensor_for_write(dev, dev->settings.xres,
|
||||
dev->settings.get_channels(),
|
||||
dev->settings.scan_method);
|
||||
catch_all_exceptions(__func__, [&]()
|
||||
{
|
||||
s->dev->cmd_set->save_power(s->dev, false);
|
||||
genesys_scanner_calibration(s->dev, sensor);
|
||||
dev->cmd_set->save_power(dev, false);
|
||||
genesys_scanner_calibration(dev, sensor);
|
||||
});
|
||||
catch_all_exceptions(__func__, [&]()
|
||||
{
|
||||
s->dev->cmd_set->save_power(s->dev, true);
|
||||
dev->cmd_set->save_power(dev, true);
|
||||
});
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||
break;
|
||||
}
|
||||
case OPT_CLEAR_CALIBRATION:
|
||||
s->dev->calibration_cache.clear();
|
||||
case OPT_CLEAR_CALIBRATION: {
|
||||
dev->calibration_cache.clear();
|
||||
|
||||
/* remove file */
|
||||
unlink(s->dev->calib_file.c_str());
|
||||
/* signals that sensors will have to be read again */
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||
break;
|
||||
case OPT_FORCE_CALIBRATION:
|
||||
s->dev->force_calibration = 1;
|
||||
s->dev->calibration_cache.clear();
|
||||
s->dev->calib_file.clear();
|
||||
|
||||
/* signals that sensors will have to be read again */
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||
break;
|
||||
|
||||
case OPT_IGNORE_OFFSETS: {
|
||||
s->dev->ignore_offsets = true;
|
||||
// remove file
|
||||
unlink(dev->calib_file.c_str());
|
||||
// signals that sensors will have to be read again
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DBG(DBG_warn, "%s: can't set unknown option %d\n", __func__, option);
|
||||
case OPT_FORCE_CALIBRATION: {
|
||||
dev->force_calibration = 1;
|
||||
dev->calibration_cache.clear();
|
||||
dev->calib_file.clear();
|
||||
|
||||
// signals that sensors will have to be read again
|
||||
*myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||
break;
|
||||
}
|
||||
|
||||
case OPT_IGNORE_OFFSETS: {
|
||||
dev->ignore_offsets = true;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
DBG(DBG_warn, "%s: can't set unknown option %d\n", __func__, option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6267,13 +6298,13 @@ void sane_get_parameters_impl(SANE_Handle handle, SANE_Parameters* params)
|
|||
{
|
||||
DBG_HELPER(dbg);
|
||||
Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle);
|
||||
auto* dev = s->dev;
|
||||
|
||||
/* don't recompute parameters once data reading is active, ie during scan */
|
||||
if (!s->dev->read_active) {
|
||||
if (!dev->read_active) {
|
||||
calc_parameters(s);
|
||||
}
|
||||
if (params)
|
||||
{
|
||||
if (params) {
|
||||
*params = s->params;
|
||||
|
||||
/* in the case of a sheetfed scanner, when full height is specified
|
||||
|
|
@ -6281,11 +6312,11 @@ void sane_get_parameters_impl(SANE_Handle handle, SANE_Parameters* params)
|
|||
* don't know the real document height.
|
||||
* We don't do that doing buffering image for digital processing
|
||||
*/
|
||||
if (s->dev->model->is_sheetfed &&
|
||||
if (dev->model->is_sheetfed &&
|
||||
s->pos_bottom_right_y == s->opt[OPT_BR_Y].constraint.range->max)
|
||||
{
|
||||
params->lines = -1;
|
||||
}
|
||||
params->lines = -1;
|
||||
}
|
||||
}
|
||||
debug_dump(DBG_proc, *params);
|
||||
}
|
||||
|
|
@ -6303,6 +6334,7 @@ void sane_start_impl(SANE_Handle handle)
|
|||
{
|
||||
DBG_HELPER(dbg);
|
||||
Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle);
|
||||
auto* dev = s->dev;
|
||||
|
||||
if (s->pos_top_left_x >= s->pos_bottom_right_x) {
|
||||
throw SaneException("top left x >= bottom right x");
|
||||
|
|
@ -6312,33 +6344,33 @@ void sane_start_impl(SANE_Handle handle)
|
|||
}
|
||||
|
||||
// fetch stored calibration
|
||||
if (s->dev->force_calibration == 0) {
|
||||
auto path = calibration_filename(s->dev);
|
||||
if (dev->force_calibration == 0) {
|
||||
auto path = calibration_filename(dev);
|
||||
s->calibration_file = path;
|
||||
s->dev->calib_file = path;
|
||||
dev->calib_file = path;
|
||||
DBG(DBG_info, "%s: Calibration filename set to:\n", __func__);
|
||||
DBG(DBG_info, "%s: >%s<\n", __func__, s->dev->calib_file.c_str());
|
||||
DBG(DBG_info, "%s: >%s<\n", __func__, dev->calib_file.c_str());
|
||||
|
||||
catch_all_exceptions(__func__, [&]()
|
||||
{
|
||||
sanei_genesys_read_calibration(s->dev->calibration_cache, s->dev->calib_file);
|
||||
sanei_genesys_read_calibration(dev->calibration_cache, dev->calib_file);
|
||||
});
|
||||
}
|
||||
|
||||
/* First make sure we have a current parameter set. Some of the
|
||||
parameters will be overwritten below, but that's OK. */
|
||||
// First make sure we have a current parameter set. Some of the
|
||||
// parameters will be overwritten below, but that's OK.
|
||||
|
||||
calc_parameters(s);
|
||||
genesys_start_scan(s->dev, s->lamp_off);
|
||||
genesys_start_scan(dev, s->lamp_off);
|
||||
|
||||
s->scanning = true;
|
||||
|
||||
/* allocate intermediate buffer when doing dynamic lineart */
|
||||
if (s->dev->settings.scan_mode == ScanColorMode::LINEART) {
|
||||
s->dev->binarize_buffer.clear();
|
||||
s->dev->binarize_buffer.alloc(s->dev->settings.pixels);
|
||||
s->dev->local_buffer.clear();
|
||||
s->dev->local_buffer.alloc(s->dev->binarize_buffer.size() * 8);
|
||||
// allocate intermediate buffer when doing dynamic lineart
|
||||
if (dev->settings.scan_mode == ScanColorMode::LINEART) {
|
||||
dev->binarize_buffer.clear();
|
||||
dev->binarize_buffer.alloc(dev->settings.pixels);
|
||||
dev->local_buffer.clear();
|
||||
dev->local_buffer.alloc(dev->binarize_buffer.size() * 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6355,14 +6387,13 @@ void sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_
|
|||
{
|
||||
DBG_HELPER(dbg);
|
||||
Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle);
|
||||
Genesys_Device *dev;
|
||||
size_t local_len;
|
||||
|
||||
if (!s) {
|
||||
throw SaneException("handle is nullptr");
|
||||
}
|
||||
|
||||
dev=s->dev;
|
||||
auto* dev = s->dev;
|
||||
if (!dev) {
|
||||
throw SaneException("dev is nullptr");
|
||||
}
|
||||
|
|
@ -6460,35 +6491,31 @@ void sane_cancel_impl(SANE_Handle handle)
|
|||
{
|
||||
DBG_HELPER(dbg);
|
||||
Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle);
|
||||
auto* dev = s->dev;
|
||||
|
||||
s->scanning = false;
|
||||
s->dev->read_active = false;
|
||||
dev->read_active = false;
|
||||
|
||||
/* no need to end scan if we are parking the head */
|
||||
if (!s->dev->parking) {
|
||||
s->dev->cmd_set->end_scan(s->dev, &s->dev->reg, true);
|
||||
// no need to end scan if we are parking the head
|
||||
if (!dev->parking) {
|
||||
dev->cmd_set->end_scan(dev, &dev->reg, true);
|
||||
}
|
||||
|
||||
/* park head if flatbed scanner */
|
||||
if (!s->dev->model->is_sheetfed) {
|
||||
if (!s->dev->parking) {
|
||||
s->dev->cmd_set->move_back_home (s->dev, has_flag(s->dev->model->flags,
|
||||
ModelFlag::MUST_WAIT));
|
||||
|
||||
s->dev->parking = !has_flag(s->dev->model->flags, ModelFlag::MUST_WAIT);
|
||||
// park head if flatbed scanner
|
||||
if (!dev->model->is_sheetfed) {
|
||||
if (!dev->parking) {
|
||||
dev->cmd_set->move_back_home(dev, has_flag(dev->model->flags, ModelFlag::MUST_WAIT));
|
||||
dev->parking = !has_flag(dev->model->flags, ModelFlag::MUST_WAIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* in case of sheetfed scanners, we have to eject the document if still present */
|
||||
s->dev->cmd_set->eject_document(s->dev);
|
||||
} else {
|
||||
// in case of sheetfed scanners, we have to eject the document if still present
|
||||
dev->cmd_set->eject_document(dev);
|
||||
}
|
||||
|
||||
/* enable power saving mode unless we are parking .... */
|
||||
if (!s->dev->parking) {
|
||||
s->dev->cmd_set->save_power(s->dev, true);
|
||||
// enable power saving mode unless we are parking ....
|
||||
if (!dev->parking) {
|
||||
dev->cmd_set->save_power(dev, true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SANE_GENESYS_API_LINKAGE
|
||||
|
|
|
|||
|
|
@ -225,16 +225,16 @@ extern void sanei_genesys_write_ahb(Genesys_Device* dev, uint32_t addr, uint32_t
|
|||
|
||||
extern void sanei_genesys_init_structs (Genesys_Device * dev);
|
||||
|
||||
const Genesys_Sensor& sanei_genesys_find_sensor_any(Genesys_Device* dev);
|
||||
const Genesys_Sensor& sanei_genesys_find_sensor(Genesys_Device* dev, unsigned dpi,
|
||||
const Genesys_Sensor& sanei_genesys_find_sensor_any(const Genesys_Device* dev);
|
||||
const Genesys_Sensor& sanei_genesys_find_sensor(const Genesys_Device* dev, unsigned dpi,
|
||||
unsigned channels, ScanMethod scan_method);
|
||||
bool sanei_genesys_has_sensor(Genesys_Device* dev, unsigned dpi, unsigned channels,
|
||||
bool sanei_genesys_has_sensor(const Genesys_Device* dev, unsigned dpi, unsigned channels,
|
||||
ScanMethod scan_method);
|
||||
Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, unsigned dpi,
|
||||
unsigned channels, ScanMethod scan_method);
|
||||
|
||||
std::vector<std::reference_wrapper<const Genesys_Sensor>>
|
||||
sanei_genesys_find_sensors_all(Genesys_Device* dev, ScanMethod scan_method);
|
||||
sanei_genesys_find_sensors_all(const Genesys_Device* dev, ScanMethod scan_method);
|
||||
std::vector<std::reference_wrapper<Genesys_Sensor>>
|
||||
sanei_genesys_find_sensors_all_for_write(Genesys_Device* dev, ScanMethod scan_method);
|
||||
|
||||
|
|
|
|||
|
|
@ -199,7 +199,19 @@ private:
|
|||
};
|
||||
|
||||
|
||||
void build_checkpoint(const genesys::Genesys_Device& dev,
|
||||
void print_params(const SANE_Parameters& params, std::stringstream& out)
|
||||
{
|
||||
out << "\n\n================\n"
|
||||
<< "Scan params:\n"
|
||||
<< "format: " << params.format << "\n"
|
||||
<< "last_frame: " << params.last_frame << "\n"
|
||||
<< "bytes_per_line: " << params.bytes_per_line << "\n"
|
||||
<< "pixels_per_line: " << params.pixels_per_line << "\n"
|
||||
<< "lines: " << params.lines << "\n"
|
||||
<< "depth: " << params.depth << "\n";
|
||||
}
|
||||
|
||||
void print_checkpoint(const genesys::Genesys_Device& dev,
|
||||
genesys::TestScannerInterface& iface,
|
||||
const std::string& checkpoint_name,
|
||||
std::stringstream& out)
|
||||
|
|
@ -240,15 +252,15 @@ void build_checkpoint(const genesys::Genesys_Device& dev,
|
|||
|
||||
void run_single_test_scan(const TestConfig& config, std::stringstream& out)
|
||||
{
|
||||
auto build_checkpoint_wrapper = [&](const genesys::Genesys_Device& dev,
|
||||
auto print_checkpoint_wrapper = [&](const genesys::Genesys_Device& dev,
|
||||
genesys::TestScannerInterface& iface,
|
||||
const std::string& checkpoint_name)
|
||||
{
|
||||
build_checkpoint(dev, iface, checkpoint_name, out);
|
||||
print_checkpoint(dev, iface, checkpoint_name, out);
|
||||
};
|
||||
|
||||
genesys::enable_testing_mode(config.vendor_id, config.product_id, config.bcd_device,
|
||||
build_checkpoint_wrapper);
|
||||
print_checkpoint_wrapper);
|
||||
|
||||
SANE_Handle handle;
|
||||
|
||||
|
|
@ -274,6 +286,8 @@ void run_single_test_scan(const TestConfig& config, std::stringstream& out)
|
|||
SANE_Parameters params;
|
||||
TIE(sane_get_parameters(handle, ¶ms));
|
||||
|
||||
print_params(params, out);
|
||||
|
||||
int buffer_size = 1024 * 1024;
|
||||
std::vector<std::uint8_t> buffer;
|
||||
buffer.resize(buffer_size);
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue