diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-08-24 18:45:55 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-08-24 18:45:55 +0200 |
commit | a77bc1fcbdf83cfdac9570c0a0ac886b5534c90f (patch) | |
tree | d839746371ecb8ed64ac81d2e37c11fcd25a00ac /backend/genesys/sensor.h | |
parent | 787fb1d54ec9ee5fb941ae897fb201feb9cb2fd1 (diff) | |
parent | 2b3e02411ecc09e7d41741b5587655c9b2f955b7 (diff) |
Merge branch 'feature/upstream' into develop
Diffstat (limited to 'backend/genesys/sensor.h')
-rw-r--r-- | backend/genesys/sensor.h | 190 |
1 files changed, 79 insertions, 111 deletions
diff --git a/backend/genesys/sensor.h b/backend/genesys/sensor.h index e70728e..ca6fef7 100644 --- a/backend/genesys/sensor.h +++ b/backend/genesys/sensor.h @@ -47,6 +47,7 @@ #include "enums.h" #include "register.h" #include "serialize.h" +#include "value_filter.h" #include <array> #include <functional> @@ -72,31 +73,30 @@ class StaggerConfig { public: StaggerConfig() = default; - StaggerConfig(unsigned min_resolution, unsigned lines_at_min) : - min_resolution_{min_resolution}, - lines_at_min_{lines_at_min} + explicit StaggerConfig(std::initializer_list<std::size_t> shifts) : + shifts_{shifts} { } - unsigned stagger_at_resolution(unsigned xresolution, unsigned yresolution) const + std::size_t max_shift() const { - if (min_resolution_ == 0 || xresolution < min_resolution_) + if (shifts_.empty()) { return 0; - return yresolution / min_resolution_ * lines_at_min_; + } + return *std::max_element(shifts_.begin(), shifts_.end()); } - unsigned min_resolution() const { return min_resolution_; } - unsigned lines_at_min() const { return lines_at_min_; } + bool empty() const { return shifts_.empty(); } + std::size_t size() const { return shifts_.size(); } + const std::vector<std::size_t>& shifts() const { return shifts_; } bool operator==(const StaggerConfig& other) const { - return min_resolution_ == other.min_resolution_ && - lines_at_min_ == other.lines_at_min_; + return shifts_ == other.shifts_; } private: - unsigned min_resolution_ = 0; - unsigned lines_at_min_ = 0; + std::vector<std::size_t> shifts_; template<class Stream> friend void serialize(Stream& str, StaggerConfig& x); @@ -105,8 +105,7 @@ private: template<class Stream> void serialize(Stream& str, StaggerConfig& x) { - serialize(str, x.min_resolution_); - serialize(str, x.lines_at_min_); + serialize(str, x.shifts_); } std::ostream& operator<<(std::ostream& out, const StaggerConfig& config); @@ -114,9 +113,14 @@ std::ostream& operator<<(std::ostream& out, const StaggerConfig& config); enum class FrontendType : unsigned { - UNKNOWN, + UNKNOWN = 0, WOLFSON, - ANALOG_DEVICES + ANALOG_DEVICES, + CANON_LIDE_80, + WOLFSON_GL841, // old code path, likely wrong calculation + WOLFSON_GL846, // old code path, likely wrong calculation + ANALOG_DEVICES_GL847, // old code path, likely wrong calculation + WOLFSON_GL124, // old code path, likely wrong calculation }; inline void serialize(std::istream& str, FrontendType& x) @@ -242,54 +246,6 @@ struct SensorExposure { std::ostream& operator<<(std::ostream& out, const SensorExposure& exposure); -class ResolutionFilter -{ -public: - struct Any {}; - static constexpr Any ANY{}; - - ResolutionFilter() : matches_any_{false} {} - ResolutionFilter(Any) : matches_any_{true} {} - ResolutionFilter(std::initializer_list<unsigned> resolutions) : - matches_any_{false}, - resolutions_{resolutions} - {} - - bool matches(unsigned resolution) const - { - if (matches_any_) - return true; - auto it = std::find(resolutions_.begin(), resolutions_.end(), resolution); - return it != resolutions_.end(); - } - - bool operator==(const ResolutionFilter& other) const - { - return matches_any_ == other.matches_any_ && resolutions_ == other.resolutions_; - } - - bool matches_any() const { return matches_any_; } - const std::vector<unsigned>& resolutions() const { return resolutions_; } - -private: - bool matches_any_ = false; - std::vector<unsigned> resolutions_; - - template<class Stream> - friend void serialize(Stream& str, ResolutionFilter& x); -}; - -std::ostream& operator<<(std::ostream& out, const ResolutionFilter& resolutions); - -template<class Stream> -void serialize(Stream& str, ResolutionFilter& x) -{ - serialize(str, x.matches_any_); - serialize_newline(str); - serialize(str, x.resolutions_); -} - - struct Genesys_Sensor { Genesys_Sensor() = default; @@ -300,10 +256,15 @@ struct Genesys_Sensor { // sensor resolution in CCD pixels. Note that we may read more than one CCD pixel per logical // pixel, see ccd_pixels_per_system_pixel() - unsigned optical_res = 0; + unsigned full_resolution = 0; + + // sensor resolution in pixel values that are read by the chip. Many scanners make low + // resolutions faster by configuring the timings in such a way that 1/2 or 1/4 of pixel values + // that are read. If zero, then it is equal to `full_resolution`. + unsigned optical_resolution = 0; // the resolution list that the sensor is usable at. - ResolutionFilter resolutions = ResolutionFilter::ANY; + ValueFilterAny<unsigned> resolutions = VALUE_FILTER_ANY; // the channel list that the sensor is usable at std::vector<unsigned> channels = { 1, 3 }; @@ -313,29 +274,32 @@ struct Genesys_Sensor { // The scanner may be setup to use a custom dpihw that does not correspond to any actual // resolution. The value zero does not set the override. - unsigned register_dpihw_override = 0; - - // The scanner may be setup to use a custom logical dpihw that does not correspond to any actual - // resolution. The value zero does not set the override. - unsigned logical_dpihw_override = 0; + unsigned register_dpihw = 0; // The scanner may be setup to use a custom dpiset value that does not correspond to any actual // resolution. The value zero does not set the override. - unsigned dpiset_override = 0; + unsigned register_dpiset = 0; + + // The resolution to use for shading calibration + unsigned shading_resolution = 0; - // CCD may present itself as half or quarter-size CCD on certain resolutions - int ccd_size_divisor = 1; + // How many real pixels correspond to one shading pixel that is sent to the scanner + unsigned shading_factor = 1; - // Some scanners need an additional multiplier over the scan coordinates - int pixel_count_multiplier = 1; + // How many pixels the shading data is offset to the right from the acquired data. Calculated + // in shading resolution. + int shading_pixel_offset = 0; + + // This defines the ratio between logical pixel coordinates and the pixel coordinates sent to + // the scanner. + Ratio pixel_count_ratio = Ratio{1, 1}; + + // The offset in pixels in terms of scan resolution that needs to be applied to scan position. + int output_pixel_offset = 0; int black_pixels = 0; // value of the dummy register int dummy_pixel = 0; - // last pixel of CCD margin at optical resolution - int ccd_start_xoffset = 0; - // total pixels used by the sensor - int sensor_pixels = 0; // TA CCD target code (reference gain) int fau_gain_white_ref = 0; // CCD target code (reference gain) @@ -346,8 +310,7 @@ struct Genesys_Sensor { int exposure_lperiod = -1; - // the number of pixels in a single segment. - // only on gl843 + // the number of pixels in a single segment. This is counted in output resolution. unsigned segment_size = 0; // the order of the segments, if any, for the sensor. If the sensor is not segmented or uses @@ -355,31 +318,28 @@ struct Genesys_Sensor { // only on gl843 std::vector<unsigned> segment_order; - // some CCDs use two arrays of pixels for double resolution. On such CCDs when scanning at - // high-enough resolution, every other pixel column is shifted - StaggerConfig stagger_config; + // some CCDs use multiple arrays of pixels for double or quadruple resolution. This can result + // in the following effects on the output: + // - every n-th column may be shifted in a vertical direction. + // - the columns themselves may be reordered in arbitrary order and may require shifting + // in X direction. + StaggerConfig stagger_x; + StaggerConfig stagger_y; + + // True if calibration should be performed on host-side + bool use_host_side_calib = false; - GenesysRegisterSettingSet custom_base_regs; // gl646-specific GenesysRegisterSettingSet custom_regs; GenesysRegisterSettingSet custom_fe_regs; // red, green and blue gamma coefficient for default gamma tables AssignableArray<float, 3> gamma; - std::function<unsigned(const Genesys_Sensor&, unsigned)> get_logical_hwdpi_fun; - std::function<unsigned(const Genesys_Sensor&, unsigned)> get_register_hwdpi_fun; - std::function<unsigned(const Genesys_Sensor&, unsigned)> get_ccd_size_divisor_fun; - std::function<unsigned(const Genesys_Sensor&, unsigned)> get_hwdpi_divisor_fun; - - unsigned get_logical_hwdpi(unsigned xres) const { return get_logical_hwdpi_fun(*this, xres); } - unsigned get_register_hwdpi(unsigned xres) const { return get_register_hwdpi_fun(*this, xres); } - unsigned get_ccd_size_divisor_for_dpi(unsigned xres) const - { - return get_ccd_size_divisor_fun(*this, xres); - } - unsigned get_hwdpi_divisor_for_dpi(unsigned xres) const + unsigned get_optical_resolution() const { - return get_hwdpi_divisor_fun(*this, xres); + if (optical_resolution != 0) + return optical_resolution; + return full_resolution; } // how many CCD pixels are processed per system pixel time. This corresponds to CKSEL + 1 @@ -405,22 +365,26 @@ struct Genesys_Sensor { bool operator==(const Genesys_Sensor& other) const { return sensor_id == other.sensor_id && - optical_res == other.optical_res && + full_resolution == other.full_resolution && + optical_resolution == other.optical_resolution && resolutions == other.resolutions && method == other.method && - ccd_size_divisor == other.ccd_size_divisor && + shading_resolution == other.shading_resolution && + shading_factor == other.shading_factor && + shading_pixel_offset == other.shading_pixel_offset && + pixel_count_ratio == other.pixel_count_ratio && + output_pixel_offset == other.output_pixel_offset && black_pixels == other.black_pixels && dummy_pixel == other.dummy_pixel && - ccd_start_xoffset == other.ccd_start_xoffset && - sensor_pixels == other.sensor_pixels && fau_gain_white_ref == other.fau_gain_white_ref && gain_white_ref == other.gain_white_ref && exposure == other.exposure && exposure_lperiod == other.exposure_lperiod && segment_size == other.segment_size && segment_order == other.segment_order && - stagger_config == other.stagger_config && - custom_base_regs == other.custom_base_regs && + stagger_x == other.stagger_x && + stagger_y == other.stagger_y && + use_host_side_calib == other.use_host_side_calib && custom_regs == other.custom_regs && custom_fe_regs == other.custom_fe_regs && gamma == other.gamma; @@ -431,14 +395,16 @@ template<class Stream> void serialize(Stream& str, Genesys_Sensor& x) { serialize(str, x.sensor_id); - serialize(str, x.optical_res); + serialize(str, x.full_resolution); serialize(str, x.resolutions); serialize(str, x.method); - serialize(str, x.ccd_size_divisor); + serialize(str, x.shading_resolution); + serialize(str, x.shading_factor); + serialize(str, x.shading_pixel_offset); + serialize(str, x.output_pixel_offset); + serialize(str, x.pixel_count_ratio); serialize(str, x.black_pixels); serialize(str, x.dummy_pixel); - serialize(str, x.ccd_start_xoffset); - serialize(str, x.sensor_pixels); serialize(str, x.fau_gain_white_ref); serialize(str, x.gain_white_ref); serialize_newline(str); @@ -451,9 +417,11 @@ void serialize(Stream& str, Genesys_Sensor& x) serialize_newline(str); serialize(str, x.segment_order); serialize_newline(str); - serialize(str, x.stagger_config); + serialize(str, x.stagger_x); + serialize_newline(str); + serialize(str, x.stagger_y); serialize_newline(str); - serialize(str, x.custom_base_regs); + serialize(str, x.use_host_side_calib); serialize_newline(str); serialize(str, x.custom_regs); serialize_newline(str); |