diff --git a/backend/genesys.cc b/backend/genesys.cc index da5e46cd9..6cbe7369b 100644 --- a/backend/genesys.cc +++ b/backend/genesys.cc @@ -206,10 +206,9 @@ const Genesys_Sensor& sanei_genesys_find_sensor(Genesys_Device* dev, int dpi, ScanMethod scan_method) { for (const auto& sensor : *s_sensors) { - if (dev->model->ccd_type == sensor.sensor_id && - (sensor.min_resolution == -1 || dpi >= sensor.min_resolution) && - (sensor.max_resolution == -1 || dpi <= sensor.max_resolution) && - sensor.method == scan_method) { + if (dev->model->ccd_type == sensor.sensor_id && sensor.resolutions.matches(dpi) && + sensor.method == scan_method) + { return sensor; } } @@ -220,10 +219,9 @@ Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, int dpi ScanMethod scan_method) { for (auto& sensor : *s_sensors) { - if (dev->model->ccd_type == sensor.sensor_id && - (sensor.min_resolution == -1 || dpi >= sensor.min_resolution) && - (sensor.max_resolution == -1 || dpi <= sensor.max_resolution) && - sensor.method == scan_method) { + if (dev->model->ccd_type == sensor.sensor_id && sensor.resolutions.matches(dpi) && + sensor.method == scan_method) + { return sensor; } } @@ -5122,7 +5120,7 @@ probe_genesys_devices (void) of Genesys_Calibration_Cache as is. */ static const char* CALIBRATION_IDENT = "sane_genesys"; -static const int CALIBRATION_VERSION = 4; +static const int CALIBRATION_VERSION = 5; bool read_calibration(std::istream& str, Genesys_Device::Calibration& calibration, const std::string& path) diff --git a/backend/genesys_low.cc b/backend/genesys_low.cc index fe7d8d5b4..3d92cc809 100644 --- a/backend/genesys_low.cc +++ b/backend/genesys_low.cc @@ -1829,8 +1829,17 @@ void debug_dump(unsigned level, const Genesys_Sensor& sensor) DBG(level, "sensor:\n"); DBG(level, " sensor_id : %d\n", sensor.sensor_id); DBG(level, " optical_res : %d\n", sensor.optical_res); - DBG(level, " min_resolution : %d\n", sensor.min_resolution); - DBG(level, " max_resolution : %d\n", sensor.max_resolution); + + DBG(level, " resolutions :"); + if (sensor.resolutions.matches_any()) { + DBG(level, " ANY\n"); + } else { + for (unsigned resolution : sensor.resolutions.resolutions()) { + DBG(level, " %d", resolution); + } + DBG(level, "\n"); + } + DBG(level, " method : %d\n", static_cast(sensor.method)); DBG(level, " ccd_size_divisor : %d\n", sensor.ccd_size_divisor); DBG(level, " black_pixels : %d\n", sensor.black_pixels); diff --git a/backend/genesys_sensor.h b/backend/genesys_sensor.h index da901898e..c57292eaf 100644 --- a/backend/genesys_sensor.h +++ b/backend/genesys_sensor.h @@ -193,6 +193,51 @@ void serialize(Stream& str, SensorProfile& x) serialize(str, x.custom_regs); } +class ResolutionFilter +{ +public: + struct Any {}; + static constexpr Any ANY{}; + + ResolutionFilter() : matches_any_{false} {} + ResolutionFilter(Any) : matches_any_{true} {} + ResolutionFilter(std::initializer_list 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& resolutions() const { return resolutions_; } + +private: + bool matches_any_ = false; + std::vector resolutions_; + + template + friend void serialize(Stream& str, ResolutionFilter& x); +}; + +template +void serialize(Stream& str, ResolutionFilter& x) +{ + serialize(str, x.matches_any_); + serialize_newline(str); + serialize(str, x.resolutions_); +} + struct Genesys_Sensor { Genesys_Sensor() = default; @@ -205,10 +250,8 @@ struct Genesys_Sensor { // pixel, see ccd_pixels_per_system_pixel() int optical_res = 0; - // the minimum and maximum resolution this sensor is usable at. -1 means that the resolution - // can be any. - int min_resolution = -1; - int max_resolution = -1; + // the resolution list that the sensor is usable at. + ResolutionFilter resolutions = ResolutionFilter::ANY; // the scan method used with the sensor ScanMethod method = ScanMethod::FLATBED; @@ -277,8 +320,7 @@ struct Genesys_Sensor { { return sensor_id == other.sensor_id && optical_res == other.optical_res && - min_resolution == other.min_resolution && - max_resolution == other.max_resolution && + resolutions == other.resolutions && method == other.method && ccd_size_divisor == other.ccd_size_divisor && black_pixels == other.black_pixels && @@ -301,8 +343,7 @@ void serialize(Stream& str, Genesys_Sensor& x) { serialize(str, x.sensor_id); serialize(str, x.optical_res); - serialize(str, x.min_resolution); - serialize(str, x.max_resolution); + serialize(str, x.resolutions); serialize(str, x.method); serialize(str, x.ccd_size_divisor); serialize(str, x.black_pixels); diff --git a/backend/genesys_serialize.h b/backend/genesys_serialize.h index 481e8727f..f93063d6c 100644 --- a/backend/genesys_serialize.h +++ b/backend/genesys_serialize.h @@ -56,6 +56,8 @@ inline void serialize_newline(std::ostream& str) { str << '\n'; } inline void serialize_newline(std::istream& str) { (void) str; } +inline void serialize(std::ostream& str, bool x) { str << static_cast(x) << " "; } +inline void serialize(std::istream& str, bool& x) { unsigned v; str >> v; x = v; } inline void serialize(std::ostream& str, char x) { str << static_cast(x) << " "; } inline void serialize(std::istream& str, char& x) { int v; str >> v; x = v; } inline void serialize(std::ostream& str, unsigned char x) { str << static_cast(x) << " "; } diff --git a/backend/genesys_tables_sensor.cc b/backend/genesys_tables_sensor.cc index 3020b84c8..4c59543c8 100644 --- a/backend/genesys_tables_sensor.cc +++ b/backend/genesys_tables_sensor.cc @@ -1205,15 +1205,14 @@ void genesys_init_sensor_tables() { struct CustomSensorSettings { - int min_resolution; - int max_resolution; + ResolutionFilter resolutions; int exposure_lperiod; ScanMethod method; GenesysRegisterSettingSet extra_custom_regs; }; CustomSensorSettings custom_settings[] = { - { -1, 600, 8016, ScanMethod::FLATBED, { + { { 100, 150, 200, 300, 400, 600 }, 8016, ScanMethod::FLATBED, { { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff }, { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff }, { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, @@ -1241,7 +1240,7 @@ void genesys_init_sensor_tables() { 0x5a, 0x40 }, } }, - { 1200, 1200, 56064, ScanMethod::FLATBED, { + { { 1200 }, 56064, ScanMethod::FLATBED, { { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, { 0x77, 0x00 }, { 0x78, 0x01 }, { 0x79, 0xff }, { 0x7a, 0x00 }, { 0x7b, 0x01 }, { 0x7c, 0xff }, @@ -1269,7 +1268,7 @@ void genesys_init_sensor_tables() { 0x5a, 0x40 }, } }, - { 2400, 2400, 56064, ScanMethod::FLATBED, { + { { 2400 }, 56064, ScanMethod::FLATBED, { { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, @@ -1297,7 +1296,7 @@ void genesys_init_sensor_tables() { 0x5a, 0x40 }, } }, - { 4800, 4800, 42752, ScanMethod::FLATBED, { + { { 4800 }, 42752, ScanMethod::FLATBED, { { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, @@ -1325,7 +1324,7 @@ void genesys_init_sensor_tables() { 0x5a, 0x40 }, } }, - { -1, -1, 15624, ScanMethod::TRANSPARENCY, { + { ResolutionFilter::ANY, 15624, ScanMethod::TRANSPARENCY, { { 0x74, 0x00 }, { 0x75, 0x1c }, { 0x76, 0x7f }, { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff }, { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, @@ -1358,8 +1357,7 @@ void genesys_init_sensor_tables() auto base_custom_regs = sensor.custom_regs; for (const CustomSensorSettings& setting : custom_settings) { - sensor.min_resolution = setting.min_resolution; - sensor.max_resolution = setting.max_resolution; + sensor.resolutions = setting.resolutions; sensor.exposure_lperiod = setting.exposure_lperiod; sensor.method = setting.method; sensor.custom_regs = base_custom_regs; @@ -1439,8 +1437,7 @@ void genesys_init_sensor_tables() { struct CustomSensorSettings { - int min_resolution; - int max_resolution; + ResolutionFilter resolutions; int exposure_lperiod; ScanMethod method; GenesysRegisterSettingSet extra_custom_regs; @@ -1448,7 +1445,7 @@ void genesys_init_sensor_tables() }; CustomSensorSettings custom_settings[] = { - { -1, 600, 7200, ScanMethod::FLATBED, { + { { 100, 300, 600 }, 7200, ScanMethod::FLATBED, { { 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f }, { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, { 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb }, @@ -1477,7 +1474,7 @@ void genesys_init_sensor_tables() { 0x80, 0x20 }, }, {} }, - { 1200, 1200, 14400, ScanMethod::FLATBED, { + { { 1200 }, 14400, ScanMethod::FLATBED, { { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff }, { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, { 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 }, @@ -1508,7 +1505,7 @@ void genesys_init_sensor_tables() { 0x03, 0x1f }, } }, - { -1, 600, 14400, ScanMethod::TRANSPARENCY, { + { { 100, 300, 600 }, 14400, ScanMethod::TRANSPARENCY, { { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x13 }, @@ -1534,7 +1531,7 @@ void genesys_init_sensor_tables() { 0x80, 0x20 }, }, {} }, - { 1200, 1200, 28800, ScanMethod::TRANSPARENCY, { + { { 1200 }, 28800, ScanMethod::TRANSPARENCY, { { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x11 }, @@ -1562,7 +1559,7 @@ void genesys_init_sensor_tables() { 0x03, 0x1f }, }, }, - { 2400, 2400, 28800, ScanMethod::TRANSPARENCY, { + { { 2400 }, 28800, ScanMethod::TRANSPARENCY, { { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x10 }, @@ -1590,7 +1587,7 @@ void genesys_init_sensor_tables() { 0x03, 0x1f }, }, }, - { 1200, 1200, 28800, ScanMethod::TRANSPARENCY_INFRARED, { + { { 1200 }, 28800, ScanMethod::TRANSPARENCY_INFRARED, { { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x11 }, @@ -1622,8 +1619,7 @@ void genesys_init_sensor_tables() for (const CustomSensorSettings& setting : custom_settings) { - sensor.min_resolution = setting.min_resolution; - sensor.max_resolution = setting.max_resolution; + sensor.resolutions = setting.resolutions; sensor.exposure_lperiod = setting.exposure_lperiod; sensor.method = setting.method; sensor.custom_regs = setting.extra_custom_regs; @@ -1654,8 +1650,7 @@ void genesys_init_sensor_tables() { struct CustomSensorSettings { - int min_resolution; - int max_resolution; + ResolutionFilter resolutions; int exposure_lperiod; ScanMethod method; GenesysRegisterSettingSet extra_custom_regs; @@ -1663,7 +1658,7 @@ void genesys_init_sensor_tables() }; CustomSensorSettings custom_settings[] = { - { -1, 1200, 24000, ScanMethod::FLATBED, { + { { 300, 600, 1200 }, 24000, ScanMethod::FLATBED, { { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 }, { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 }, { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, @@ -1694,7 +1689,7 @@ void genesys_init_sensor_tables() }, {}, }, - { -1, 1200, 45000, ScanMethod::TRANSPARENCY, { + { { 300, 600, 1200 }, 45000, ScanMethod::TRANSPARENCY, { { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 }, { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 }, { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, @@ -1725,7 +1720,7 @@ void genesys_init_sensor_tables() }, {}, }, - { 2400, 2400, 45000, ScanMethod::TRANSPARENCY, { + { { 2400 }, 45000, ScanMethod::TRANSPARENCY, { { 0x74, 0x03 }, { 0x75, 0xfe }, { 0x76, 0x00 }, { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 }, { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, @@ -1756,7 +1751,7 @@ void genesys_init_sensor_tables() }, {}, }, - { 4800, 4800, 45000, ScanMethod::TRANSPARENCY, { + { { 4800 }, 45000, ScanMethod::TRANSPARENCY, { { 0x74, 0x03 }, { 0x75, 0xff }, { 0x76, 0xff }, { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff }, { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, @@ -1788,7 +1783,7 @@ void genesys_init_sensor_tables() { { 0x03, 0x1f }, }, }, - { -1, 1200, 45000, ScanMethod::TRANSPARENCY_INFRARED, { + { { 1200 }, 45000, ScanMethod::TRANSPARENCY_INFRARED, { { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 }, { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 }, { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, @@ -1821,8 +1816,7 @@ void genesys_init_sensor_tables() for (const CustomSensorSettings& setting : custom_settings) { - sensor.min_resolution = setting.min_resolution; - sensor.max_resolution = setting.max_resolution; + sensor.resolutions = setting.resolutions; sensor.method = setting.method; sensor.exposure_lperiod = setting.exposure_lperiod; sensor.custom_regs = setting.extra_custom_regs;