From 675497fcd818b2dcc716ce052bb90913091f8bc2 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:04 +0200 Subject: [PATCH] genesys: Use host-side gray instead of device-side true-gray on gl841 True gray mode is not handled correctly by devices: they have bugs that lead to incorrect LED color being emitted (e.g. dark red) and thus this feature is completely unusable. At least LiDE 35/40/50, LiDE 60 and LiDE 80 are affected. Simpy disabling true-gray unfortunately leads to even worse outcome because the scanner then simply proceeds to perform a color scan. To work around these problems we do a normal color scan and then produce gray output based on the color data. This will satisfy the use cases when correct gray is needed. In cases when it is sufficient to construct gray from a single color channel, the color filter setting could be used. --- backend/genesys/gl841.cpp | 43 ++++---------------------------- backend/genesys/tables_model.cpp | 3 +++ 2 files changed, 8 insertions(+), 38 deletions(-) diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index eb073fa23..bbe190b1c 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -818,7 +818,6 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens const ScanSession& session) { DBG_HELPER_ARGS(dbg, "exposure_time=%d", exposure_time); - std::uint16_t expavg, expr, expb, expg; dev->cmd_set->set_fe(dev, sensor, AFE_SET); @@ -875,11 +874,7 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens /* AFEMOD should depend on FESET, and we should set these * bits separately */ reg->find_reg(0x04).value &= ~(REG_0x04_FILTER | REG_0x04_AFEMOD); - if (has_flag(session.params.flags, ScanFlag::ENABLE_LEDADD)) { - reg->find_reg(0x04).value |= 0x10; /* no filter */ - } - else if (session.params.channels == 1) - { + if (session.params.channels == 1) { switch (session.params.color_filter) { case ColorFilter::RED: @@ -909,23 +904,6 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens /* CIS scanners can do true gray by setting LEDADD */ reg->find_reg(0x87).value &= ~REG_0x87_LEDADD; - if (has_flag(session.params.flags, ScanFlag::ENABLE_LEDADD)) { - reg->find_reg(0x87).value |= REG_0x87_LEDADD; - expr = reg->get16(REG_EXPR); - expg = reg->get16(REG_EXPG); - expb = reg->get16(REG_EXPB); - - /* use minimal exposure for best image quality */ - expavg = expg; - if (expr < expg) - expavg = expr; - if (expb < expavg) - expavg = expb; - - dev->reg.set16(REG_EXPR, expavg); - dev->reg.set16(REG_EXPG, expavg); - dev->reg.set16(REG_EXPB, expavg); - } // enable gamma tables if (should_enable_gamma(session, sensor)) { @@ -1051,6 +1029,9 @@ dummy \ scanned lines dev->total_bytes_read = 0; dev->total_bytes_to_read = session.output_line_bytes_requested * session.params.lines; + if (session.use_host_side_gray) { + dev->total_bytes_to_read /= 3; + } DBG(DBG_info, "%s: total bytes to send = %zu\n", __func__, dev->total_bytes_to_read); } @@ -1088,20 +1069,6 @@ ScanSession CommandSetGl841::calculate_scan_session(const Genesys_Device* dev, start += dev->settings.tl_x; start = static_cast((start * dev->settings.xres) / MM_PER_INCH); - // we enable true gray for cis scanners only, and just when doing - // scan since color calibration is OK for this mode - ScanFlag flags = ScanFlag::NONE; - - // true gray (led add for cis scanners) - if (dev->model->is_cis && - settings.color_filter == ColorFilter::NONE && - dev->settings.scan_mode != ScanColorMode::COLOR_SINGLE_PASS && - dev->model->sensor_id != SensorId::CIS_CANON_LIDE_80) - { - // on Lide 80 the LEDADD bit results in only red LED array being lit - flags |= ScanFlag::ENABLE_LEDADD; - } - ScanSession session; session.params.xres = dev->settings.xres; session.params.yres = dev->settings.yres; @@ -1117,7 +1084,7 @@ ScanSession CommandSetGl841::calculate_scan_session(const Genesys_Device* dev, session.params.color_filter = dev->settings.color_filter; session.params.contrast_adjustment = dev->settings.contrast; session.params.brightness_adjustment = dev->settings.brightness; - session.params.flags = flags; + session.params.flags = ScanFlag::NONE; compute_session(dev, session, sensor); return session; diff --git a/backend/genesys/tables_model.cpp b/backend/genesys/tables_model.cpp index acd933a89..7d77c6152 100644 --- a/backend/genesys/tables_model.cpp +++ b/backend/genesys/tables_model.cpp @@ -191,6 +191,7 @@ void genesys_init_usb_device_tables() model.gpio_id = GpioId::CANON_LIDE_35; model.motor_id = MotorId::CANON_LIDE_35; model.flags = ModelFlag::DARK_WHITE_CALIBRATION | + ModelFlag::HOST_SIDE_GRAY | ModelFlag::CUSTOM_GAMMA; model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | @@ -1110,6 +1111,7 @@ void genesys_init_usb_device_tables() model.gpio_id = GpioId::CANON_LIDE_35; model.motor_id = MotorId::CANON_LIDE_60; model.flags = ModelFlag::DARK_WHITE_CALIBRATION | + ModelFlag::HOST_SIDE_GRAY | ModelFlag::CUSTOM_GAMMA; model.buttons = GENESYS_HAS_COPY_SW | @@ -1165,6 +1167,7 @@ void genesys_init_usb_device_tables() model.gpio_id = GpioId::CANON_LIDE_80; model.motor_id = MotorId::CANON_LIDE_80; model.flags = ModelFlag::DARK_WHITE_CALIBRATION | + ModelFlag::HOST_SIDE_GRAY | ModelFlag::CUSTOM_GAMMA; model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW |