From a664ffddc26cc9366e8a3b44d42108382c6c9513 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sun, 26 Dec 2021 14:53:14 +0200 Subject: [PATCH 01/27] genesys: Store contrast and brightness adjustments in session params --- backend/genesys/genesys.cpp | 16 +++++++++++++++- backend/genesys/gl124.cpp | 8 ++++++++ backend/genesys/gl646.cpp | 16 ++++++++++++++++ backend/genesys/gl841.cpp | 10 ++++++++++ backend/genesys/gl842.cpp | 6 ++++++ backend/genesys/gl843.cpp | 6 ++++++ backend/genesys/gl846.cpp | 4 ++++ backend/genesys/gl847.cpp | 4 ++++ backend/genesys/settings.cpp | 2 ++ backend/genesys/settings.h | 12 +++++++++++- 10 files changed, 82 insertions(+), 2 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 543a6289b..5d07c12f2 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -795,6 +795,8 @@ void scanner_move(Genesys_Device& dev, ScanMethod scan_method, unsigned steps, D session.params.scan_method = scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::GREEN; + session.params.contrast_adjustment = dev.settings.contrast; + session.params.brightness_adjustment = dev.settings.brightness; session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA | @@ -959,6 +961,8 @@ void scanner_move_back_home(Genesys_Device& dev, bool wait_until_home) session.params.scan_method = dev.settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::GREEN; + session.params.contrast_adjustment = dev.settings.contrast; + session.params.brightness_adjustment = dev.settings.brightness; session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA | @@ -1100,6 +1104,8 @@ void scanner_move_back_home_ta(Genesys_Device& dev) session.params.scan_method = scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::GREEN; + session.params.contrast_adjustment = dev.settings.contrast; + session.params.brightness_adjustment = dev.settings.brightness; session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA | @@ -1210,6 +1216,8 @@ void scanner_search_strip(Genesys_Device& dev, bool forward, bool black) session.params.scan_method = dev.settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::RED; + session.params.contrast_adjustment = dev.settings.contrast; + session.params.brightness_adjustment = dev.settings.brightness; session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA; if (dev.model->asic_type != AsicType::GL841 && !forward) { @@ -1506,6 +1514,8 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; session.params.color_filter = dev.model->asic_type == AsicType::GL843 ? ColorFilter::RED : dev.settings.color_filter; + session.params.contrast_adjustment = dev.settings.contrast; + session.params.brightness_adjustment = dev.settings.brightness; session.params.flags = flags; compute_session(&dev, session, *calib_sensor); @@ -1815,6 +1825,8 @@ void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor& session.params.scan_method = dev.settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; 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; compute_session(&dev, session, *calib_sensor); @@ -2023,6 +2035,8 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor session.params.scan_method = dev.settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; 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 = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA | ScanFlag::SINGLE_LINE | @@ -5243,7 +5257,7 @@ static void probe_genesys_devices() of Genesys_Calibration_Cache as is. */ static const char* CALIBRATION_IDENT = "sane_genesys"; -static const int CALIBRATION_VERSION = 31; +static const int CALIBRATION_VERSION = 32; bool read_calibration(std::istream& str, Genesys_Device::Calibration& calibration, const std::string& path) diff --git a/backend/genesys/gl124.cpp b/backend/genesys/gl124.cpp index 94a4fed4e..ecd9b3bbd 100644 --- a/backend/genesys/gl124.cpp +++ b/backend/genesys/gl124.cpp @@ -815,6 +815,8 @@ ScanSession CommandSetGl124::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; + session.params.contrast_adjustment = dev->settings.contrast; + session.params.brightness_adjustment = dev->settings.brightness; session.params.flags = ScanFlag::NONE; compute_session(dev, session, sensor); @@ -983,6 +985,8 @@ void CommandSetGl124::init_regs_for_shading(Genesys_Device* dev, const Genesys_S session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; session.params.color_filter = ColorFilter::RED; + session.params.contrast_adjustment = dev->settings.contrast; + session.params.brightness_adjustment = dev->settings.brightness; session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA | ScanFlag::DISABLE_BUFFER_FULL_MOVE; @@ -1116,6 +1120,8 @@ void move_to_calibration_area(Genesys_Device* dev, const Genesys_Sensor& sensor, session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; 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 = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA | ScanFlag::SINGLE_LINE | @@ -1202,6 +1208,8 @@ void CommandSetGl124::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Se session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; 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; compute_session(dev, session, sensor); diff --git a/backend/genesys/gl646.cpp b/backend/genesys/gl646.cpp index acc1a4b8d..b792f21d0 100644 --- a/backend/genesys/gl646.cpp +++ b/backend/genesys/gl646.cpp @@ -1707,6 +1707,8 @@ void CommandSetGl646::move_back_home(Genesys_Device* dev, bool wait_until_home) session.params.scan_method = dev->model->default_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; session.params.color_filter = ColorFilter::RED; + session.params.contrast_adjustment = dev->settings.contrast; + session.params.brightness_adjustment = dev->settings.brightness; session.params.flags = ScanFlag::REVERSE | ScanFlag::AUTO_GO_HOME | ScanFlag::DISABLE_GAMMA; @@ -1823,6 +1825,8 @@ void CommandSetGl646::init_regs_for_shading(Genesys_Device* dev, const Genesys_S session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; 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 = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA | ScanFlag::IGNORE_COLOR_OFFSET | @@ -1931,6 +1935,8 @@ SensorExposure CommandSetGl646::led_calibration(Genesys_Device* dev, const Genes session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = scan_mode; session.params.color_filter = ColorFilter::RED; + session.params.contrast_adjustment = dev->settings.contrast; + session.params.brightness_adjustment = dev->settings.brightness; session.params.flags = ScanFlag::DISABLE_SHADING; if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) { session.params.flags |= ScanFlag::USE_XPA; @@ -2110,6 +2116,8 @@ static void ad_fe_offset_calibration(Genesys_Device* dev, const Genesys_Sensor& session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; session.params.color_filter = ColorFilter::RED; + session.params.contrast_adjustment = dev->settings.contrast; + session.params.brightness_adjustment = dev->settings.brightness; session.params.flags = ScanFlag::DISABLE_SHADING; if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) { session.params.flags |= ScanFlag::USE_XPA; @@ -2222,6 +2230,8 @@ void CommandSetGl646::offset_calibration(Genesys_Device* dev, const Genesys_Sens session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; session.params.color_filter = ColorFilter::RED; + session.params.contrast_adjustment = dev->settings.contrast; + session.params.brightness_adjustment = dev->settings.brightness; session.params.flags = ScanFlag::DISABLE_SHADING; if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) { session.params.flags |= ScanFlag::USE_XPA; @@ -2373,6 +2383,8 @@ void CommandSetGl646::coarse_gain_calibration(Genesys_Device* dev, const Genesys session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; session.params.color_filter = ColorFilter::RED; + session.params.contrast_adjustment = dev->settings.contrast; + session.params.brightness_adjustment = dev->settings.brightness; session.params.flags = ScanFlag::DISABLE_SHADING; if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) { session.params.flags |= ScanFlag::USE_XPA; @@ -2485,6 +2497,8 @@ void CommandSetGl646::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Se session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::RED; + session.params.contrast_adjustment = 0; + session.params.brightness_adjustment = 0; session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA; if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) { @@ -2966,6 +2980,8 @@ ScanSession CommandSetGl646::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; + session.params.contrast_adjustment = settings.contrast; + session.params.brightness_adjustment = settings.brightness; session.params.flags = ScanFlag::AUTO_GO_HOME; if (settings.scan_method == ScanMethod::TRANSPARENCY) { session.params.flags |= ScanFlag::USE_XPA; diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index 62e0e9d27..2d4cd7a9c 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -1132,6 +1132,8 @@ ScanSession CommandSetGl841::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = dev->settings.scan_mode; 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; compute_session(dev, session, sensor); @@ -1613,6 +1615,8 @@ void CommandSetGl841::init_regs_for_shading(Genesys_Device* dev, const Genesys_S session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; 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 = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA; compute_session(dev, session, calib_sensor); @@ -1690,6 +1694,8 @@ static void ad_fe_offset_calibration(Genesys_Device* dev, const Genesys_Sensor& session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; 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 = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA | ScanFlag::SINGLE_LINE | @@ -1811,6 +1817,8 @@ void CommandSetGl841::offset_calibration(Genesys_Device* dev, const Genesys_Sens session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; 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 = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA | ScanFlag::SINGLE_LINE | @@ -2160,6 +2168,8 @@ void CommandSetGl841::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Se session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; session.params.color_filter = dev->settings.color_filter; + session.params.contrast_adjustment = 0; + session.params.brightness_adjustment = 0; session.params.flags = flags; compute_session(dev, session, sensor); diff --git a/backend/genesys/gl842.cpp b/backend/genesys/gl842.cpp index 9d3da67e1..2ad58d4e9 100644 --- a/backend/genesys/gl842.cpp +++ b/backend/genesys/gl842.cpp @@ -629,6 +629,8 @@ ScanSession CommandSetGl842::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; + session.params.contrast_adjustment = settings.contrast; + session.params.brightness_adjustment = settings.brightness; session.params.flags = flags; compute_session(dev, session, sensor); @@ -823,6 +825,8 @@ void CommandSetGl842::init_regs_for_shading(Genesys_Device* dev, const Genesys_S session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = dev->settings.scan_mode; 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; compute_session(dev, session, calib_sensor); @@ -916,6 +920,8 @@ void CommandSetGl842::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Se session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; session.params.color_filter = dev->settings.color_filter; + session.params.contrast_adjustment = 0; + session.params.brightness_adjustment = 0; session.params.flags = flags; compute_session(dev, session, calib_sensor); diff --git a/backend/genesys/gl843.cpp b/backend/genesys/gl843.cpp index f63f67545..86a08cac9 100644 --- a/backend/genesys/gl843.cpp +++ b/backend/genesys/gl843.cpp @@ -1122,6 +1122,8 @@ ScanSession CommandSetGl843::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; + session.params.contrast_adjustment = settings.contrast; + session.params.brightness_adjustment = settings.brightness; session.params.flags = flags; compute_session(dev, session, sensor); @@ -1433,6 +1435,8 @@ void CommandSetGl843::init_regs_for_shading(Genesys_Device* dev, const Genesys_S session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = dev->settings.scan_mode; 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; compute_session(dev, session, calib_sensor); @@ -1536,6 +1540,8 @@ void CommandSetGl843::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Se session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; session.params.color_filter = dev->settings.color_filter; + session.params.contrast_adjustment = 0; + session.params.brightness_adjustment = 0; session.params.flags = flags; compute_session(dev, session, calib_sensor); diff --git a/backend/genesys/gl846.cpp b/backend/genesys/gl846.cpp index c8907b26c..bf8778efd 100644 --- a/backend/genesys/gl846.cpp +++ b/backend/genesys/gl846.cpp @@ -759,6 +759,8 @@ ScanSession CommandSetGl846::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; + session.params.contrast_adjustment = settings.contrast; + session.params.brightness_adjustment = settings.brightness; // backtracking isn't handled well, so don't enable it session.params.flags = flags; @@ -882,6 +884,8 @@ void CommandSetGl846::init_regs_for_shading(Genesys_Device* dev, const Genesys_S session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; 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; compute_session(dev, session, calib_sensor); diff --git a/backend/genesys/gl847.cpp b/backend/genesys/gl847.cpp index 91ac4ebce..052c46610 100644 --- a/backend/genesys/gl847.cpp +++ b/backend/genesys/gl847.cpp @@ -735,6 +735,8 @@ ScanSession CommandSetGl847::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; + session.params.contrast_adjustment = settings.contrast; + session.params.brightness_adjustment = settings.brightness; session.params.flags = flags; compute_session(dev, session, sensor); @@ -900,6 +902,8 @@ void CommandSetGl847::init_regs_for_shading(Genesys_Device* dev, const Genesys_S session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; 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; compute_session(dev, session, calib_sensor); diff --git a/backend/genesys/settings.cpp b/backend/genesys/settings.cpp index 7f6479815..66b3929f9 100644 --- a/backend/genesys/settings.cpp +++ b/backend/genesys/settings.cpp @@ -86,6 +86,8 @@ std::ostream& operator<<(std::ostream& out, const SetupParams& params) << " channels: " << params.channels << '\n' << " scan_mode: " << params.scan_mode << '\n' << " color_filter: " << params.color_filter << '\n' + << " contrast_adjustment: " << params.contrast_adjustment << '\n' + << " brightness_adjustment: " << params.brightness_adjustment << '\n' << " flags: " << params.flags << '\n' << "}"; return out; diff --git a/backend/genesys/settings.h b/backend/genesys/settings.h index 4c834fa72..f95b12fe4 100644 --- a/backend/genesys/settings.h +++ b/backend/genesys/settings.h @@ -102,6 +102,7 @@ std::ostream& operator<<(std::ostream& out, const Genesys_Settings& settings); struct SetupParams { static constexpr unsigned NOT_SET = std::numeric_limits::max(); + static constexpr unsigned NOT_SET_I = std::numeric_limits::max(); // resolution in x direction unsigned xres = NOT_SET; @@ -136,6 +137,10 @@ struct SetupParams { ColorFilter color_filter = static_cast(NOT_SET); + // the values for contrast and brightness adjustment in the range of [-100..100] + int contrast_adjustment = NOT_SET_I; + int brightness_adjustment = NOT_SET_I; + ScanFlag flags = ScanFlag::NONE; unsigned get_requested_pixels() const @@ -152,7 +157,8 @@ struct SetupParams { pixels == NOT_SET || lines == NOT_SET ||depth == NOT_SET || channels == NOT_SET || scan_method == static_cast(NOT_SET) || scan_mode == static_cast(NOT_SET) || - color_filter == static_cast(NOT_SET)) + color_filter == static_cast(NOT_SET) || + contrast_adjustment == NOT_SET_I || brightness_adjustment == NOT_SET_I) { throw std::runtime_error("SetupParams are not valid"); } @@ -172,6 +178,8 @@ struct SetupParams { scan_method == other.scan_method && scan_mode == other.scan_mode && color_filter == other.color_filter && + contrast_adjustment == other.contrast_adjustment && + brightness_adjustment == other.brightness_adjustment && flags == other.flags; } }; @@ -193,6 +201,8 @@ void serialize(Stream& str, SetupParams& x) serialize(str, x.scan_method); serialize(str, x.scan_mode); serialize(str, x.color_filter); + serialize(str, x.contrast_adjustment); + serialize(str, x.brightness_adjustment); serialize(str, x.flags); } From aa795984f53e1ceb287dd197c1222199270e3aaf Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sun, 26 Dec 2021 14:53:15 +0200 Subject: [PATCH 02/27] genesys: Enable gamma setting when contrast or brightness is adjusted Brightness and contrast adjustments are handled via gamma tables and thus gamma functionality is required for these settings to have any effect. Previously if the device has a sensor with identity gamma (gamma = {1, 1, 1}), then gamma tables were turned off, consequently brightness and contrast settings had no effect. The underlying issue was identified by Gunnar Hjalmarsson and STK. --- backend/genesys/low.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/backend/genesys/low.cpp b/backend/genesys/low.cpp index ddd2c88f6..5e3b4c491 100644 --- a/backend/genesys/low.cpp +++ b/backend/genesys/low.cpp @@ -638,11 +638,16 @@ bool should_enable_gamma(const ScanSession& session, const Genesys_Sensor& senso if ((session.params.flags & ScanFlag::DISABLE_GAMMA) != ScanFlag::NONE) { return false; } + if (session.params.depth == 16) { + return false; + } + if (session.params.brightness_adjustment != 0 || session.params.contrast_adjustment != 0) { + return true; + } + if (sensor.gamma[0] == 1.0f || sensor.gamma[1] == 1.0f || sensor.gamma[2] == 1.0f) { return false; } - if (session.params.depth == 16) - return false; return true; } From 951bcf0f347860af0b7b33e1e160e84283f06b70 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:20:54 +0200 Subject: [PATCH 03/27] genesys: Remove unused two-table feeding support from gl124 --- backend/genesys/gl124.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/backend/genesys/gl124.cpp b/backend/genesys/gl124.cpp index ecd9b3bbd..aac8fe6e8 100644 --- a/backend/genesys/gl124.cpp +++ b/backend/genesys/gl124.cpp @@ -453,7 +453,6 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev, ScanFlag flags) { DBG_HELPER(dbg); - int use_fast_fed; unsigned int lincnt, fast_dpi; unsigned int feedl,dist; uint32_t z1, z2; @@ -467,9 +466,6 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev, feed_steps, static_cast(scan_mode), static_cast(flags)); - /* we never use fast fed since we do manual feed for the scans */ - use_fast_fed=0; - /* enforce motor minimal scan speed * @TODO extend motor struct for this value */ if (scan_mode == ScanColorMode::COLOR_SINGLE_PASS) @@ -516,12 +512,6 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev, /* compute register 02 value */ uint8_t r02 = REG_0x02_NOTHOME; - if (use_fast_fed) { - r02 |= REG_0x02_FASTFED; - } else { - r02 &= ~REG_0x02_FASTFED; - } - if (has_flag(flags, ScanFlag::AUTO_GO_HOME)) { r02 |= REG_0x02_AGOHOME; } @@ -573,9 +563,6 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev, if (has_flag(flags, ScanFlag::FEEDING)) { dist *= 2; } - if (use_fast_fed) { - dist += fast_table.table.size() * 2; - } /* get sure we don't use insane value */ if (dist < feedl) { @@ -587,7 +574,7 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev, reg->set24(REG_FEEDL, feedl); /* doesn't seem to matter that much */ - sanei_genesys_calculate_zmod(use_fast_fed, + sanei_genesys_calculate_zmod(false, scan_exposure_time, scan_table.table, scan_table.table.size(), From 6c9b10a897f140c340626007ecb17b6fd6263bb8 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:20:55 +0200 Subject: [PATCH 04/27] genesys: Remove unused two-table feeding support from gl846 --- backend/genesys/gl846.cpp | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/backend/genesys/gl846.cpp b/backend/genesys/gl846.cpp index bf8778efd..ee820928b 100644 --- a/backend/genesys/gl846.cpp +++ b/backend/genesys/gl846.cpp @@ -374,25 +374,13 @@ static void gl846_init_motor_regs_scan(Genesys_Device* dev, unsigned step_multiplier = gl846_get_step_multiplier(reg); - bool use_fast_fed = false; - if (dev->settings.yres == 4444 && feed_steps > 100 && !has_flag(flags, ScanFlag::FEEDING)) { - use_fast_fed = true; - } - if (has_flag(dev->model->flags, ModelFlag::DISABLE_FAST_FEEDING)) { - use_fast_fed = false; - } - reg->set24(REG_LINCNT, scan_lines); reg->set8(REG_0x02, 0); sanei_genesys_set_motor_power(*reg, true); std::uint8_t reg02 = reg->get8(REG_0x02); - if (use_fast_fed) { - reg02 |= REG_0x02_FASTFED; - } else { - reg02 &= ~REG_0x02_FASTFED; - } + reg02 &= ~REG_0x02_FASTFED; if (has_flag(flags, ScanFlag::AUTO_GO_HOME)) { reg02 |= REG_0x02_AGOHOME | REG_0x02_NOTHOME; @@ -446,18 +434,11 @@ static void gl846_init_motor_regs_scan(Genesys_Device* dev, unsigned feedl = feed_steps; unsigned dist = 0; - if (use_fast_fed) { - feedl <<= static_cast(fast_profile->step_type); - dist = (scan_table.table.size() + 2 * fast_table.table.size()); - // TODO read and decode REG_0xAB - dist += (reg->get8(0x5e) & 31); - dist += reg->get8(REG_FEDCNT); - } else { - feedl <<= static_cast(motor_profile.step_type); - dist = scan_table.table.size(); - if (has_flag(flags, ScanFlag::FEEDING)) { - dist *= 2; - } + + feedl <<= static_cast(motor_profile.step_type); + dist = scan_table.table.size(); + if (has_flag(flags, ScanFlag::FEEDING)) { + dist *= 2; } // check for overflow @@ -513,7 +494,7 @@ static void gl846_init_motor_regs_scan(Genesys_Device* dev, reg->set8(REG_BWDSTEP, min_restep); std::uint32_t z1, z2; - sanei_genesys_calculate_zmod(use_fast_fed, + sanei_genesys_calculate_zmod(false, scan_exposure_time * ccdlmt * tgtime, scan_table.table, scan_table.table.size(), From 512ad64c10f5a3c22ced41d657b4590313bf0427 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:20:56 +0200 Subject: [PATCH 05/27] genesys: Remove unused two-table feeding support from gl847 --- backend/genesys/gl847.cpp | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/backend/genesys/gl847.cpp b/backend/genesys/gl847.cpp index 052c46610..18b1e42bd 100644 --- a/backend/genesys/gl847.cpp +++ b/backend/genesys/gl847.cpp @@ -338,25 +338,13 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev, unsigned step_multiplier = gl847_get_step_multiplier (reg); - bool use_fast_fed = false; - if (dev->settings.yres == 4444 && feed_steps > 100 && !has_flag(flags, ScanFlag::FEEDING)) { - use_fast_fed = true; - } - if (has_flag(dev->model->flags, ModelFlag::DISABLE_FAST_FEEDING)) { - use_fast_fed = false; - } - reg->set24(REG_LINCNT, scan_lines); reg->set8(REG_0x02, 0); sanei_genesys_set_motor_power(*reg, true); std::uint8_t reg02 = reg->get8(REG_0x02); - if (use_fast_fed) { - reg02 |= REG_0x02_FASTFED; - } else { - reg02 &= ~REG_0x02_FASTFED; - } + reg02 &= ~REG_0x02_FASTFED; if (has_flag(flags, ScanFlag::AUTO_GO_HOME)) { reg02 |= REG_0x02_AGOHOME | REG_0x02_NOTHOME; @@ -402,19 +390,11 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev, // correct move distance by acceleration and deceleration amounts unsigned feedl = feed_steps; unsigned dist = 0; - if (use_fast_fed) - { - feedl <<= static_cast(fast_step_type); - dist = (scan_table.table.size() + 2 * fast_table.table.size()); - // TODO read and decode REG_0xAB - dist += (reg->get8(0x5e) & 31); - dist += reg->get8(REG_FEDCNT); - } else { - feedl <<= static_cast(motor_profile.step_type); - dist = scan_table.table.size(); - if (has_flag(flags, ScanFlag::FEEDING)) { - dist *= 2; - } + + feedl <<= static_cast(motor_profile.step_type); + dist = scan_table.table.size(); + if (has_flag(flags, ScanFlag::FEEDING)) { + dist *= 2; } // check for overflow @@ -456,7 +436,7 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev, reg->set8(REG_BWDSTEP, min_restep); std::uint32_t z1, z2; - sanei_genesys_calculate_zmod(use_fast_fed, + sanei_genesys_calculate_zmod(false, scan_exposure_time * ccdlmt * tgtime, scan_table.table, scan_table.table.size(), From 3574aac3d41492d0d0daed430815349c516091be Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:20:57 +0200 Subject: [PATCH 06/27] genesys: Remove broken two-table feeding support from gl841 At least on LiDE 50 two-table feeding caused unexplained motor spin-up failures on certain motor exposures. Various register modifications showed that there's high likelihood on device-side bug. Even the official drivers don't use proper two-table feeding. --- backend/genesys/gl841.cpp | 60 +-------------------------------------- 1 file changed, 1 insertion(+), 59 deletions(-) diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index 2d4cd7a9c..2a7a3041d 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -541,7 +541,6 @@ static void gl841_init_motor_regs_feed(Genesys_Device* dev, const Genesys_Sensor { DBG_HELPER_ARGS(dbg, "feed_steps=%d, flags=%x", feed_steps, static_cast(flags)); unsigned step_multiplier = 2; - int use_fast_fed = 0; unsigned int feedl; /*number of scan lines to add in a scan_lines line*/ @@ -572,10 +571,6 @@ static void gl841_init_motor_regs_feed(Genesys_Device* dev, const Genesys_Sensor // BUG: fast table is counted in base_ydpi / 4 feedl = feed_steps - fast_table.table.size() * 2; - use_fast_fed = 1; - if (has_flag(dev->model->flags, ModelFlag::DISABLE_FAST_FEEDING)) { - use_fast_fed = false; - } reg->set8(0x3d, (feedl >> 16) & 0xf); reg->set8(0x3e, (feedl >> 8) & 0xff); @@ -590,10 +585,6 @@ static void gl841_init_motor_regs_feed(Genesys_Device* dev, const Genesys_Sensor reg->find_reg(0x02).value &= ~0x80; /*NOT_HOME OFF*/ reg->find_reg(0x02).value |= REG_0x02_MTRPWR; - - if (use_fast_fed) - reg->find_reg(0x02).value |= 0x08; - else reg->find_reg(0x02).value &= ~0x08; if (has_flag(flags, ScanFlag::AUTO_GO_HOME)) { @@ -640,9 +631,6 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor unsigned step_multiplier = 2; - int use_fast_fed = 0; - unsigned int fast_time; - unsigned int slow_time; unsigned int feedl; unsigned int min_restep = 0x20; @@ -679,54 +667,11 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor fast_table.slice_steps(max_fast_slope_steps_count, step_multiplier); } - /* fast fed special cases handling */ - if (dev->model->gpio_id == GpioId::XP300 - || dev->model->gpio_id == GpioId::DP685) - { - /* quirk: looks like at least this scanner is unable to use - 2-feed mode */ - use_fast_fed = 0; - } - else if (feed_steps < fast_table.table.size() * 2 + - (slow_table.table.size() >> static_cast(motor_profile.step_type))) - { - use_fast_fed = 0; - DBG(DBG_info, "%s: feed too short, slow move forced.\n", __func__); - } else { -/* for deciding whether we should use fast mode we need to check how long we - need for (fast)accelerating, moving, decelerating, (TODO: stopping?) - (slow)accelerating again versus (slow)accelerating and moving. we need - fast and slow tables here. -*/ -/*NOTE: scan_exposure_time is per scan_yres*/ -/*NOTE: fast_exposure is per base_ydpi/4*/ -/*we use full steps as base unit here*/ - fast_time = - (fast_table.table.back() << static_cast(fast_profile->step_type)) / 4 * - (feed_steps - fast_table.table.size()*2 - - (slow_table.table.size() >> static_cast(motor_profile.step_type))) - + fast_table.pixeltime_sum() * 2 + slow_table.pixeltime_sum(); - slow_time = - (scan_exposure_time * scan_yres) / dev->motor.base_ydpi * - (feed_steps - (slow_table.table.size() >> static_cast(motor_profile.step_type))) - + slow_table.pixeltime_sum(); - - use_fast_fed = fast_time < slow_time; - } - - if (has_flag(dev->model->flags, ModelFlag::DISABLE_FAST_FEEDING)) { - use_fast_fed = false; - } - - if (use_fast_fed) { - feedl = feed_steps - fast_table.table.size() * 2 - - (slow_table.table.size() >> static_cast(motor_profile.step_type)); - } else if ((feed_steps << static_cast(motor_profile.step_type)) < slow_table.table.size()) { + if ((feed_steps << static_cast(motor_profile.step_type)) < slow_table.table.size()) { feedl = 0; } else { feedl = (feed_steps << static_cast(motor_profile.step_type)) - slow_table.table.size(); } - DBG(DBG_info, "%s: Decided to use %s mode\n", __func__, use_fast_fed?"fast feed":"slow feed"); reg->set8(0x3d, (feedl >> 16) & 0xf); reg->set8(0x3e, (feedl >> 8) & 0xff); @@ -743,9 +688,6 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor reg->find_reg(0x02).value &= ~REG_0x02_MTRREV; } - if (use_fast_fed) - reg->find_reg(0x02).value |= 0x08; - else reg->find_reg(0x02).value &= ~0x08; if (has_flag(flags, ScanFlag::AUTO_GO_HOME)) From d14b71b3ad19daeab09db433e6cae37a71da48b0 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:20:58 +0200 Subject: [PATCH 07/27] genesys: Inline gl841_get_led_exposure() --- backend/genesys/gl841.cpp | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index 2a7a3041d..d7665ddbb 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -888,27 +888,6 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens reg->set8(0x34, sensor.dummy_pixel); } -static int -gl841_get_led_exposure(Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int d,r,g,b,m; - if (!dev->model->is_cis) - return 0; - d = dev->reg.find_reg(0x19).value; - - r = sensor.exposure.red; - g = sensor.exposure.green; - b = sensor.exposure.blue; - - m = r; - if (m < g) - m = g; - if (m < b) - m = b; - - return m + d; -} - /** @brief compute exposure time * Compute exposure time for the device and the given scan resolution */ @@ -917,9 +896,13 @@ static int gl841_exposure_time(Genesys_Device *dev, const Genesys_Sensor& sensor int start, int used_pixels) { -int led_exposure; - - led_exposure=gl841_get_led_exposure(dev, sensor); + int led_exposure = 0; + if (dev->model->is_cis) { + unsigned dummy = dev->reg.find_reg(0x19).value; + unsigned min_sensor_exposure = std::min({sensor.exposure.red, sensor.exposure.green, + sensor.exposure.blue}); + led_exposure = dummy + min_sensor_exposure; + } return sanei_genesys_exposure_time2(dev, profile, slope_dpi, start + used_pixels,/*+tgtime? currently done in sanei_genesys_exposure_time2 with tgtime = 32 pixel*/ led_exposure); From cd51c58c4548fb30d7cddac33bed44f4489b7a6f Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:20:59 +0200 Subject: [PATCH 08/27] genesys: Fix incorrect scan exposure setup on gl841 When sensor exposure values are significantly different from each other the total scan exposure will be too low leading to the device becoming confused and significantly --- backend/genesys/gl841.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index d7665ddbb..d90ae388e 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -899,9 +899,9 @@ static int gl841_exposure_time(Genesys_Device *dev, const Genesys_Sensor& sensor int led_exposure = 0; if (dev->model->is_cis) { unsigned dummy = dev->reg.find_reg(0x19).value; - unsigned min_sensor_exposure = std::min({sensor.exposure.red, sensor.exposure.green, + unsigned max_sensor_exposure = std::max({sensor.exposure.red, sensor.exposure.green, sensor.exposure.blue}); - led_exposure = dummy + min_sensor_exposure; + led_exposure = dummy + max_sensor_exposure; } return sanei_genesys_exposure_time2(dev, profile, slope_dpi, start + used_pixels,/*+tgtime? currently done in sanei_genesys_exposure_time2 with tgtime = 32 pixel*/ From 3f306231b52c491e703d3ea31273121832f58f20 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:00 +0200 Subject: [PATCH 09/27] genesys: Remove true_gray variable by deriving its value directly --- backend/genesys/genesys.cpp | 6 ------ backend/genesys/gl646.cpp | 4 +++- backend/genesys/gl841.cpp | 3 ++- backend/genesys/low.cpp | 3 ++- backend/genesys/settings.h | 3 --- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 5d07c12f2..050a1b609 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -4380,12 +4380,6 @@ static Genesys_Settings calculate_scan_settings(Genesys_Scanner* s) settings.color_filter = ColorFilter::NONE; } - if (s->color_filter == "None") { - settings.true_gray = 1; - } else { - settings.true_gray = 0; - } - // brightness and contrast only for for 8 bit scans if (s->bit_depth == 8) { settings.contrast = (s->contrast * 127) / 100; diff --git a/backend/genesys/gl646.cpp b/backend/genesys/gl646.cpp index b792f21d0..db087f80e 100644 --- a/backend/genesys/gl646.cpp +++ b/backend/genesys/gl646.cpp @@ -605,7 +605,9 @@ void CommandSetGl646::init_regs_for_scan_session(Genesys_Device* dev, const Gene } /* true CIS gray if needed */ - if (dev->model->is_cis && session.params.channels == 1 && dev->settings.true_gray) { + if (dev->model->is_cis && session.params.channels == 1 && + session.params.color_filter == ColorFilter::NONE) + { regs->find_reg(0x05).value |= REG_0x05_LEDADD; } else { regs->find_reg(0x05).value &= ~REG_0x05_LEDADD; diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index d90ae388e..a79fa9449 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -1036,7 +1036,8 @@ ScanSession CommandSetGl841::calculate_scan_session(const Genesys_Device* dev, ScanFlag flags = ScanFlag::NONE; // true gray (led add for cis scanners) - if (dev->model->is_cis && dev->settings.true_gray && + 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) { diff --git a/backend/genesys/low.cpp b/backend/genesys/low.cpp index 5e3b4c491..34a830016 100644 --- a/backend/genesys/low.cpp +++ b/backend/genesys/low.cpp @@ -1119,7 +1119,8 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se dev->model->asic_type == AsicType::GL845 || dev->model->asic_type == AsicType::GL846) { - s.enable_ledadd = (s.params.channels == 1 && dev->model->is_cis && dev->settings.true_gray); + s.enable_ledadd = (s.params.channels == 1 && dev->model->is_cis && + s.params.color_filter == ColorFilter::NONE); } s.use_host_side_calib = sensor.use_host_side_calib; diff --git a/backend/genesys/settings.h b/backend/genesys/settings.h index f95b12fe4..d2b7f1fa8 100644 --- a/backend/genesys/settings.h +++ b/backend/genesys/settings.h @@ -76,9 +76,6 @@ struct Genesys_Settings ColorFilter color_filter = ColorFilter::NONE; - // true if scan is true gray, false if monochrome scan - int true_gray = 0; - // value for contrast enhancement in the [-100..100] range int contrast = 0; From 9d6883cc819fda72f2a7346533ee516a69c191fd Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:01 +0200 Subject: [PATCH 10/27] genesys: Rename ImagePipelineNodeMergeMono{Lines -> LinesToColor} --- backend/genesys/image_pipeline.cpp | 10 +++++----- backend/genesys/image_pipeline.h | 6 +++--- backend/genesys/low.cpp | 6 +++--- testsuite/backend/genesys/tests_image_pipeline.cpp | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/backend/genesys/image_pipeline.cpp b/backend/genesys/image_pipeline.cpp index 14e2f8de6..162b2e53d 100644 --- a/backend/genesys/image_pipeline.cpp +++ b/backend/genesys/image_pipeline.cpp @@ -304,8 +304,8 @@ bool ImagePipelineNodeInvert::get_next_row_data(std::uint8_t* out_data) return got_data; } -ImagePipelineNodeMergeMonoLines::ImagePipelineNodeMergeMonoLines(ImagePipelineNode& source, - ColorOrder color_order) : +ImagePipelineNodeMergeMonoLinesToColor::ImagePipelineNodeMergeMonoLinesToColor( + ImagePipelineNode& source, ColorOrder color_order) : source_(source), buffer_(source_.get_row_bytes()) { @@ -314,7 +314,7 @@ ImagePipelineNodeMergeMonoLines::ImagePipelineNodeMergeMonoLines(ImagePipelineNo output_format_ = get_output_format(source_.get_format(), color_order); } -bool ImagePipelineNodeMergeMonoLines::get_next_row_data(std::uint8_t* out_data) +bool ImagePipelineNodeMergeMonoLinesToColor::get_next_row_data(std::uint8_t* out_data) { bool got_data = true; @@ -341,8 +341,8 @@ bool ImagePipelineNodeMergeMonoLines::get_next_row_data(std::uint8_t* out_data) return got_data; } -PixelFormat ImagePipelineNodeMergeMonoLines::get_output_format(PixelFormat input_format, - ColorOrder order) +PixelFormat ImagePipelineNodeMergeMonoLinesToColor::get_output_format(PixelFormat input_format, + ColorOrder order) { switch (input_format) { case PixelFormat::I1: { diff --git a/backend/genesys/image_pipeline.h b/backend/genesys/image_pipeline.h index 3632b36eb..aaf8312f2 100644 --- a/backend/genesys/image_pipeline.h +++ b/backend/genesys/image_pipeline.h @@ -295,11 +295,11 @@ private: }; // A pipeline node that merges 3 mono lines into a color channel -class ImagePipelineNodeMergeMonoLines : public ImagePipelineNode +class ImagePipelineNodeMergeMonoLinesToColor : public ImagePipelineNode { public: - ImagePipelineNodeMergeMonoLines(ImagePipelineNode& source, - ColorOrder color_order); + ImagePipelineNodeMergeMonoLinesToColor(ImagePipelineNode& source, + ColorOrder color_order); std::size_t get_width() const override { return source_.get_width(); } std::size_t get_height() const override { return source_.get_height() / 3; } diff --git a/backend/genesys/low.cpp b/backend/genesys/low.cpp index 34a830016..b63fe30a6 100644 --- a/backend/genesys/low.cpp +++ b/backend/genesys/low.cpp @@ -442,7 +442,7 @@ Image read_unshuffled_image_from_scanner(Genesys_Device* dev, const ScanSession& } if (dev->model->is_cis && session.params.channels == 3) { - pipeline.push_node(dev->model->line_mode_color_order); + pipeline.push_node(dev->model->line_mode_color_order); } if (pipeline.get_output_format() == PixelFormat::BGR888) { @@ -540,7 +540,7 @@ Image read_shuffled_image_from_scanner(Genesys_Device* dev, const ScanSession& s } if (dev->model->is_cis && session.params.channels == 3) { - pipeline.push_node(dev->model->line_mode_color_order); + pipeline.push_node(dev->model->line_mode_color_order); } if (pipeline.get_output_format() == PixelFormat::BGR888) { @@ -1218,7 +1218,7 @@ ImagePipelineStack build_image_pipeline(const Genesys_Device& dev, const ScanSes } if (dev.model->is_cis && session.params.channels == 3) { - pipeline.push_node(dev.model->line_mode_color_order); + pipeline.push_node(dev.model->line_mode_color_order); if (log_image_data) { pipeline.push_node(debug_prefix + "_4_after_merge_mono.tiff"); diff --git a/testsuite/backend/genesys/tests_image_pipeline.cpp b/testsuite/backend/genesys/tests_image_pipeline.cpp index 8edeff8ab..7baebd6e4 100644 --- a/testsuite/backend/genesys/tests_image_pipeline.cpp +++ b/testsuite/backend/genesys/tests_image_pipeline.cpp @@ -468,7 +468,7 @@ void test_node_invert_1_bits() ASSERT_EQ(out_data, expected_data); } -void test_node_merge_mono_lines() +void test_node_merge_mono_lines_to_color() { using Data = std::vector; @@ -481,7 +481,7 @@ void test_node_merge_mono_lines() ImagePipelineStack stack; stack.push_first_node(8, 3, PixelFormat::I8, std::move(in_data)); - stack.push_node(ColorOrder::RGB); + stack.push_node(ColorOrder::RGB); ASSERT_EQ(stack.get_output_width(), 8u); ASSERT_EQ(stack.get_output_height(), 1u); @@ -937,7 +937,7 @@ void test_image_pipeline() test_node_invert_16_bits(); test_node_invert_8_bits(); test_node_invert_1_bits(); - test_node_merge_mono_lines(); + test_node_merge_mono_lines_to_color(); test_node_split_mono_lines(); test_node_component_shift_lines(); test_node_pixel_shift_columns_no_switch(); From a8219f15ab018e042c0237ac3f024ff4762cf1e0 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:02 +0200 Subject: [PATCH 11/27] genesys: Implement image pipeline for merging color channels to gray --- backend/genesys/image_pipeline.cpp | 69 +++++++++++++++++++ backend/genesys/image_pipeline.h | 27 ++++++++ .../backend/genesys/tests_image_pipeline.cpp | 32 +++++++++ 3 files changed, 128 insertions(+) diff --git a/backend/genesys/image_pipeline.cpp b/backend/genesys/image_pipeline.cpp index 162b2e53d..6c178eda7 100644 --- a/backend/genesys/image_pipeline.cpp +++ b/backend/genesys/image_pipeline.cpp @@ -417,6 +417,75 @@ PixelFormat ImagePipelineNodeSplitMonoLines::get_output_format(PixelFormat input throw SaneException("Unsupported input format %d", static_cast(input_format)); } + +ImagePipelineNodeMergeColorToGray::ImagePipelineNodeMergeColorToGray(ImagePipelineNode& source) : + source_(source) +{ + + output_format_ = get_output_format(source_.get_format()); + float red_mult = 0.2125f; + float green_mult = 0.7154f; + float blue_mult = 0.0721f; + + switch (get_pixel_format_color_order(source_.get_format())) { + case ColorOrder::RGB: { + ch0_mult_ = red_mult; + ch1_mult_ = green_mult; + ch2_mult_ = blue_mult; + break; + } + case ColorOrder::BGR: { + ch0_mult_ = blue_mult; + ch1_mult_ = green_mult; + ch2_mult_ = red_mult; + break; + } + case ColorOrder::GBR: { + ch0_mult_ = green_mult; + ch1_mult_ = blue_mult; + ch2_mult_ = red_mult; + break; + } + default: + throw SaneException("Unknown color order"); + } + temp_buffer_.resize(source_.get_row_bytes()); +} + +bool ImagePipelineNodeMergeColorToGray::get_next_row_data(std::uint8_t* out_data) +{ + auto* src_data = temp_buffer_.data(); + + bool got_data = source_.get_next_row_data(src_data); + + auto src_format = source_.get_format(); + + for (std::size_t x = 0, width = get_width(); x < width; ++x) { + std::uint16_t ch0 = get_raw_channel_from_row(src_data, x, 0, src_format); + std::uint16_t ch1 = get_raw_channel_from_row(src_data, x, 1, src_format); + std::uint16_t ch2 = get_raw_channel_from_row(src_data, x, 2, src_format); + float mono = ch0 * ch0_mult_ + ch1 * ch1_mult_ + ch2 * ch2_mult_; + set_raw_channel_to_row(out_data, x, 0, static_cast(mono), output_format_); + } + return got_data; +} + +PixelFormat ImagePipelineNodeMergeColorToGray::get_output_format(PixelFormat input_format) +{ + switch (input_format) { + case PixelFormat::RGB111: + return PixelFormat::I1; + case PixelFormat::RGB888: + case PixelFormat::BGR888: + return PixelFormat::I8; + case PixelFormat::RGB161616: + case PixelFormat::BGR161616: + return PixelFormat::I16; + default: break; + } + throw SaneException("Unsupported format %d", static_cast(input_format)); +} + ImagePipelineNodeComponentShiftLines::ImagePipelineNodeComponentShiftLines( ImagePipelineNode& source, unsigned shift_r, unsigned shift_g, unsigned shift_b) : source_(source), diff --git a/backend/genesys/image_pipeline.h b/backend/genesys/image_pipeline.h index aaf8312f2..8e4915514 100644 --- a/backend/genesys/image_pipeline.h +++ b/backend/genesys/image_pipeline.h @@ -342,6 +342,33 @@ private: unsigned next_channel_ = 0; }; + +// A pipeline node that merges 3 mono lines into a gray channel +class ImagePipelineNodeMergeColorToGray : public ImagePipelineNode +{ +public: + ImagePipelineNodeMergeColorToGray(ImagePipelineNode& source); + + std::size_t get_width() const override { return source_.get_width(); } + std::size_t get_height() const override { return source_.get_height(); } + PixelFormat get_format() const override { return output_format_; } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + static PixelFormat get_output_format(PixelFormat input_format); + + ImagePipelineNode& source_; + PixelFormat output_format_ = PixelFormat::UNKNOWN; + float ch0_mult_ = 0; + float ch1_mult_ = 0; + float ch2_mult_ = 0; + + std::vector temp_buffer_; +}; + // A pipeline node that shifts colors across lines by the given offsets class ImagePipelineNodeComponentShiftLines : public ImagePipelineNode { diff --git a/testsuite/backend/genesys/tests_image_pipeline.cpp b/testsuite/backend/genesys/tests_image_pipeline.cpp index 7baebd6e4..8c46e8d89 100644 --- a/testsuite/backend/genesys/tests_image_pipeline.cpp +++ b/testsuite/backend/genesys/tests_image_pipeline.cpp @@ -500,6 +500,37 @@ void test_node_merge_mono_lines_to_color() ASSERT_EQ(out_data, expected_data); } +void test_node_merge_color_to_gray() +{ + using Data = std::vector; + + Data in_data = { + 0x10, 0x20, 0x30, 0x11, 0x21, 0x31, + 0x12, 0x22, 0x32, 0x13, 0x23, 0x33, + 0x14, 0x24, 0x34, 0x15, 0x25, 0x35, + 0x16, 0x26, 0x36, 0x17, 0x27, 0x37, + }; + + ImagePipelineStack stack; + stack.push_first_node(8, 1, PixelFormat::RGB888, + std::move(in_data)); + stack.push_node(); + + ASSERT_EQ(stack.get_output_width(), 8u); + ASSERT_EQ(stack.get_output_height(), 1u); + ASSERT_EQ(stack.get_output_row_bytes(), 8u); + ASSERT_EQ(stack.get_output_format(), PixelFormat::I8); + + auto out_data = stack.get_all_data(); + + Data expected_data = { + 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24 + }; + + ASSERT_EQ(out_data, expected_data); +} + + void test_node_split_mono_lines() { using Data = std::vector; @@ -938,6 +969,7 @@ void test_image_pipeline() test_node_invert_8_bits(); test_node_invert_1_bits(); test_node_merge_mono_lines_to_color(); + test_node_merge_color_to_gray(); test_node_split_mono_lines(); test_node_component_shift_lines(); test_node_pixel_shift_columns_no_switch(); From 9aabbbab904cb2048fc932b24f4d54bfdb07c217 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:03 +0200 Subject: [PATCH 12/27] genesys: Implement host-side gray support --- backend/genesys/enums.h | 3 +++ backend/genesys/low.cpp | 20 ++++++++++++++++++++ backend/genesys/settings.cpp | 4 +++- backend/genesys/settings.h | 4 ++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/backend/genesys/enums.h b/backend/genesys/enums.h index 9d7034bcf..f506988f4 100644 --- a/backend/genesys/enums.h +++ b/backend/genesys/enums.h @@ -526,6 +526,9 @@ enum class ModelFlag : unsigned // disable fast feeding mode on this scanner DISABLE_FAST_FEEDING = 1 << 14, + // scan gray scans as color and combine on host side + HOST_SIDE_GRAY = 1 << 15, + // the scanner uses multi-segment sensors that must be handled during calibration SIS_SENSOR = 1 << 16, diff --git a/backend/genesys/low.cpp b/backend/genesys/low.cpp index b63fe30a6..fb4660b40 100644 --- a/backend/genesys/low.cpp +++ b/backend/genesys/low.cpp @@ -445,6 +445,10 @@ Image read_unshuffled_image_from_scanner(Genesys_Device* dev, const ScanSession& pipeline.push_node(dev->model->line_mode_color_order); } + if (session.use_host_side_gray) { + pipeline.push_node(); + } + if (pipeline.get_output_format() == PixelFormat::BGR888) { pipeline.push_node(PixelFormat::RGB888); } @@ -954,6 +958,14 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se s.output_startx = static_cast( static_cast(s.params.startx) + sensor.output_pixel_offset); + if (has_flag(dev->model->flags, ModelFlag::HOST_SIDE_GRAY) && s.params.channels == 1 && + s.params.color_filter == ColorFilter::NONE) + { + s.use_host_side_gray = true; + s.params.channels = 3; + s.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + } + s.stagger_x = sensor.stagger_x; s.stagger_y = sensor.stagger_y; @@ -1280,6 +1292,14 @@ ImagePipelineStack build_image_pipeline(const Genesys_Device& dev, const ScanSes } } + if (session.use_host_side_gray) { + pipeline.push_node(); + + if (log_image_data) { + pipeline.push_node(debug_prefix + "_10_after_nogray.tiff"); + } + } + if (pipeline.get_output_width() != session.params.get_requested_pixels()) { pipeline.push_node(session.params.get_requested_pixels()); } diff --git a/backend/genesys/settings.cpp b/backend/genesys/settings.cpp index 66b3929f9..8eb06c819 100644 --- a/backend/genesys/settings.cpp +++ b/backend/genesys/settings.cpp @@ -129,7 +129,8 @@ bool ScanSession::operator==(const ScanSession& other) const shading_pixel_offset == other.shading_pixel_offset && buffer_size_read == other.buffer_size_read && enable_ledadd == other.enable_ledadd && - use_host_side_calib == other.use_host_side_calib; + use_host_side_calib == other.use_host_side_calib && + use_host_side_gray == other.use_host_side_gray; } std::ostream& operator<<(std::ostream& out, const ScanSession& session) @@ -166,6 +167,7 @@ std::ostream& operator<<(std::ostream& out, const ScanSession& session) << " buffer_size_read: " << session.buffer_size_read << '\n' << " enable_ledadd: " << session.enable_ledadd << '\n' << " use_host_side_calib: " << session.use_host_side_calib << '\n' + << " use_host_side_gray: " << session.use_host_side_gray << '\n' << " params: " << format_indent_braced_list(4, session.params) << '\n' << "}"; return out; diff --git a/backend/genesys/settings.h b/backend/genesys/settings.h index d2b7f1fa8..f92854442 100644 --- a/backend/genesys/settings.h +++ b/backend/genesys/settings.h @@ -324,6 +324,9 @@ struct ScanSession { // whether calibration should be performed host-side bool use_host_side_calib = false; + // whether gray scanning should be performed host-side (scan as color and merge to gray) + bool use_host_side_gray = false; + void assert_computed() const { if (!computed) { @@ -375,6 +378,7 @@ void serialize(Stream& str, ScanSession& x) serialize(str, x.buffer_size_read); serialize(str, x.enable_ledadd); serialize(str, x.use_host_side_calib); + serialize(str, x.use_host_side_gray); } std::ostream& operator<<(std::ostream& out, const SANE_Parameters& params); From 81a948a87a32354f09a97cb63fabc5ad5c996553 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:04 +0200 Subject: [PATCH 13/27] 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 | 44 ++++---------------------------- backend/genesys/tables_model.cpp | 3 +++ 2 files changed, 8 insertions(+), 39 deletions(-) diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index a79fa9449..c01de7997 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -761,8 +761,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); - uint16_t expavg, expr, expb, expg; - dev->cmd_set->set_fe(dev, sensor, AFE_SET); /* gpio part.*/ @@ -818,11 +816,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: @@ -852,23 +846,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)) { @@ -994,6 +971,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); } @@ -1031,20 +1011,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; @@ -1060,7 +1026,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 | From 14db0399823f1b0d8f1dd79e4db9e4918535cdfb Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:05 +0200 Subject: [PATCH 14/27] genesys: Remove duplicate register writes in gl841 calibration --- backend/genesys/genesys.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 050a1b609..4f34d0203 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -2102,16 +2102,6 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor for (unsigned i_test = 0; i_test < 100 && !acceptable; ++i_test) { regs_set_exposure(dev.model->asic_type, regs, { exp[0], exp[1], exp[2] }); - if (dev.model->asic_type == AsicType::GL841) { - // FIXME: remove - dev.interface->write_register(0x10, (exp[0] >> 8) & 0xff); - dev.interface->write_register(0x11, exp[0] & 0xff); - dev.interface->write_register(0x12, (exp[1] >> 8) & 0xff); - dev.interface->write_register(0x13, exp[1] & 0xff); - dev.interface->write_register(0x14, (exp[2] >> 8) & 0xff); - dev.interface->write_register(0x15, exp[2] & 0xff); - } - dev.interface->write_registers(regs); dbg.log(DBG_info, "starting line reading"); From 1f1be738569d6f7debb30c567310ce6375af0838 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:06 +0200 Subject: [PATCH 15/27] genesys: Use more robust gain calibration on gl841 --- backend/genesys/genesys.cpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 4f34d0203..1a901441d 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -1885,7 +1885,8 @@ void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor& float curr_output = 0; float target_value = 0; - if (dev.model->asic_type == AsicType::GL842 || + if (dev.model->asic_type == AsicType::GL841 || + dev.model->asic_type == AsicType::GL842 || dev.model->asic_type == AsicType::GL843) { std::vector values; @@ -1901,18 +1902,6 @@ void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor& curr_output = static_cast(values[unsigned((values.size() - 1) * 0.95)]); target_value = calib_sensor->gain_white_ref * coeff; - } else if (dev.model->asic_type == AsicType::GL841) { - // FIXME: use the GL843 approach - unsigned max = 0; - for (std::size_t x = 0; x < image.get_width(); x++) { - auto value = image.get_raw_channel(x, 0, ch); - if (value > max) { - max = value; - } - } - - curr_output = max; - target_value = 65535.0f; } else { // FIXME: use the GL843 approach auto width = image.get_width(); From a5816f9e94ce8383f9d7955665cf5dcaf05a88d6 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:07 +0200 Subject: [PATCH 16/27] genesys: Clean up exposure calibration on gl841 --- backend/genesys/genesys.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 1a901441d..2fda70f0f 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -2007,14 +2007,9 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor regs = dev.reg; // FIXME: apply this to all ASICs } - unsigned yres = resolution; - if (dev.model->asic_type == AsicType::GL841) { - yres = dev.settings.yres; // FIXME: remove this - } - ScanSession session; session.params.xres = resolution; - session.params.yres = yres; + session.params.yres = resolution; session.params.startx = 0; session.params.starty = 0; session.params.pixels = dev.model->x_size_calib_mm * resolution / MM_PER_INCH; From adb8617b5ff67005db82f8ffb02642e22959b98f Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:08 +0200 Subject: [PATCH 17/27] genesys: Remove erroneous register write on LiDE 80 --- backend/genesys/gl841.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index c01de7997..ee18961b9 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -330,11 +330,6 @@ gl841_init_registers (Genesys_Device * dev) dev->interface->write_0x8c(0x10, 0x94); dev->interface->write_register(0x09, 0x10); - - // FIXME: the following code originally changed 0x6b, but due to bug the 0x6c register was - // effectively changed. The current behavior matches the old code, but should probably be fixed. - dev->reg.find_reg(0x6c).value |= REG_0x6B_GPO18; - dev->reg.find_reg(0x6c).value &= ~REG_0x6B_GPO17; } } From 0e688eb9df9ba790ea1e6472b8cb8a8b38814efa Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:09 +0200 Subject: [PATCH 18/27] genesys: Reset registers after move during led calibration on gl841 --- backend/genesys/genesys.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 2fda70f0f..841361365 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -1999,7 +1999,8 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor const auto& calib_sensor = sanei_genesys_find_sensor(&dev, resolution, channels, dev.settings.scan_method); - if (dev.model->asic_type == AsicType::GL845 || + if (dev.model->asic_type == AsicType::GL841 || + dev.model->asic_type == AsicType::GL845 || dev.model->asic_type == AsicType::GL846 || dev.model->asic_type == AsicType::GL847 || dev.model->asic_type == AsicType::GL124) From c88bf56d8f43e23b8e6afe18b55c536641cc09b5 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:10 +0200 Subject: [PATCH 19/27] genesys: Remove duplicate register write during led calibration on gl841 --- backend/genesys/genesys.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 841361365..de6bfa6d4 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -2031,10 +2031,6 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor dev.cmd_set->init_regs_for_scan_session(&dev, calib_sensor, ®s, session); - if (dev.model->asic_type == AsicType::GL841) { - dev.interface->write_registers(regs); // FIXME: remove this - } - std::uint16_t exp[3]; if (dev.model->asic_type == AsicType::GL841) { From 43390304233eeaa4842074f718e02468700e0cbb Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:11 +0200 Subject: [PATCH 20/27] genesys: Specify target white level for all gl841 devices --- backend/genesys/tables_sensor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/genesys/tables_sensor.cpp b/backend/genesys/tables_sensor.cpp index d79a018ac..4f1753842 100644 --- a/backend/genesys/tables_sensor.cpp +++ b/backend/genesys/tables_sensor.cpp @@ -471,8 +471,8 @@ void genesys_init_sensor_tables() sensor.register_dpihw = 1200; sensor.black_pixels = 87; sensor.dummy_pixel = 87; - sensor.fau_gain_white_ref = 0; - sensor.gain_white_ref = 0; + sensor.fau_gain_white_ref = 100; + sensor.gain_white_ref = 100; sensor.exposure = { 0x0400, 0x0400, 0x0400 }; sensor.custom_regs = { { 0x16, 0x00 }, { 0x17, 0x02 }, { 0x18, 0x00 }, { 0x19, 0x50 }, @@ -519,8 +519,8 @@ void genesys_init_sensor_tables() sensor.register_dpihw = 1200; sensor.black_pixels = 87; sensor.dummy_pixel = 87; - sensor.fau_gain_white_ref = 0; - sensor.gain_white_ref = 0; + sensor.fau_gain_white_ref = 100; + sensor.gain_white_ref = 100; sensor.exposure = { 0x0400, 0x0400, 0x0400 }; sensor.custom_regs = { { 0x16, 0x00 }, { 0x17, 0x01 }, { 0x18, 0x00 }, { 0x19, 0x50 }, From f7f0419b57375f6c287a1f57c02b9bc505a1f0ae Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:12 +0200 Subject: [PATCH 21/27] genesys: Remove no longer used led calibration fallback code on gl841 This was used only on scanners which did not have calibration target intensity value. All gl841 scanners now have such setting, so the code can be removed. --- backend/genesys/genesys.cpp | 54 ++++--------------------------------- 1 file changed, 5 insertions(+), 49 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index de6bfa6d4..5ae2dafe7 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -2045,9 +2045,6 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor std::uint16_t target = sensor.gain_white_ref * 256; - std::uint16_t min_exposure = 500; // only gl841 - std::uint16_t max_exposure = ((exp[0] + exp[1] + exp[2]) / 3) * 2; // only gl841 - std::uint16_t top[3] = {}; std::uint16_t bottom[3] = {}; @@ -2128,52 +2125,11 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor acceptable = true; if (dev.model->asic_type == AsicType::GL841) { - if (avg[0] < avg[1] * 0.95 || avg[1] < avg[0] * 0.95 || - avg[0] < avg[2] * 0.95 || avg[2] < avg[0] * 0.95 || - avg[1] < avg[2] * 0.95 || avg[2] < avg[1] * 0.95) - { - acceptable = false; - } - - // led exposure is not acceptable if white level is too low. - // ~80 hardcoded value for white level - if (avg[0] < 20000 || avg[1] < 20000 || avg[2] < 20000) { - acceptable = false; - } - - // for scanners using target value - if (target > 0) { - acceptable = true; - for (unsigned i = 0; i < 3; i++) { - // we accept +- 2% delta from target - if (std::abs(avg[i] - target) > target / 50) { - exp[i] = (exp[i] * target) / avg[i]; - acceptable = false; - } - } - } else { - if (!acceptable) { - unsigned avga = (avg[0] + avg[1] + avg[2]) / 3; - exp[0] = (exp[0] * avga) / avg[0]; - exp[1] = (exp[1] * avga) / avg[1]; - exp[2] = (exp[2] * avga) / avg[2]; - /* Keep the resulting exposures below this value. Too long exposure drives - the ccd into saturation. We may fix this by relying on the fact that - we get a striped scan without shading, by means of statistical calculation - */ - unsigned avge = (exp[0] + exp[1] + exp[2]) / 3; - - if (avge > max_exposure) { - exp[0] = (exp[0] * max_exposure) / avge; - exp[1] = (exp[1] * max_exposure) / avge; - exp[2] = (exp[2] * max_exposure) / avge; - } - if (avge < min_exposure) { - exp[0] = (exp[0] * min_exposure) / avge; - exp[1] = (exp[1] * min_exposure) / avge; - exp[2] = (exp[2] * min_exposure) / avge; - } - + for (unsigned i = 0; i < 3; i++) { + // we accept +- 2% delta from target + if (std::abs(avg[i] - target) > target / 50) { + exp[i] = (exp[i] * target) / avg[i]; + acceptable = false; } } } else if (dev.model->asic_type == AsicType::GL845 || From 957f2832b7dc6a8ddf40f4388dc67168e82c74c6 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:13 +0200 Subject: [PATCH 22/27] genesys: Reuse gl124 led calibration acceptability criteria for gl841 --- backend/genesys/genesys.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 5ae2dafe7..30de49fea 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -2124,16 +2124,8 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor acceptable = true; - if (dev.model->asic_type == AsicType::GL841) { - for (unsigned i = 0; i < 3; i++) { - // we accept +- 2% delta from target - if (std::abs(avg[i] - target) > target / 50) { - exp[i] = (exp[i] * target) / avg[i]; - acceptable = false; - } - } - } else if (dev.model->asic_type == AsicType::GL845 || - dev.model->asic_type == AsicType::GL846) + if (dev.model->asic_type == AsicType::GL845 || + dev.model->asic_type == AsicType::GL846) { for (unsigned i = 0; i < 3; i++) { if (avg[i] < bottom[i]) { @@ -2166,7 +2158,9 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor acceptable = false; } } - } else if (dev.model->asic_type == AsicType::GL124) { + } else if (dev.model->asic_type == AsicType::GL841 || + dev.model->asic_type == AsicType::GL124) + { for (unsigned i = 0; i < 3; i++) { // we accept +- 2% delta from target if (std::abs(avg[i] - target) > target / 50) { From 11d1c4295eecd9f918d9aceb22541ce876e57044 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:14 +0200 Subject: [PATCH 23/27] genesys: Ensure sensor exposure is up-to-date when scanning on gl841 --- backend/genesys/genesys.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 30de49fea..9ab7b352b 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -674,9 +674,9 @@ void scanner_setup_sensor(Genesys_Device& dev, const Genesys_Sensor& sensor, regs.set8(custom_reg.address, custom_reg.value); } - if (dev.model->asic_type != AsicType::GL841 && - dev.model->asic_type != AsicType::GL843) + if (dev.model->asic_type != AsicType::GL843) { + // FIXME: remove the above check regs_set_exposure(dev.model->asic_type, regs, sensor.exposure); } From 86e47614b91752082e314885779f9b6f176779de Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:15 +0200 Subject: [PATCH 24/27] genesys: Fix inconsistent exposure values in led calib in testing mode --- backend/genesys/genesys.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 9ab7b352b..fbedc527d 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -2090,15 +2090,13 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor if (dev.model->asic_type == AsicType::GL841) { scanner_stop_action(dev); dev.cmd_set->move_back_home(&dev, true); - return { exp[0], exp[1], exp[2] }; } else if (dev.model->asic_type == AsicType::GL124) { scanner_stop_action(dev); - return calib_sensor.exposure; } else { scanner_stop_action(dev); dev.cmd_set->move_back_home(&dev, true); - return calib_sensor.exposure; } + return { exp[0], exp[1], exp[2] }; } auto image = read_unshuffled_image_from_scanner(&dev, session, session.output_line_bytes); From db978550eb3b8bb2d7384620b1c1ce5ba9e4503d Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:16 +0200 Subject: [PATCH 25/27] genesys: Use consistent initial exposure for led calibration on gl841 --- backend/genesys/genesys.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index fbedc527d..e1ff07139 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -2033,15 +2033,9 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor std::uint16_t exp[3]; - if (dev.model->asic_type == AsicType::GL841) { - exp[0] = sensor.exposure.red; - exp[1] = sensor.exposure.green; - exp[2] = sensor.exposure.blue; - } else { - exp[0] = calib_sensor.exposure.red; - exp[1] = calib_sensor.exposure.green; - exp[2] = calib_sensor.exposure.blue; - } + exp[0] = calib_sensor.exposure.red; + exp[1] = calib_sensor.exposure.green; + exp[2] = calib_sensor.exposure.blue; std::uint16_t target = sensor.gain_white_ref * 256; From 2d467ced5708a772cd49cca2241b0aa233c19e06 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:17 +0200 Subject: [PATCH 26/27] genesys: Fixed offset calibration on certain gl841 devices --- backend/genesys/gl841.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index ee18961b9..10052b205 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -1653,14 +1653,10 @@ static void ad_fe_offset_calibration(Genesys_Device* dev, const Genesys_Sensor& turn++; } while ((top-bottom)>1 && turn < 100); - // FIXME: don't overwrite the calibrated values - dev->frontend.set_offset(0, 0); - dev->frontend.set_offset(1, 0); - dev->frontend.set_offset(2, 0); - DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, - dev->frontend.get_offset(0), - dev->frontend.get_offset(1), - dev->frontend.get_offset(2)); + DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, + dev->frontend.get_offset(0), + dev->frontend.get_offset(1), + dev->frontend.get_offset(2)); } /* this function does the offset calibration by scanning one line of the calibration From 03a4c60a0100491ff250b8d3d4e2a1c84dfefa89 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 27 Dec 2021 22:21:18 +0200 Subject: [PATCH 27/27] genesys: Remove unneeded per-scanner register setup These register values are overwritten later. --- backend/genesys/gl841.cpp | 48 ++++++++++----------------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index 10052b205..92623464e 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -149,15 +149,6 @@ gl841_init_registers (Genesys_Device * dev) dev->reg.init_reg(0x13, 0x00); // SENSOR_DEF dev->reg.init_reg(0x14, 0x00); // SENSOR_DEF dev->reg.init_reg(0x15, 0x00); // SENSOR_DEF - if (dev->model->model_id == ModelId::CANON_LIDE_80) { - dev->reg.init_reg(0x10, 0x40); - dev->reg.init_reg(0x11, 0x00); - dev->reg.init_reg(0x12, 0x40); - dev->reg.init_reg(0x13, 0x00); - dev->reg.init_reg(0x14, 0x40); - dev->reg.init_reg(0x15, 0x00); - } - dev->reg.init_reg(0x16, 0x00); // SENSOR_DEF, overwritten in scanner_setup_sensor() below dev->reg.init_reg(0x17, 0x00); // SENSOR_DEF, overwritten in scanner_setup_sensor() below dev->reg.init_reg(0x18, 0x00); // SENSOR_DEF, overwritten in scanner_setup_sensor() below @@ -184,36 +175,21 @@ gl841_init_registers (Genesys_Device * dev) dev->reg.init_reg(0x27, 0x00); dev->reg.init_reg(0x29, 0xff); - dev->reg.init_reg(0x2c, 0x00); - dev->reg.init_reg(0x2d, 0x00); - if (dev->model->model_id == ModelId::CANON_LIDE_80) { - dev->reg.init_reg(0x2c, sensor.full_resolution >> 8); - dev->reg.init_reg(0x2d, sensor.full_resolution & 0xff); - } + dev->reg.init_reg(0x2c, 0x02); // DPISET: overwritten during scanner setup + dev->reg.init_reg(0x2d, 0x58); // DPISET: overwritten during scanner setup dev->reg.init_reg(0x2e, 0x80); dev->reg.init_reg(0x2f, 0x80); - dev->reg.init_reg(0x30, 0x00); - dev->reg.init_reg(0x31, 0x00); - dev->reg.init_reg(0x32, 0x00); - dev->reg.init_reg(0x33, 0x00); - dev->reg.init_reg(0x34, 0x00); - dev->reg.init_reg(0x35, 0x00); - dev->reg.init_reg(0x36, 0x00); - dev->reg.init_reg(0x37, 0x00); - dev->reg.init_reg(0x38, 0x4f); - dev->reg.init_reg(0x39, 0xc1); - if (dev->model->model_id == ModelId::CANON_LIDE_80) { - dev->reg.init_reg(0x31, 0x10); - dev->reg.init_reg(0x32, 0x15); - dev->reg.init_reg(0x33, 0x0e); - dev->reg.init_reg(0x34, 0x40); - dev->reg.init_reg(0x35, 0x00); - dev->reg.init_reg(0x36, 0x2a); - dev->reg.init_reg(0x37, 0x30); - dev->reg.init_reg(0x38, 0x2a); - dev->reg.init_reg(0x39, 0xf8); - } + dev->reg.init_reg(0x30, 0x00); // STRPIXEL: overwritten during scanner setup + dev->reg.init_reg(0x31, 0x00); // STRPIXEL: overwritten during scanner setup + dev->reg.init_reg(0x32, 0x00); // ENDPIXEL: overwritten during scanner setup + dev->reg.init_reg(0x33, 0x00); // ENDPIXEL: overwritten during scanner setup + dev->reg.init_reg(0x34, 0x00); // DUMMY: overwritten during scanner setup + dev->reg.init_reg(0x35, 0x00); // MAXWD: overwritten during scanner setup + dev->reg.init_reg(0x36, 0x00); // MAXWD: overwritten during scanner setup + dev->reg.init_reg(0x37, 0x00); // MAXWD: overwritten during scanner setup + dev->reg.init_reg(0x38, 0x4f); // LPERIOD: overwritten during scanner setup + dev->reg.init_reg(0x39, 0xc1); // LPERIOD: overwritten during scanner setup dev->reg.init_reg(0x3d, 0x00); dev->reg.init_reg(0x3e, 0x00);