1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
4 
5    This file is part of the SANE package.
6 
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <https://www.gnu.org/licenses/>.
19 */
20 
21 #define DEBUG_DECLARE_ONLY
22 
23 #include "low.h"
24 #include <map>
25 
26 namespace genesys {
27 
28 StaticInit<std::vector<Genesys_Sensor>> s_sensors;
29 
genesys_init_sensor_tables()30 void genesys_init_sensor_tables()
31 {
32     s_sensors.init();
33 
34     Genesys_Sensor sensor;
35 
36     sensor = Genesys_Sensor();
37     sensor.sensor_id = SensorId::CCD_UMAX; // gl646
38     sensor.full_resolution = 1200;
39     sensor.black_pixels = 48;
40     sensor.dummy_pixel = 64;
41     sensor.fau_gain_white_ref = 210;
42     sensor.gain_white_ref = 230;
43     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
44     sensor.custom_regs = {
45         { 0x08, 0x01 }, { 0x09, 0x03 }, { 0x0a, 0x05 }, { 0x0b, 0x07 },
46         { 0x16, 0x33 }, { 0x17, 0x05 }, { 0x18, 0x31 }, { 0x19, 0x2a },
47         { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x02 },
48         { 0x52, 0x13 }, { 0x53, 0x17 }, { 0x54, 0x03 }, { 0x55, 0x07 },
49         { 0x56, 0x0b }, { 0x57, 0x0f }, { 0x58, 0x23 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
50         { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 },
51     };
52     sensor.gamma = { 1.0f, 1.0f, 1.0f };
53     {
54         struct CustomSensorSettings
55         {
56             ValueFilterAny<unsigned> resolutions;
57             unsigned register_dpiset;
58             int output_pixel_offset;
59         };
60 
61         CustomSensorSettings custom_settings[] = {
62             { { 75 }, 150, 4 },
63             { { 150 }, 300, 8 },
64             { { 300 }, 600, 16 },
65             { { 600 }, 1200, 32 },
66             { { 1200 }, 2400, 64 },
67         };
68 
69         for (const CustomSensorSettings& setting : custom_settings) {
70             sensor.resolutions = setting.resolutions;
71             sensor.register_dpiset = setting.register_dpiset;
72             sensor.output_pixel_offset = setting.output_pixel_offset;
73             s_sensors->push_back(sensor);
74         }
75     }
76 
77 
78     sensor = Genesys_Sensor();
79     sensor.sensor_id = SensorId::CCD_ST12; // gl646
80     sensor.full_resolution = 600;
81     sensor.black_pixels = 48;
82     sensor.dummy_pixel = 85;
83     sensor.fau_gain_white_ref = 210;
84     sensor.gain_white_ref = 230;
85     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
86     sensor.custom_regs = {
87         { 0x08, 0x02 }, { 0x09, 0x00 }, { 0x0a, 0x06 }, { 0x0b, 0x04 },
88         { 0x16, 0x2b }, { 0x17, 0x08 }, { 0x18, 0x20 }, { 0x19, 0x2a },
89         { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x0c }, { 0x1d, 0x03 },
90         { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
91         { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
92         { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 },
93     };
94     sensor.gamma = { 1.0f, 1.0f, 1.0f };
95     {
96         struct CustomSensorSettings
97         {
98             ValueFilterAny<unsigned> resolutions;
99             int output_pixel_offset;
100         };
101 
102         CustomSensorSettings custom_settings[] = {
103             { { 75 }, 10 },
104             { { 150 }, 21 },
105             { { 300 }, 42 },
106             { { 600 }, 85 },
107         };
108 
109         for (const CustomSensorSettings& setting : custom_settings) {
110             sensor.resolutions = setting.resolutions;
111             sensor.register_dpiset = setting.resolutions.values()[0];
112             sensor.output_pixel_offset = setting.output_pixel_offset;
113             s_sensors->push_back(sensor);
114         }
115     }
116 
117 
118     sensor = Genesys_Sensor();
119     sensor.sensor_id = SensorId::CCD_ST24; // gl646
120     sensor.full_resolution = 1200;
121     sensor.black_pixels = 48;
122     sensor.dummy_pixel = 64;
123     sensor.fau_gain_white_ref = 210;
124     sensor.gain_white_ref = 230;
125     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
126     sensor.custom_regs = {
127         { 0x08, 0x0e }, { 0x09, 0x0c }, { 0x0a, 0x00 }, { 0x0b, 0x0c },
128         { 0x16, 0x33 }, { 0x17, 0x08 }, { 0x18, 0x31 }, { 0x19, 0x2a },
129         { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x02 },
130         { 0x52, 0x17 }, { 0x53, 0x03 }, { 0x54, 0x07 }, { 0x55, 0x0b },
131         { 0x56, 0x0f }, { 0x57, 0x13 }, { 0x58, 0x03 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
132         { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 },
133     };
134     sensor.gamma = { 1.0f, 1.0f, 1.0f };
135     {
136         struct CustomSensorSettings
137         {
138             ValueFilterAny<unsigned> resolutions;
139             unsigned register_dpiset;
140             int output_pixel_offset;
141         };
142 
143         CustomSensorSettings custom_settings[] = {
144             { { 75 }, 150, 4 },
145             { { 150 }, 300, 8 },
146             { { 300 }, 600, 16 },
147             { { 600 }, 1200, 32 },
148             { { 1200 }, 2400, 64 },
149         };
150 
151         for (const CustomSensorSettings& setting : custom_settings) {
152             sensor.resolutions = setting.resolutions;
153             sensor.register_dpiset = setting.register_dpiset;
154             sensor.output_pixel_offset = setting.output_pixel_offset;
155             s_sensors->push_back(sensor);
156         }
157     }
158 
159 
160     sensor = Genesys_Sensor();
161     sensor.sensor_id = SensorId::CCD_5345; // gl646
162     sensor.full_resolution = 1200;
163     sensor.black_pixels = 48;
164     sensor.dummy_pixel = 16;
165     sensor.fau_gain_white_ref = 190;
166     sensor.gain_white_ref = 190;
167     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
168     sensor.gamma = { 2.38f, 2.35f, 2.34f };
169 
170     {
171         struct CustomSensorSettings {
172             ValueFilterAny<unsigned> resolutions;
173             unsigned optical_resolution;
174             unsigned register_dpiset;
175             unsigned exposure_lperiod;
176             Ratio pixel_count_ratio;
177             int output_pixel_offset;
178             StaggerConfig stagger_y; // FIXME: may be incorrect
179             GenesysRegisterSettingSet custom_regs;
180         };
181 
182         CustomSensorSettings custom_settings[] = {
183             {   { 50 }, 600, 100, 12000, Ratio{1, 2}, 0, StaggerConfig{}, {
184                     { 0x08, 0x00 }, { 0x09, 0x05 }, { 0x0a, 0x06 }, { 0x0b, 0x08 },
185                     { 0x16, 0x0b }, { 0x17, 0x0a }, { 0x18, 0x28 }, { 0x19, 0x2a },
186                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x03 },
187                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
188                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
189                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
190                 }
191             },
192             {   { 75 }, 600, 150, 11000, Ratio{1, 2}, 1, StaggerConfig{}, {
193                     { 0x08, 0x00 }, { 0x09, 0x05 }, { 0x0a, 0x06 }, { 0x0b, 0x08 },
194                     { 0x16, 0x0b }, { 0x17, 0x0a }, { 0x18, 0x28 }, { 0x19, 0x2a },
195                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x03 },
196                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
197                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
198                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
199                 }
200             },
201             {   { 100 }, 600, 200, 11000, Ratio{1, 2}, 1, StaggerConfig{}, {
202                     { 0x08, 0x00 }, { 0x09, 0x05 }, { 0x0a, 0x06 }, { 0x0b, 0x08 },
203                     { 0x16, 0x0b }, { 0x17, 0x0a }, { 0x18, 0x28 }, { 0x19, 0x2a },
204                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x03 },
205                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
206                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
207                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
208                 }
209             },
210             {   { 150 }, 600, 300, 11000, Ratio{1, 2}, 2, StaggerConfig{}, {
211                     { 0x08, 0x00 }, { 0x09, 0x05 }, { 0x0a, 0x06 }, { 0x0b, 0x08 },
212                     { 0x16, 0x0b }, { 0x17, 0x0a }, { 0x18, 0x28 }, { 0x19, 0x2a },
213                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x03 },
214                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
215                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
216                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
217                 }
218             },
219             {   { 200 }, 600, 400, 11000, Ratio{1, 2}, 2, StaggerConfig{}, {
220                     { 0x08, 0x00 }, { 0x09, 0x05 }, { 0x0a, 0x06 }, { 0x0b, 0x08 },
221                     { 0x16, 0x0b }, { 0x17, 0x0a }, { 0x18, 0x28 }, { 0x19, 0x2a },
222                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x03 },
223                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
224                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
225                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
226                 }
227             },
228             {   { 300 }, 600, 600, 11000, Ratio{1, 2}, 4, StaggerConfig{}, {
229                     { 0x08, 0x00 }, { 0x09, 0x05 }, { 0x0a, 0x06 }, { 0x0b, 0x08 },
230                     { 0x16, 0x0b }, { 0x17, 0x0a }, { 0x18, 0x28 }, { 0x19, 0x2a },
231                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x03 },
232                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
233                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
234                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
235                 }
236             },
237             {   { 400 }, 600, 800, 11000, Ratio{1, 2}, 5, StaggerConfig{}, {
238                     { 0x08, 0x00 }, { 0x09, 0x05 }, { 0x0a, 0x06 }, { 0x0b, 0x08 },
239                     { 0x16, 0x0b }, { 0x17, 0x0a }, { 0x18, 0x28 }, { 0x19, 0x2a },
240                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x03 },
241                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
242                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
243                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
244                 }
245             },
246             {   { 600 }, 600, 1200, 11000, Ratio{1, 2}, 8, StaggerConfig{}, {
247                     { 0x08, 0x00 }, { 0x09, 0x05 }, { 0x0a, 0x06 }, { 0x0b, 0x08 },
248                     { 0x16, 0x0b }, { 0x17, 0x0a }, { 0x18, 0x28 }, { 0x19, 0x2a },
249                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x03 },
250                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
251                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
252                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
253                 }
254             },
255             {   { 1200 }, 1200, 1200, 11000, Ratio{1, 1}, 16, StaggerConfig{4, 0}, {
256                     { 0x08, 0x0d }, { 0x09, 0x0f }, { 0x0a, 0x11 }, { 0x0b, 0x13 },
257                     { 0x16, 0x0b }, { 0x17, 0x0a }, { 0x18, 0x30 }, { 0x19, 0x2a },
258                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x03 },
259                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x0b }, { 0x55, 0x0f },
260                     { 0x56, 0x13 }, { 0x57, 0x17 }, { 0x58, 0x23 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
261                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
262                 }
263             },
264         };
265 
266         for (const CustomSensorSettings& setting : custom_settings)
267         {
268             sensor.resolutions = setting.resolutions;
269             sensor.optical_resolution = setting.optical_resolution;
270             sensor.register_dpiset = setting.register_dpiset;
271             sensor.exposure_lperiod = setting.exposure_lperiod;
272             sensor.pixel_count_ratio = setting.pixel_count_ratio;
273             sensor.output_pixel_offset = setting.output_pixel_offset;
274             sensor.stagger_y = setting.stagger_y;
275             sensor.custom_regs = setting.custom_regs;
276             s_sensors->push_back(sensor);
277         }
278     }
279 
280 
281     sensor = Genesys_Sensor();
282     sensor.sensor_id = SensorId::CCD_HP2400; // gl646
283     sensor.full_resolution = 1200;
284     sensor.black_pixels = 48;
285     sensor.dummy_pixel = 15;
286     sensor.fau_gain_white_ref = 210;
287     sensor.gain_white_ref = 200;
288     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
289     sensor.gamma = { 2.1f, 2.1f, 2.1f };
290 
291     {
292         struct CustomSensorSettings {
293             ValueFilterAny<unsigned> resolutions;
294             unsigned register_dpiset;
295             unsigned exposure_lperiod;
296             Ratio pixel_count_ratio;
297             int output_pixel_offset;
298             StaggerConfig stagger_y;
299             GenesysRegisterSettingSet custom_regs;
300         };
301 
302         CustomSensorSettings custom_settings[] = {
303             { { 50 }, 200, 7211, Ratio{1, 4}, 0, StaggerConfig{}, {
304                     { 0x08, 0x14 }, { 0x09, 0x15 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
305                     { 0x16, 0xbf }, { 0x17, 0x08 }, { 0x18, 0x3f }, { 0x19, 0x2a },
306                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x02 },
307                     { 0x52, 0x0b }, { 0x53, 0x0f }, { 0x54, 0x13 }, { 0x55, 0x17 },
308                     { 0x56, 0x03 }, { 0x57, 0x07 }, { 0x58, 0x63 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
309                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
310                 }
311             },
312             { { 100 }, 400, 7211, Ratio{1, 4}, 1, StaggerConfig{}, {
313                     { 0x08, 0x14 }, { 0x09, 0x15 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
314                     { 0x16, 0xbf }, { 0x17, 0x08 }, { 0x18, 0x3f }, { 0x19, 0x2a },
315                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x02 },
316                     { 0x52, 0x0b }, { 0x53, 0x0f }, { 0x54, 0x13 }, { 0x55, 0x17 },
317                     { 0x56, 0x03 }, { 0x57, 0x07 }, { 0x58, 0x63 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
318                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
319                 }
320             },
321             { { 150 }, 600, 7211, Ratio{1, 4}, 1, StaggerConfig{}, {
322                     { 0x08, 0x14 }, { 0x09, 0x15 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
323                     { 0x16, 0xbf }, { 0x17, 0x08 }, { 0x18, 0x3f }, { 0x19, 0x2a },
324                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x02 },
325                     { 0x52, 0x0b }, { 0x53, 0x0f }, { 0x54, 0x13 }, { 0x55, 0x17 },
326                     { 0x56, 0x03 }, { 0x57, 0x07 }, { 0x58, 0x63 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
327                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
328                 }
329             },
330             { { 300 }, 1200, 8751, Ratio{1, 4}, 3, StaggerConfig{}, {
331                     { 0x08, 0x14 }, { 0x09, 0x15 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
332                     { 0x16, 0xbf }, { 0x17, 0x08 }, { 0x18, 0x3f }, { 0x19, 0x2a },
333                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x02 },
334                     { 0x52, 0x0b }, { 0x53, 0x0f }, { 0x54, 0x13 }, { 0x55, 0x17 },
335                     { 0x56, 0x03 }, { 0x57, 0x07 }, { 0x58, 0x63 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
336                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
337                 }
338             },
339             { { 600 }, 1200, 18760, Ratio{1, 2}, 7, StaggerConfig{}, {
340                     { 0x08, 0x0e }, { 0x09, 0x0f }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
341                     { 0x16, 0xbf }, { 0x17, 0x08 }, { 0x18, 0x31 }, { 0x19, 0x2a },
342                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x02 },
343                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x0b }, { 0x55, 0x0f },
344                     { 0x56, 0x13 }, { 0x57, 0x17 }, { 0x58, 0x23 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
345                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
346                 }
347             },
348             { { 1200 }, 1200, 21749, Ratio{1, 1}, 15, StaggerConfig{4, 0}, {
349                     { 0x08, 0x02 }, { 0x09, 0x04 }, { 0x0a, 0x00 }, { 0x0b, 0x00 },
350                     { 0x16, 0xbf }, { 0x17, 0x08 }, { 0x18, 0x30 }, { 0x19, 0x2a },
351                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0xc0 }, { 0x1d, 0x42 },
352                     { 0x52, 0x0b }, { 0x53, 0x0f }, { 0x54, 0x13 }, { 0x55, 0x17 },
353                     { 0x56, 0x03 }, { 0x57, 0x07 }, { 0x58, 0x63 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
354                     { 0x5b, 0x00 }, { 0x5c, 0x0e }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
355                 }
356             },
357         };
358 
359         for (const CustomSensorSettings& setting : custom_settings)
360         {
361             sensor.resolutions = setting.resolutions;
362             sensor.register_dpiset = setting.register_dpiset;
363             sensor.exposure_lperiod = setting.exposure_lperiod;
364             sensor.pixel_count_ratio = setting.pixel_count_ratio;
365             sensor.output_pixel_offset = setting.output_pixel_offset;
366             sensor.stagger_y = setting.stagger_y;
367             sensor.custom_regs = setting.custom_regs;
368             s_sensors->push_back(sensor);
369         }
370     }
371 
372 
373     sensor = Genesys_Sensor();
374     sensor.sensor_id = SensorId::CCD_HP2300; // gl646
375     sensor.full_resolution = 600;
376     sensor.black_pixels = 48;
377     sensor.dummy_pixel = 20;
378     sensor.fau_gain_white_ref = 180;
379     sensor.gain_white_ref = 180;
380     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
381     sensor.gamma = { 2.1f, 2.1f, 2.1f };
382 
383     {
384         struct CustomSensorSettings {
385             ValueFilterAny<unsigned> resolutions;
386             unsigned optical_resolution;
387             unsigned register_dpiset;
388             unsigned exposure_lperiod;
389             Ratio pixel_count_ratio;
390             int output_pixel_offset;
391             GenesysRegisterSettingSet custom_regs;
392         };
393 
394         CustomSensorSettings custom_settings[] = {
395             { { 75 }, 300, 150, 4480, Ratio{1, 2}, 2, {
396                     { 0x08, 0x16 }, { 0x09, 0x00 }, { 0x0a, 0x01 }, { 0x0b, 0x03 },
397                     { 0x16, 0xb7 }, { 0x17, 0x0a }, { 0x18, 0x20 }, { 0x19, 0x2a },
398                     { 0x1a, 0x6a }, { 0x1b, 0x8a }, { 0x1c, 0x00 }, { 0x1d, 0x85 },
399                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
400                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
401                     { 0x5b, 0x06 }, { 0x5c, 0x0b }, { 0x5d, 0x10 }, { 0x5e, 0x16 }
402                 }
403             },
404             { { 150 }, 300, 300, 4350, Ratio{1, 2}, 5, {
405                     { 0x08, 0x16 }, { 0x09, 0x00 }, { 0x0a, 0x01 }, { 0x0b, 0x03 },
406                     { 0x16, 0xb7 }, { 0x17, 0x0a }, { 0x18, 0x20 }, { 0x19, 0x2a },
407                     { 0x1a, 0x6a }, { 0x1b, 0x8a }, { 0x1c, 0x00 }, { 0x1d, 0x85 },
408                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
409                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
410                     { 0x5b, 0x06 }, { 0x5c, 0x0b }, { 0x5d, 0x10 }, { 0x5e, 0x16 }
411                 }
412             },
413             { { 300 }, 300, 600, 4350, Ratio{1, 2}, 10, {
414                     { 0x08, 0x16 }, { 0x09, 0x00 }, { 0x0a, 0x01 }, { 0x0b, 0x03 },
415                     { 0x16, 0xb7 }, { 0x17, 0x0a }, { 0x18, 0x20 }, { 0x19, 0x2a },
416                     { 0x1a, 0x6a }, { 0x1b, 0x8a }, { 0x1c, 0x00 }, { 0x1d, 0x85 },
417                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
418                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
419                     { 0x5b, 0x06 }, { 0x5c, 0x0b }, { 0x5d, 0x10 }, { 0x5e, 0x16 }
420                 }
421             },
422             { { 600 }, 600, 600, 8700, Ratio{1, 1}, 20, {
423                     { 0x08, 0x01 }, { 0x09, 0x03 }, { 0x0a, 0x04 }, { 0x0b, 0x06 },
424                     { 0x16, 0xb7 }, { 0x17, 0x0a }, { 0x18, 0x20 }, { 0x19, 0x2a },
425                     { 0x1a, 0x6a }, { 0x1b, 0x8a }, { 0x1c, 0x00 }, { 0x1d, 0x05 },
426                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
427                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
428                     { 0x5b, 0x06 }, { 0x5c, 0x0b }, { 0x5d, 0x10 }, { 0x5e, 0x16 }
429                 }
430             },
431         };
432 
433         for (const CustomSensorSettings& setting : custom_settings)
434         {
435             sensor.resolutions = setting.resolutions;
436             sensor.optical_resolution = setting.optical_resolution;
437             sensor.register_dpiset = setting.register_dpiset;
438             sensor.exposure_lperiod = setting.exposure_lperiod;
439             sensor.pixel_count_ratio = setting.pixel_count_ratio;
440             sensor.output_pixel_offset = setting.output_pixel_offset;
441             sensor.custom_regs = setting.custom_regs;
442             s_sensors->push_back(sensor);
443         }
444     }
445 
446 
447     sensor = Genesys_Sensor();
448     sensor.sensor_id = SensorId::CIS_CANON_LIDE_35; // gl841
449     sensor.full_resolution = 1200;
450     sensor.register_dpihw = 1200;
451     sensor.black_pixels = 87;
452     sensor.dummy_pixel = 87;
453     sensor.fau_gain_white_ref = 100;
454     sensor.gain_white_ref = 100;
455     sensor.exposure = { 0x0400, 0x0400, 0x0400 };
456     sensor.custom_regs = {
457         { 0x16, 0x00 }, { 0x17, 0x02 }, { 0x18, 0x00 }, { 0x19, 0x50 },
458         { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x02 },
459         { 0x52, 0x05 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
460         { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x3a }, { 0x59, 0x03 }, { 0x5a, 0x40 },
461         { 0x70, 0x00 }, { 0x71, 0x00 }, { 0x72, 0x00 }, { 0x73, 0x00 },
462     };
463     sensor.gamma = { 1.0f, 1.0f, 1.0f };
464     {
465         struct CustomSensorSettings
466         {
467             ValueFilterAny<unsigned> resolutions;
468             unsigned optical_resolution;
469             unsigned register_dpiset;
470             unsigned shading_resolution;
471             int output_pixel_offset;
472         };
473 
474         CustomSensorSettings custom_settings[] = {
475             { { 75 }, 600, 150, 600, 11 },
476             { { 100 }, 600, 200, 600, 14 },
477             { { 150 }, 600, 300, 600, 22 },
478             { { 200 }, 600, 400, 600, 29 },
479             { { 300 }, 600, 600, 600, 44 },
480             { { 600 }, 600, 1200, 600, 88 },
481             { { 1200 }, 1200, 1200, 1200, 88 },
482         };
483 
484         for (const CustomSensorSettings& setting : custom_settings) {
485             sensor.resolutions = setting.resolutions;
486             sensor.optical_resolution = setting.optical_resolution;
487             sensor.register_dpiset = setting.register_dpiset;
488             sensor.shading_resolution = setting.shading_resolution;
489             sensor.output_pixel_offset = setting.output_pixel_offset;
490             s_sensors->push_back(sensor);
491         }
492     }
493 
494 
495     sensor = Genesys_Sensor();
496     sensor.sensor_id = SensorId::CIS_CANON_LIDE_60; // gl841
497     sensor.full_resolution = 1200;
498     sensor.register_dpihw = 1200;
499     sensor.black_pixels = 87;
500     sensor.dummy_pixel = 87;
501     sensor.fau_gain_white_ref = 100;
502     sensor.gain_white_ref = 100;
503     sensor.exposure = { 0x0400, 0x0400, 0x0400 };
504     sensor.custom_regs = {
505         { 0x16, 0x00 }, { 0x17, 0x01 }, { 0x18, 0x00 }, { 0x19, 0x50 },
506         { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x02 },
507         { 0x52, 0x05 }, { 0x53, 0x07 }, { 0x54, 0x03 }, { 0x55, 0x05 },
508         { 0x56, 0x02 }, { 0x57, 0x05 }, { 0x58, 0x3a }, { 0x59, 0x03 }, { 0x5a, 0x40 },
509         { 0x70, 0x00 }, { 0x71, 0x00 }, { 0x72, 0x00 }, { 0x73, 0x00 },
510     };
511     sensor.gamma = { 1.0f, 1.0f, 1.0f };
512     {
513         struct CustomSensorSettings
514         {
515             ValueFilterAny<unsigned> resolutions;
516             unsigned optical_resolution;
517             unsigned register_dpiset;
518             unsigned shading_resolution;
519             int output_pixel_offset;
520         };
521 
522         CustomSensorSettings custom_settings[] = {
523             { { 75 }, 600, 150, 600, 11 },
524             { { 100 }, 600, 200, 600, 14 },
525             { { 150 }, 600, 300, 600, 22 },
526             { { 200 }, 600, 400, 600, 29 },
527             { { 300 }, 600, 600, 600, 44 },
528             { { 600 }, 600, 1200, 600, 88 },
529             { { 1200 }, 1200, 1200, 1200, 88 },
530         };
531 
532         for (const CustomSensorSettings& setting : custom_settings) {
533             sensor.resolutions = setting.resolutions;
534             sensor.optical_resolution = setting.optical_resolution;
535             sensor.register_dpiset = setting.register_dpiset;
536             sensor.shading_resolution = setting.shading_resolution;
537             sensor.output_pixel_offset = setting.output_pixel_offset;
538             s_sensors->push_back(sensor);
539         }
540     }
541 
542 
543     sensor = Genesys_Sensor();
544     sensor.sensor_id = SensorId::CIS_CANON_LIDE_90; // gl842
545     sensor.full_resolution = 2400;
546     sensor.black_pixels = 20;
547     sensor.dummy_pixel = 253;
548     sensor.fau_gain_white_ref = 150;
549     sensor.gain_white_ref = 150;
550     sensor.use_host_side_calib = true;
551     sensor.custom_regs = {
552         { 0x16, 0x20 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0xff },
553         { 0x1a, 0x24 }, { 0x1c, 0x00 }, { 0x1d, 0x04 },
554         { 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x02 }, { 0x55, 0x04 },
555         { 0x56, 0x02 }, { 0x57, 0x04 }, { 0x58, 0x0a }, { 0x59, 0x71 }, { 0x5a, 0x55 },
556         { 0x70, 0x00 }, { 0x71, 0x05 }, { 0x72, 0x07 }, { 0x73, 0x09 },
557         { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff },
558         { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x3f },
559         { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x1e }, { 0x7d, 0x11 }, { 0x7f, 0x50 }
560     };
561     sensor.gamma = { 1.0f, 1.0f, 1.0f };
562     {
563         struct CustomSensorSettings
564         {
565             ValueFilterAny<unsigned> resolutions;
566             unsigned optical_resolution;
567             unsigned register_dpihw;
568             unsigned register_dpiset;
569             unsigned shading_resolution;
570             unsigned shading_factor;
571             int output_pixel_offset;
572             SensorExposure exposure;
573             unsigned exposure_lperiod;
574             unsigned segment_size;
575             std::vector<unsigned> segment_order;
576         };
577 
578         CustomSensorSettings custom_settings[] = {
579             {   { 300 }, 300, 600, 600, 300, 2, 280, { 955, 1235, 675 }, 6500, 5152,
580                 std::vector<unsigned>{} },
581             {   { 600 }, 600, 600, 600, 600, 1, 250, { 1655, 2075, 1095 }, 6536, 5152,
582                 std::vector<unsigned>{} },
583             {   { 1200 }, 1200, 1200, 1200, 1200, 1, 500, { 3055, 4175, 1935 }, 12688, 5152,
584                 {0, 1} },
585             {   { 2400 }, 2400, 2400, 2400, 2400, 1, 1000, { 5855, 7535, 3615 }, 21500, 5152,
586                 {0, 1, 2, 3} },
587         };
588 
589         for (const CustomSensorSettings& setting : custom_settings) {
590             sensor.resolutions = setting.resolutions;
591             sensor.optical_resolution = setting.optical_resolution;
592             sensor.register_dpihw = setting.register_dpihw;
593             sensor.register_dpiset = setting.register_dpiset;
594             sensor.shading_resolution = setting.shading_resolution;
595             sensor.shading_factor = setting.shading_factor;
596             sensor.output_pixel_offset = setting.output_pixel_offset;
597             sensor.exposure = setting.exposure;
598             sensor.exposure_lperiod = setting.exposure_lperiod;
599             sensor.segment_size = setting.segment_size;
600             sensor.segment_order = setting.segment_order;
601             s_sensors->push_back(sensor);
602         }
603     }
604 
605 
606     sensor = Genesys_Sensor();
607     sensor.sensor_id = SensorId::CIS_XP200; // gl646
608     sensor.full_resolution = 600;
609     sensor.black_pixels = 5;
610     sensor.dummy_pixel = 38;
611     sensor.fau_gain_white_ref = 200;
612     sensor.gain_white_ref = 200;
613     sensor.exposure = { 0x1450, 0x0c80, 0x0a28 };
614     sensor.custom_regs = {
615         { 0x08, 0x06 }, { 0x09, 0x07 }, { 0x0a, 0x0a }, { 0x0b, 0x04 },
616         { 0x16, 0x24 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x2a },
617         { 0x1a, 0x0a }, { 0x1b, 0x0a }, { 0x1c, 0x00 }, { 0x1d, 0x11 },
618         { 0x52, 0x08 }, { 0x53, 0x02 }, { 0x54, 0x00 }, { 0x55, 0x00 },
619         { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x1a }, { 0x59, 0x51 }, { 0x5a, 0x00 },
620         { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
621     };
622     sensor.gamma = { 2.1f, 2.1f, 2.1f };
623 
624     {
625         struct CustomSensorSettings {
626             ValueFilterAny<unsigned> resolutions;
627             std::vector<unsigned> channels;
628             unsigned exposure_lperiod;
629             SensorExposure exposure;
630             int output_pixel_offset;
631         };
632 
633         CustomSensorSettings custom_settings[] = {
634             {  { 75 }, { 3 },  5700, { 0x1644, 0x0c80, 0x092e }, 4 },
635             { { 100 }, { 3 },  5700, { 0x1644, 0x0c80, 0x092e }, 6 },
636             { { 200 }, { 3 },  5700, { 0x1644, 0x0c80, 0x092e }, 12 },
637             { { 300 }, { 3 },  9000, { 0x1644, 0x0c80, 0x092e }, 19 },
638             { { 600 }, { 3 }, 16000, { 0x1644, 0x0c80, 0x092e }, 38 },
639             {  { 75 }, { 1 }, 16000, { 0x050a, 0x0fa0, 0x1010 }, 4 },
640             { { 100 }, { 1 },  7800, { 0x050a, 0x0fa0, 0x1010 }, 6 },
641             { { 200 }, { 1 }, 11000, { 0x050a, 0x0fa0, 0x1010 }, 12 },
642             { { 300 }, { 1 }, 13000, { 0x050a, 0x0fa0, 0x1010 }, 19 },
643             { { 600 }, { 1 }, 24000, { 0x050a, 0x0fa0, 0x1010 }, 38 },
644         };
645 
646         for (const CustomSensorSettings& setting : custom_settings)
647         {
648             sensor.resolutions = setting.resolutions;
649             sensor.channels = setting.channels;
650             sensor.register_dpiset = setting.resolutions.values()[0];
651             sensor.exposure_lperiod = setting.exposure_lperiod;
652             sensor.exposure = setting.exposure;
653             sensor.output_pixel_offset = setting.output_pixel_offset;
654             s_sensors->push_back(sensor);
655         }
656     }
657 
658 
659     sensor = Genesys_Sensor();
660     sensor.sensor_id = SensorId::CCD_HP3670; // gl646
661     sensor.full_resolution = 1200;
662     sensor.black_pixels = 48;
663     sensor.dummy_pixel = 16;
664     sensor.fau_gain_white_ref = 210;
665     sensor.gain_white_ref = 200;
666     sensor.exposure = { 0, 0, 0 };
667     sensor.gamma = { 1.0f, 1.0f, 1.0f };
668 
669     {
670         struct CustomSensorSettings {
671             ValueFilterAny<unsigned> resolutions;
672             unsigned register_dpiset;
673             unsigned exposure_lperiod;
674             Ratio pixel_count_ratio;
675             int output_pixel_offset;
676             StaggerConfig stagger_y;
677             GenesysRegisterSettingSet custom_regs;
678         };
679 
680         CustomSensorSettings custom_settings[] = {
681             {   { 50 }, 200, 5758, Ratio{1, 4}, 0, StaggerConfig{}, {
682                     { 0x08, 0x00 }, { 0x09, 0x0a }, { 0x0a, 0x0b }, { 0x0b, 0x0d },
683                     { 0x16, 0x33 }, { 0x17, 0x07 }, { 0x18, 0x33 }, { 0x19, 0x2a },
684                     { 0x1a, 0x02 }, { 0x1b, 0x13 }, { 0x1c, 0xc0 }, { 0x1d, 0x43 },
685                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
686                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x15 }, { 0x5a, 0xc1 },
687                     { 0x5b, 0x05 }, { 0x5c, 0x0a }, { 0x5d, 0x0f }, { 0x5e, 0x00 }
688                 }
689             },
690             {   { 75 }, 300, 4879, Ratio{1, 4}, 1, StaggerConfig{}, {
691                     { 0x08, 0x00 }, { 0x09, 0x0a }, { 0x0a, 0x0b }, { 0x0b, 0x0d },
692                     { 0x16, 0x33 }, { 0x17, 0x07 }, { 0x18, 0x33 }, { 0x19, 0x2a },
693                     { 0x1a, 0x02 }, { 0x1b, 0x13 }, { 0x1c, 0xc0 }, { 0x1d, 0x43 },
694                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
695                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x15 }, { 0x5a, 0xc1 },
696                     { 0x5b, 0x05 }, { 0x5c, 0x0a }, { 0x5d, 0x0f }, { 0x5e, 0x00 }
697                 }
698             },
699             {   { 100 }, 400, 4487, Ratio{1, 4}, 1, StaggerConfig{}, {
700                     { 0x08, 0x00 }, { 0x09, 0x0a }, { 0x0a, 0x0b }, { 0x0b, 0x0d },
701                     { 0x16, 0x33 }, { 0x17, 0x07 }, { 0x18, 0x33 }, { 0x19, 0x2a },
702                     { 0x1a, 0x02 }, { 0x1b, 0x13 }, { 0x1c, 0xc0 }, { 0x1d, 0x43 },
703                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
704                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x15 }, { 0x5a, 0xc1 },
705                     { 0x5b, 0x05 }, { 0x5c, 0x0a }, { 0x5d, 0x0f }, { 0x5e, 0x00 }
706                 }
707             },
708             {   { 150 }, 600, 4879, Ratio{1, 4}, 2, StaggerConfig{}, {
709                     { 0x08, 0x00 }, { 0x09, 0x0a }, { 0x0a, 0x0b }, { 0x0b, 0x0d },
710                     { 0x16, 0x33 }, { 0x17, 0x07 }, { 0x18, 0x33 }, { 0x19, 0x2a },
711                     { 0x1a, 0x02 }, { 0x1b, 0x13 }, { 0x1c, 0xc0 }, { 0x1d, 0x43 },
712                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
713                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x15 }, { 0x5a, 0xc1 },
714                     { 0x5b, 0x05 }, { 0x5c, 0x0a }, { 0x5d, 0x0f }, { 0x5e, 0x00 }
715                 }
716             },
717             {   { 300 }, 1200, 4503, Ratio{1, 4}, 4, StaggerConfig{}, {
718                     { 0x08, 0x00 }, { 0x09, 0x0a }, { 0x0a, 0x0b }, { 0x0b, 0x0d },
719                     { 0x16, 0x33 }, { 0x17, 0x07 }, { 0x18, 0x33 }, { 0x19, 0x2a },
720                     { 0x1a, 0x02 }, { 0x1b, 0x13 }, { 0x1c, 0xc0 }, { 0x1d, 0x43 },
721                     { 0x52, 0x0f }, { 0x53, 0x13 }, { 0x54, 0x17 }, { 0x55, 0x03 },
722                     { 0x56, 0x07 }, { 0x57, 0x0b }, { 0x58, 0x83 }, { 0x59, 0x15 }, { 0x5a, 0xc1 },
723                     { 0x5b, 0x05 }, { 0x5c, 0x0a }, { 0x5d, 0x0f }, { 0x5e, 0x00 }
724                 }
725             },
726             {   { 600 }, 1200, 10251, Ratio{1, 2}, 8, StaggerConfig{}, {
727                     { 0x08, 0x00 }, { 0x09, 0x05 }, { 0x0a, 0x06 }, { 0x0b, 0x08 },
728                     { 0x16, 0x33 }, { 0x17, 0x07 }, { 0x18, 0x31 }, { 0x19, 0x2a },
729                     { 0x1a, 0x02 }, { 0x1b, 0x0e }, { 0x1c, 0xc0 }, { 0x1d, 0x43 },
730                     { 0x52, 0x0b }, { 0x53, 0x0f }, { 0x54, 0x13 }, { 0x55, 0x17 },
731                     { 0x56, 0x03 }, { 0x57, 0x07 }, { 0x58, 0x63 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
732                     { 0x5b, 0x02 }, { 0x5c, 0x0e }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
733                 }
734             },
735             {   { 1200 }, 1200, 12750, Ratio{1, 1}, 16, StaggerConfig{4, 0}, {
736                     { 0x08, 0x0d }, { 0x09, 0x0f }, { 0x0a, 0x11 }, { 0x0b, 0x13 },
737                     { 0x16, 0x2b }, { 0x17, 0x07 }, { 0x18, 0x30 }, { 0x19, 0x2a },
738                     { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0xc0 }, { 0x1d, 0x43 },
739                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x0b }, { 0x55, 0x0f },
740                     { 0x56, 0x13 }, { 0x57, 0x17 }, { 0x58, 0x23 }, { 0x59, 0x00 }, { 0x5a, 0xc1 },
741                     { 0x5b, 0x00 }, { 0x5c, 0x00 }, { 0x5d, 0x00 }, { 0x5e, 0x00 }
742                 }
743             },
744         };
745 
746         for (const CustomSensorSettings& setting : custom_settings)
747         {
748             sensor.resolutions = setting.resolutions;
749             sensor.register_dpiset = setting.register_dpiset;
750             sensor.exposure_lperiod = setting.exposure_lperiod;
751             sensor.pixel_count_ratio = setting.pixel_count_ratio;
752             sensor.output_pixel_offset = setting.output_pixel_offset;
753             sensor.stagger_y = setting.stagger_y;
754             sensor.custom_regs = setting.custom_regs;
755             s_sensors->push_back(sensor);
756         }
757     }
758 
759 
760     sensor = Genesys_Sensor();
761     sensor.sensor_id = SensorId::CCD_DP665; // gl841
762     sensor.full_resolution = 600;
763     sensor.register_dpihw = 600;
764     sensor.shading_resolution = 600;
765     sensor.black_pixels = 27;
766     sensor.dummy_pixel = 27;
767     sensor.fau_gain_white_ref = 210;
768     sensor.gain_white_ref = 200;
769     sensor.exposure = { 0x1100, 0x1100, 0x1100 };
770     sensor.custom_regs = {
771         { 0x16, 0x00 }, { 0x17, 0x02 }, { 0x18, 0x04 }, { 0x19, 0x50 },
772         { 0x1a, 0x10 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x02 },
773         { 0x52, 0x04 }, { 0x53, 0x05 }, { 0x54, 0x00 }, { 0x55, 0x00 },
774         { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x54 }, { 0x59, 0x03 }, { 0x5a, 0x00 },
775         { 0x70, 0x00 }, { 0x71, 0x00 }, { 0x72, 0x00 }, { 0x73, 0x00 },
776     };
777     sensor.gamma = { 1.0f, 1.0f, 1.0f };
778     {
779         struct CustomSensorSettings
780         {
781             ValueFilterAny<unsigned> resolutions;
782             unsigned register_dpiset;
783             int output_pixel_offset;
784         };
785 
786         CustomSensorSettings custom_settings[] = {
787             { { 75 }, 75, 1 },
788             { { 150 }, 150, 3 },
789             { { 300 }, 300, 7 },
790             { { 600 }, 600, 14 },
791             { { 1200 }, 1200, 28 },
792         };
793 
794         for (const CustomSensorSettings& setting : custom_settings) {
795             sensor.resolutions = setting.resolutions;
796             sensor.register_dpiset = setting.register_dpiset;
797             sensor.output_pixel_offset = setting.output_pixel_offset;
798             s_sensors->push_back(sensor);
799         }
800     }
801 
802     sensor = Genesys_Sensor();
803     sensor.sensor_id = SensorId::CCD_ROADWARRIOR; // gl841
804     sensor.full_resolution = 600;
805     sensor.register_dpihw = 600;
806     sensor.shading_resolution = 600;
807     sensor.black_pixels = 27;
808     sensor.dummy_pixel = 27;
809     sensor.fau_gain_white_ref = 210;
810     sensor.gain_white_ref = 200;
811     sensor.exposure = { 0x1100, 0x1100, 0x1100 };
812     sensor.custom_regs = {
813         { 0x16, 0x00 }, { 0x17, 0x02 }, { 0x18, 0x04 }, { 0x19, 0x50 },
814         { 0x1a, 0x10 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x02 },
815         { 0x52, 0x04 }, { 0x53, 0x05 }, { 0x54, 0x00 }, { 0x55, 0x00 },
816         { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x54 }, { 0x59, 0x03 }, { 0x5a, 0x00 },
817         { 0x70, 0x00 }, { 0x71, 0x00 }, { 0x72, 0x00 }, { 0x73, 0x00 },
818     };
819     sensor.gamma = { 1.0f, 1.0f, 1.0f };
820     {
821         struct CustomSensorSettings
822         {
823             ValueFilterAny<unsigned> resolutions;
824             unsigned register_dpiset;
825             int output_pixel_offset;
826         };
827 
828         CustomSensorSettings custom_settings[] = {
829             { { 75 }, 75, 1 },
830             { { 150 }, 150, 3 },
831             { { 300 }, 300, 7 },
832             { { 600 }, 600, 14 },
833             { { 1200 }, 1200, 28 },
834         };
835 
836         for (const CustomSensorSettings& setting : custom_settings) {
837             sensor.resolutions = setting.resolutions;
838             sensor.register_dpiset = setting.register_dpiset;
839             sensor.output_pixel_offset = setting.output_pixel_offset;
840             s_sensors->push_back(sensor);
841         }
842     }
843 
844 
845     sensor = Genesys_Sensor();
846     sensor.sensor_id = SensorId::CCD_DSMOBILE600; // gl841
847     sensor.full_resolution = 600;
848     sensor.register_dpihw = 600;
849     sensor.shading_resolution = 600;
850     sensor.black_pixels = 28;
851     sensor.dummy_pixel = 28;
852     sensor.fau_gain_white_ref = 210;
853     sensor.gain_white_ref = 200;
854     sensor.exposure = { 0x1544, 0x1544, 0x1544 };
855     sensor.custom_regs = {
856         { 0x16, 0x00 }, { 0x17, 0x02 }, { 0x18, 0x04 }, { 0x19, 0x50 },
857         { 0x1a, 0x10 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x02 },
858         { 0x52, 0x04 }, { 0x53, 0x05 }, { 0x54, 0x00 }, { 0x55, 0x00 },
859         { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x54 }, { 0x59, 0x03 }, { 0x5a, 0x00 },
860         { 0x70, 0x00 }, { 0x71, 0x00 }, { 0x72, 0x00 }, { 0x73, 0x00 },
861     };
862     sensor.gamma = { 1.0f, 1.0f, 1.0f };
863     {
864         struct CustomSensorSettings
865         {
866             ValueFilterAny<unsigned> resolutions;
867             unsigned register_dpiset;
868             int output_pixel_offset;
869         };
870 
871         CustomSensorSettings custom_settings[] = {
872             { { 75 }, 75, 3 },
873             { { 150 }, 150, 7 },
874             { { 300 }, 300, 14 },
875             { { 600 }, 600, 29 },
876         };
877 
878         for (const CustomSensorSettings& setting : custom_settings) {
879             sensor.resolutions = setting.resolutions;
880             sensor.register_dpiset = setting.register_dpiset;
881             sensor.output_pixel_offset = setting.output_pixel_offset;
882             s_sensors->push_back(sensor);
883         }
884     }
885 
886 
887     sensor = Genesys_Sensor();
888     sensor.sensor_id = SensorId::CCD_XP300; // gl841
889     sensor.full_resolution = 600;
890     sensor.register_dpihw = 1200; // FIXME: could be incorrect, but previous code used this value
891     sensor.shading_resolution = 600;
892     sensor.black_pixels = 27;
893     sensor.dummy_pixel = 27;
894     sensor.fau_gain_white_ref = 210;
895     sensor.gain_white_ref = 200;
896     sensor.exposure = { 0x1100, 0x1100, 0x1100 };
897     sensor.custom_regs = {
898         { 0x16, 0x00 }, { 0x17, 0x02 }, { 0x18, 0x04 }, { 0x19, 0x50 },
899         { 0x1a, 0x10 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x02 },
900         { 0x52, 0x04 }, { 0x53, 0x05 }, { 0x54, 0x00 }, { 0x55, 0x00 },
901         { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x54 }, { 0x59, 0x03 }, { 0x5a, 0x00 },
902         { 0x70, 0x00 }, { 0x71, 0x00 }, { 0x72, 0x00 }, { 0x73, 0x00 },
903     };
904     sensor.gamma = { 1.0f, 1.0f, 1.0f };
905     {
906         struct CustomSensorSettings
907         {
908             ValueFilterAny<unsigned> resolutions;
909             unsigned register_dpiset;
910             int output_pixel_offset;
911         };
912 
913         CustomSensorSettings custom_settings[] = {
914             { { 75 }, 150, 3 },
915             { { 150 }, 300, 7 },
916             { { 300 }, 600, 14 },
917             { { 600 }, 1200, 28 },
918         };
919 
920         for (const CustomSensorSettings& setting : custom_settings) {
921             sensor.resolutions = setting.resolutions;
922             sensor.register_dpiset = setting.register_dpiset;
923             sensor.output_pixel_offset = setting.output_pixel_offset;
924             s_sensors->push_back(sensor);
925         }
926     }
927 
928 
929     sensor = Genesys_Sensor();
930     sensor.sensor_id = SensorId::CCD_DOCKETPORT_487; // gl841
931     sensor.full_resolution = 600;
932     sensor.register_dpihw = 600;
933     sensor.shading_resolution = 600;
934     sensor.black_pixels = 27;
935     sensor.dummy_pixel = 27;
936     sensor.fau_gain_white_ref = 210;
937     sensor.gain_white_ref = 200;
938     sensor.exposure = { 0x1100, 0x1100, 0x1100 };
939     sensor.custom_regs = {
940         { 0x16, 0x00 }, { 0x17, 0x02 }, { 0x18, 0x04 }, { 0x19, 0x50 },
941         { 0x1a, 0x10 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x02 },
942         { 0x52, 0x04 }, { 0x53, 0x05 }, { 0x54, 0x00 }, { 0x55, 0x00 },
943         { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x54 }, { 0x59, 0x03 }, { 0x5a, 0x00 },
944         { 0x70, 0x00 }, { 0x71, 0x00 }, { 0x72, 0x00 }, { 0x73, 0x00 },
945     };
946     sensor.gamma = { 1.0f, 1.0f, 1.0f };
947     {
948         struct CustomSensorSettings
949         {
950             ValueFilterAny<unsigned> resolutions;
951             unsigned register_dpiset;
952             int output_pixel_offset;
953         };
954 
955         CustomSensorSettings custom_settings[] = {
956             { { 75 }, 150, 3 },
957             { { 150 }, 300, 7 },
958             { { 300 }, 600, 14 },
959             { { 600 }, 600, 28 },
960         };
961 
962         for (const CustomSensorSettings& setting : custom_settings) {
963             sensor.resolutions = setting.resolutions;
964             sensor.register_dpiset = setting.register_dpiset;
965             sensor.output_pixel_offset = setting.output_pixel_offset;
966             s_sensors->push_back(sensor);
967         }
968     }
969 
970 
971     sensor = Genesys_Sensor();
972     sensor.sensor_id = SensorId::CCD_DP685; // gl841
973     sensor.full_resolution = 600;
974     sensor.register_dpihw = 600;
975     sensor.shading_resolution = 600;
976     sensor.full_resolution = 600;
977     sensor.black_pixels = 27;
978     sensor.dummy_pixel = 27;
979     sensor.fau_gain_white_ref = 210;
980     sensor.gain_white_ref = 200;
981     sensor.exposure = { 0x1100, 0x1100, 0x1100 };
982     sensor.custom_regs = {
983         { 0x16, 0x00 }, { 0x17, 0x02 }, { 0x18, 0x04 }, { 0x19, 0x50 },
984         { 0x1a, 0x10 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x02 },
985         { 0x52, 0x04 }, { 0x53, 0x05 }, { 0x54, 0x00 }, { 0x55, 0x00 },
986         { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x54 }, { 0x59, 0x03 }, { 0x5a, 0x00 },
987         { 0x70, 0x00 }, { 0x71, 0x00 }, { 0x72, 0x00 }, { 0x73, 0x00 },
988     };
989     sensor.gamma = { 1.0f, 1.0f, 1.0f };
990     {
991         struct CustomSensorSettings
992         {
993             ValueFilterAny<unsigned> resolutions;
994             unsigned register_dpiset;
995             int output_pixel_offset;
996         };
997 
998         CustomSensorSettings custom_settings[] = {
999             { { 75 }, 75, 3 },
1000             { { 150 }, 150, 6 },
1001             { { 300 }, 300, 13 },
1002             { { 600 }, 600, 27 },
1003         };
1004 
1005         for (const CustomSensorSettings& setting : custom_settings) {
1006             sensor.resolutions = setting.resolutions;
1007             sensor.register_dpiset = setting.register_dpiset;
1008             sensor.output_pixel_offset = setting.output_pixel_offset;
1009             s_sensors->push_back(sensor);
1010         }
1011     }
1012 
1013 
1014     sensor = Genesys_Sensor();
1015     sensor.sensor_id = SensorId::CIS_CANON_LIDE_200; // gl847
1016     sensor.full_resolution = 4800;
1017     sensor.black_pixels = 87*4;
1018     sensor.dummy_pixel = 16*4;
1019     sensor.fau_gain_white_ref = 210;
1020     sensor.gain_white_ref = 200;
1021     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
1022     sensor.gamma = { 2.2f, 2.2f, 2.2f };
1023 
1024     {
1025         struct CustomSensorSettings {
1026             ValueFilterAny<unsigned> resolutions;
1027             unsigned register_dpihw;
1028             int exposure_lperiod;
1029             SensorExposure exposure;
1030             Ratio pixel_count_ratio;
1031             unsigned shading_factor;
1032             int output_pixel_offset;
1033             unsigned segment_size;
1034             std::vector<unsigned> segment_order;
1035             GenesysRegisterSettingSet custom_regs;
1036         };
1037 
1038         CustomSensorSettings custom_settings[] = {
1039             // Note: Windows driver uses 1424 lperiod and enables dummy line (0x17)
1040             {   { 150 }, 600, 2848, { 304, 203, 180 }, Ratio{1, 8}, 4, 80, 5136,
1041                 std::vector<unsigned>{}, {
1042                     { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff },
1043                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1044                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1045                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1046                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1047                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1048                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1049                 }
1050             },
1051             // Note: Windows driver uses 1424 lperiod and enables dummy line (0x17)
1052             {   { 200 }, 600, 2848, { 304, 203, 180 }, Ratio{1, 8}, 3, 106, 5136,
1053                 std::vector<unsigned>{}, {
1054                     { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff },
1055                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1056                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1057                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1058                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1059                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1060                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1061                 }
1062             },
1063             // Note: Windows driver uses 788 lperiod and enables dummy line (0x17)
1064             {   { 300 }, 600, 1424, { 304, 203, 180 }, Ratio{1, 8}, 2, 160, 5136,
1065                 std::vector<unsigned>{}, {
1066                     { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff },
1067                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1068                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1069                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1070                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1071                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1072                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1073                 }
1074             },
1075             // Note: Windows driver uses 788 lperiod and enables dummy line (0x17)
1076             {   { 400 }, 600, 1424, { 304, 203, 180 }, Ratio{1, 8}, 1, 213, 5136,
1077                 std::vector<unsigned>{}, {
1078                     { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff },
1079                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1080                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1081                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1082                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1083                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1084                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1085                 }
1086             },
1087             {   { 600 }, 600, 1432, { 492, 326, 296 }, Ratio{1, 8}, 1, 320, 5136,
1088                 std::vector<unsigned>{}, {
1089                     { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff },
1090                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1091                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1092                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1093                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1094                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1095                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1096                 }
1097             },
1098             {   { 1200 }, 1200, 2712, { 935, 592, 538 }, Ratio{1, 8}, 1, 640, 5136,
1099                 { 0, 1 }, {
1100                     { 0x16, 0x10 }, { 0x17, 0x08 }, { 0x18, 0x00 }, { 0x19, 0xff },
1101                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1102                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1103                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1104                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1105                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1106                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1107                 }
1108             },
1109             {   { 2400 }, 2400, 5280, { 1777, 1125, 979 }, Ratio{1, 8}, 1, 1280, 5136,
1110                 { 0, 2, 1, 3 }, {
1111                     { 0x16, 0x10 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0xff },
1112                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1113                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1114                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1115                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1116                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1117                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1118                 }
1119             },
1120             {   { 4800 }, 4800, 10416, { 3377, 2138, 1780 }, Ratio{1, 8}, 1, 2560, 5136,
1121                 { 0, 2, 4, 6, 1, 3, 5, 7 }, {
1122                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0xff },
1123                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1124                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1125                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1126                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1127                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1128                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1129                 }
1130             }
1131         };
1132 
1133         for (const auto& setting : custom_settings) {
1134             sensor.resolutions = setting.resolutions;
1135             sensor.register_dpihw = setting.register_dpihw;
1136             sensor.register_dpiset = setting.resolutions.values()[0];
1137             sensor.shading_resolution = setting.register_dpihw;
1138             sensor.exposure_lperiod = setting.exposure_lperiod;
1139             sensor.exposure = setting.exposure;
1140             sensor.pixel_count_ratio = setting.pixel_count_ratio;
1141             sensor.shading_factor = setting.shading_factor;
1142             sensor.output_pixel_offset = setting.output_pixel_offset;
1143             sensor.segment_size = setting.segment_size;
1144             sensor.segment_order = setting.segment_order;
1145             sensor.custom_regs = setting.custom_regs;
1146             s_sensors->push_back(sensor);
1147         }
1148     }
1149 
1150 
1151     sensor = Genesys_Sensor();
1152     sensor.sensor_id = SensorId::CIS_CANON_LIDE_700F; // gl847
1153     sensor.full_resolution = 4800;
1154     sensor.black_pixels = 73*8; // black pixels 73 at 600 dpi
1155     sensor.dummy_pixel = 16*8;
1156     sensor.fau_gain_white_ref = 210;
1157     sensor.gain_white_ref = 200;
1158     sensor.gamma = { 1.0f, 1.0f, 1.0f };
1159 
1160     {
1161         struct CustomSensorSettings {
1162             ValueFilterAny<unsigned> resolutions;
1163             unsigned register_dpihw;
1164             int exposure_lperiod;
1165             SensorExposure exposure;
1166             Ratio pixel_count_ratio;
1167             unsigned shading_factor;
1168             int output_pixel_offset;
1169             unsigned segment_size;
1170             std::vector<unsigned> segment_order;
1171             GenesysRegisterSettingSet custom_regs;
1172         };
1173 
1174         CustomSensorSettings custom_settings[] = {
1175             {   { 75 }, 600, 2848, { 465, 310, 239 }, Ratio{1, 8}, 8, 48, 5187,
1176                 std::vector<unsigned>{}, {
1177                     { 0x16, 0x10 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0xff },
1178                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1179                     { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1180                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1181                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 },
1182                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 },
1183                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1184                 }
1185             },
1186             {   { 100 }, 600, 2848, { 465, 310, 239 }, Ratio{1, 8}, 6, 64, 5187,
1187                 std::vector<unsigned>{}, {
1188                     { 0x16, 0x10 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0xff },
1189                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1190                     { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1191                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1192                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 },
1193                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 },
1194                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1195                 }
1196             },
1197             {   { 150 }, 600, 2848, { 465, 310, 239 }, Ratio{1, 8}, 4, 96, 5187,
1198                 std::vector<unsigned>{}, {
1199                     { 0x16, 0x10 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0xff },
1200                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1201                     { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1202                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1203                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 },
1204                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 },
1205                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1206                 }
1207             },
1208             {   { 200 }, 600, 2848, { 465, 310, 239 }, Ratio{1, 8}, 3, 128, 5187,
1209                 std::vector<unsigned>{}, {
1210                     { 0x16, 0x10 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0xff },
1211                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1212                     { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1213                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1214                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 },
1215                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 },
1216                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1217                 }
1218             },
1219             {   { 300 }, 600, 1424, { 465, 310, 239 }, Ratio{1, 8}, 2, 192, 5187,
1220                 std::vector<unsigned>{}, {
1221                     { 0x16, 0x10 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0xff },
1222                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1223                     { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1224                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1225                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 },
1226                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 },
1227                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1228                 }
1229             },
1230             {   { 600 }, 600, 1504, { 465, 310, 239 }, Ratio{1, 8}, 1, 384, 5187,
1231                 std::vector<unsigned>{}, {
1232                     { 0x16, 0x10 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0xff },
1233                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1234                     { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1235                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1236                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 },
1237                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 },
1238                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1239                 }
1240             },
1241             {   { 1200 }, 1200, 2696, { 1464, 844, 555 }, Ratio{1, 8}, 1, 768, 5187,
1242                 { 0, 1 }, {
1243                     { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff },
1244                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1245                     { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1246                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1247                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 },
1248                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 },
1249                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1250                 }
1251             },
1252             {   { 2400 }, 2400, 10576, { 2798, 1558, 972 }, Ratio{1, 8}, 1, 1536, 5187,
1253                 { 0, 1, 2, 3 }, {
1254                     { 0x16, 0x10 }, { 0x17, 0x08 }, { 0x18, 0x00 }, { 0x19, 0xff },
1255                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1256                     { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1257                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1258                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 },
1259                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 },
1260                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1261                 }
1262             },
1263             {   { 4800 }, 4800, 10576, { 2798, 1558, 972 }, Ratio{1, 8}, 1, 3072, 5187,
1264                 { 0, 1, 4, 5, 2, 3, 6, 7 }, {
1265                     { 0x16, 0x10 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0xff },
1266                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1267                     { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1268                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1269                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 },
1270                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 },
1271                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1272                 }
1273             }
1274         };
1275 
1276         for (const auto& setting : custom_settings) {
1277             sensor.resolutions = setting.resolutions;
1278             sensor.register_dpihw = setting.register_dpihw;
1279             sensor.register_dpiset = setting.resolutions.values()[0];
1280             sensor.shading_resolution = setting.register_dpihw;
1281             sensor.exposure_lperiod = setting.exposure_lperiod;
1282             sensor.exposure = setting.exposure;
1283             sensor.pixel_count_ratio = setting.pixel_count_ratio;
1284             sensor.shading_factor = setting.shading_factor;
1285             sensor.output_pixel_offset = setting.output_pixel_offset;
1286             sensor.segment_size = setting.segment_size;
1287             sensor.segment_order = setting.segment_order;
1288             sensor.custom_regs = setting.custom_regs;
1289             s_sensors->push_back(sensor);
1290         }
1291     }
1292 
1293 
1294     sensor = Genesys_Sensor();
1295     sensor.sensor_id = SensorId::CIS_CANON_LIDE_100; // gl847
1296     sensor.full_resolution = 2400;
1297     sensor.black_pixels = 87*4;
1298     sensor.dummy_pixel = 16*4;
1299     sensor.fau_gain_white_ref = 210;
1300     sensor.gain_white_ref = 200;
1301     sensor.exposure = { 0x01c1, 0x0126, 0x00e5 };
1302     sensor.gamma = { 2.2f, 2.2f, 2.2f };
1303 
1304     {
1305         struct CustomSensorSettings {
1306             ValueFilterAny<unsigned> resolutions;
1307             unsigned register_dpihw;
1308             int exposure_lperiod;
1309             SensorExposure exposure;
1310             Ratio pixel_count_ratio;
1311             unsigned shading_factor;
1312             int output_pixel_offset;
1313             unsigned segment_size;
1314             std::vector<unsigned> segment_order;
1315             GenesysRegisterSettingSet custom_regs;
1316         };
1317 
1318         CustomSensorSettings custom_settings[] = {
1319             {   { 150 }, 600, 2304, { 423, 294, 242 }, Ratio{1, 4}, 4, 80, 5136,
1320                 std::vector<unsigned>{}, {
1321                     { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff },
1322                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1323                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1324                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1325                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1326                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1327                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1328                 }
1329             },
1330             {   { 200 }, 600, 2304, { 423, 294, 242 }, Ratio{1, 4}, 3, 106, 5136,
1331                 std::vector<unsigned>{}, {
1332                     { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff },
1333                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1334                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1335                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1336                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1337                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1338                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1339                 }
1340             },
1341             {   { 300 }, 600, 1728, { 423, 294, 242 }, Ratio{1, 4}, 2, 160, 5136,
1342                 std::vector<unsigned>{}, {
1343                     { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff },
1344                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1345                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1346                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1347                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1348                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1349                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1350                 }
1351             },
1352             {   { 600 }, 600, 1432, { 423, 294, 242 }, Ratio{1, 4}, 1, 320, 5136,
1353                 std::vector<unsigned>{}, {
1354                     { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff },
1355                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1356                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1357                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1358                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1359                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1360                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1361                 },
1362             },
1363             {   { 1200 }, 1200, 2712, { 791, 542, 403 }, Ratio{1, 4}, 1, 640, 5136, {0, 1}, {
1364                     { 0x16, 0x10 }, { 0x17, 0x08 }, { 0x18, 0x00 }, { 0x19, 0xff },
1365                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1366                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1367                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1368                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1369                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1370                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1371                 }
1372             },
1373             {   { 2400 }, 2400, 5280, { 1504, 1030, 766 }, Ratio{1, 4}, 1, 1280, 5136, {0, 2, 1, 3}, {
1374                     { 0x16, 0x10 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0xff },
1375                     { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 },
1376                     { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
1377                     { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 },
1378                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
1379                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
1380                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
1381                 }
1382             }
1383         };
1384 
1385         for (const auto& setting : custom_settings) {
1386             sensor.resolutions = setting.resolutions;
1387             sensor.register_dpihw = setting.register_dpihw;
1388             sensor.register_dpiset = setting.resolutions.values()[0];
1389             sensor.shading_resolution = setting.register_dpihw;
1390             sensor.exposure_lperiod = setting.exposure_lperiod;
1391             sensor.exposure = setting.exposure;
1392             sensor.pixel_count_ratio = setting.pixel_count_ratio;
1393             sensor.shading_factor = setting.shading_factor;
1394             sensor.output_pixel_offset = setting.output_pixel_offset;
1395             sensor.segment_size = setting.segment_size;
1396             sensor.segment_order = setting.segment_order;
1397             sensor.custom_regs = setting.custom_regs;
1398             s_sensors->push_back(sensor);
1399         }
1400     }
1401 
1402     sensor = Genesys_Sensor();
1403     sensor.sensor_id = SensorId::CCD_KVSS080; // gl843
1404     sensor.full_resolution = 600;
1405     sensor.register_dpihw = 600;
1406     sensor.shading_resolution = 600;
1407     sensor.black_pixels = 38;
1408     sensor.dummy_pixel = 38;
1409     sensor.fau_gain_white_ref = 160;
1410     sensor.gain_white_ref = 160;
1411     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
1412     sensor.exposure_lperiod = 8000;
1413     sensor.custom_regs = {
1414         { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 },
1415         { 0x77, 0x00 }, { 0x78, 0xff }, { 0x79, 0xff },
1416         { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff },
1417         { 0x0c, 0x00 },
1418         { 0x70, 0x01 },
1419         { 0x71, 0x03 },
1420         { 0x9e, 0x00 },
1421         { 0xaa, 0x00 },
1422         { 0x16, 0x33 },
1423         { 0x17, 0x1c },
1424         { 0x18, 0x00 },
1425         { 0x19, 0x2a },
1426         { 0x1a, 0x2c },
1427         { 0x1b, 0x00 },
1428         { 0x1c, 0x20 },
1429         { 0x1d, 0x04 },
1430         { 0x52, 0x0c },
1431         { 0x53, 0x0f },
1432         { 0x54, 0x00 },
1433         { 0x55, 0x03 },
1434         { 0x56, 0x06 },
1435         { 0x57, 0x09 },
1436         { 0x58, 0x6b },
1437         { 0x59, 0x00 },
1438         { 0x5a, 0xc0 },
1439         { 0x7d, 0x90 },
1440     };
1441     sensor.gamma = { 1.0f, 1.0f, 1.0f };
1442     {
1443         struct CustomSensorSettings
1444         {
1445             ValueFilterAny<unsigned> resolutions;
1446             unsigned register_dpiset;
1447             Ratio pixel_count_ratio;
1448             int output_pixel_offset;
1449         };
1450 
1451         CustomSensorSettings custom_settings[] = {
1452             { { 75 }, 75, Ratio{1, 1}, 4 },
1453             { { 100 }, 100, Ratio{1, 1}, 6 },
1454             { { 150 }, 150, Ratio{1, 1}, 9 },
1455             { { 200 }, 200, Ratio{1, 1}, 12 },
1456             { { 300 }, 300, Ratio{1, 1}, 19 },
1457             { { 600 }, 600, Ratio{1, 1}, 38 },
1458         };
1459 
1460         for (const CustomSensorSettings& setting : custom_settings) {
1461             sensor.resolutions = setting.resolutions;
1462             sensor.register_dpiset = setting.register_dpiset;
1463             sensor.pixel_count_ratio = setting.pixel_count_ratio;
1464             sensor.output_pixel_offset = setting.output_pixel_offset;
1465             s_sensors->push_back(sensor);
1466         }
1467     }
1468 
1469     sensor = Genesys_Sensor();
1470     sensor.sensor_id = SensorId::CCD_G4050; // gl843
1471     sensor.full_resolution = 4800;
1472     sensor.black_pixels = 50*8;
1473     // 31 at 600 dpi dummy_pixels 58 at 1200
1474     sensor.dummy_pixel = 58;
1475     sensor.fau_gain_white_ref = 160;
1476     sensor.gain_white_ref = 160;
1477     sensor.exposure = { 0x2c09, 0x22b8, 0x10f0 };
1478     sensor.custom_regs = {};
1479     sensor.gamma = { 1.0f, 1.0f, 1.0f };
1480 
1481     {
1482         struct CustomSensorSettings {
1483             ValueFilterAny<unsigned> resolutions;
1484             unsigned register_dpihw;
1485             unsigned register_dpiset;
1486             int exposure_lperiod;
1487             ScanMethod method;
1488             Ratio pixel_count_ratio;
1489             int output_pixel_offset;
1490             StaggerConfig stagger_y; // FIXME: may be incorrect
1491             GenesysRegisterSettingSet extra_custom_regs;
1492         };
1493 
1494         GenesysRegisterSettingSet regs_100_to_600 = {
1495             { 0x0c, 0x00 },
1496             { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0x2a },
1497             { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x08 },
1498             { 0x52, 0x0b }, { 0x53, 0x0e }, { 0x54, 0x11 }, { 0x55, 0x02 }, { 0x56, 0x05 },
1499             { 0x57, 0x08 }, { 0x58, 0x63 }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1500             { 0x70, 0x00 }, { 0x71, 0x02 },
1501             { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff },
1502             { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff },
1503             { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, { 0x7d, 0x90 },
1504             { 0x9e, 0x00 },
1505             { 0xaa, 0x00 },
1506         };
1507 
1508         GenesysRegisterSettingSet regs_1200 = {
1509             { 0x0c, 0x20 },
1510             { 0x16, 0x3b }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a },
1511             { 0x1a, 0x38 }, { 0x1b, 0x10 }, { 0x1c, 0x00 }, { 0x1d, 0x08 },
1512             { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b }, { 0x56, 0x0e },
1513             { 0x57, 0x11 }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1514             { 0x70, 0x08 }, { 0x71, 0x0c },
1515             { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff },
1516             { 0x77, 0x00 }, { 0x78, 0x01 }, { 0x79, 0xff },
1517             { 0x7a, 0x00 }, { 0x7b, 0x01 }, { 0x7c, 0xff }, { 0x7d, 0x90 },
1518             { 0x9e, 0xc0 },
1519             { 0xaa, 0x05 },
1520         };
1521 
1522         GenesysRegisterSettingSet regs_2400 = {
1523             { 0x0c, 0x20 },
1524             { 0x16, 0x3b }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a },
1525             { 0x1a, 0x38 }, { 0x1b, 0x10 }, { 0x1c, 0xc0 }, { 0x1d, 0x08 },
1526             { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b }, { 0x56, 0x0e },
1527             { 0x57, 0x11 }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1528             { 0x70, 0x08 }, { 0x71, 0x0a },
1529             { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff },
1530             { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
1531             { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, { 0x7d, 0x90 },
1532             { 0x9e, 0xc0 },
1533             { 0xaa, 0x05 },
1534         };
1535 
1536         GenesysRegisterSettingSet regs_4800 = {
1537             { 0x0c, 0x21 },
1538             { 0x16, 0x3b }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a },
1539             { 0x1a, 0x38 }, { 0x1b, 0x10 }, { 0x1c, 0xc1 }, { 0x1d, 0x08 },
1540             { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b }, { 0x56, 0x0e },
1541             { 0x57, 0x11 }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1542             { 0x70, 0x08 }, { 0x71, 0x0a },
1543             { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff },
1544             { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
1545             { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, { 0x7d, 0x90 },
1546             { 0x9e, 0xc0 },
1547             { 0xaa, 0x07 },
1548         };
1549 
1550         GenesysRegisterSettingSet regs_ta_any = {
1551             { 0x0c, 0x00 },
1552             { 0x16, 0x33 }, { 0x17, 0x4c }, { 0x18, 0x01 }, { 0x19, 0x2a },
1553             { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x08 },
1554             { 0x52, 0x0e }, { 0x53, 0x11 }, { 0x54, 0x02 }, { 0x55, 0x05 }, { 0x56, 0x08 },
1555             { 0x57, 0x0b }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0xc0 },
1556             { 0x70, 0x00 }, { 0x71, 0x02 },
1557             { 0x74, 0x00 }, { 0x75, 0x1c }, { 0x76, 0x7f },
1558             { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff },
1559             { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, { 0x7d, 0x90 },
1560             { 0x9e, 0x00 },
1561             { 0xaa, 0x00 },
1562         };
1563 
1564         CustomSensorSettings custom_settings[] = {
1565             {   { 100 }, 600, 100, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 1,
1566                 StaggerConfig{}, regs_100_to_600 },
1567             {   { 150 }, 600, 150, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 1,
1568                 StaggerConfig{}, regs_100_to_600 },
1569             {   { 200 }, 600, 200, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 2,
1570                 StaggerConfig{}, regs_100_to_600 },
1571             {   { 300 }, 600, 300, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 3,
1572                 StaggerConfig{}, regs_100_to_600 },
1573             {   { 400 }, 600, 400, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 4,
1574                 StaggerConfig{}, regs_100_to_600 },
1575             {   { 600 }, 600, 600, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 7,
1576                 StaggerConfig{}, regs_100_to_600 },
1577             {   { 1200 }, 1200, 1200, 56064, ScanMethod::FLATBED, Ratio{1, 4}, 14,
1578                 StaggerConfig{}, regs_1200 },
1579             {   { 2400 }, 2400, 2400, 56064, ScanMethod::FLATBED, Ratio{1, 2}, 29,
1580                 StaggerConfig{4, 0}, regs_2400 },
1581             {   { 4800 }, 4800, 4800, 42752, ScanMethod::FLATBED, Ratio{1, 1}, 58,
1582                 StaggerConfig{8, 0}, regs_4800 },
1583             {   { 100, 150, 200, 300, 400, 600, 1200 }, 600, 600, 15624, ScanMethod::TRANSPARENCY,
1584                 Ratio{1, 1}, 58, StaggerConfig{}, regs_ta_any }, // FIXME: may be incorrect
1585             {   { 2400 }, 600, 600, 15624, ScanMethod::TRANSPARENCY,
1586                 Ratio{1, 1}, 58, StaggerConfig{4, 0}, regs_ta_any }, // FIXME: may be incorrect
1587             {   { 4800 }, 600, 600, 15624, ScanMethod::TRANSPARENCY,
1588                 Ratio{1, 1}, 58, StaggerConfig{8, 0}, regs_ta_any }, // FIXME: may be incorrect
1589         };
1590 
1591         auto base_custom_regs = sensor.custom_regs;
1592         for (const CustomSensorSettings& setting : custom_settings)
1593         {
1594             sensor.resolutions = setting.resolutions;
1595             sensor.register_dpihw = setting.register_dpihw;
1596             sensor.register_dpiset = setting.register_dpiset;
1597             sensor.shading_resolution = setting.register_dpihw;
1598             sensor.exposure_lperiod = setting.exposure_lperiod;
1599             sensor.method = setting.method;
1600             sensor.pixel_count_ratio = setting.pixel_count_ratio;
1601             sensor.output_pixel_offset = setting.output_pixel_offset;
1602             sensor.stagger_y = setting.stagger_y;
1603             sensor.custom_regs = base_custom_regs;
1604             sensor.custom_regs.merge(setting.extra_custom_regs);
1605             s_sensors->push_back(sensor);
1606         }
1607     }
1608 
1609     sensor = Genesys_Sensor();
1610     sensor.sensor_id = SensorId::CCD_HP_4850C; // gl843
1611     sensor.full_resolution = 4800;
1612     sensor.black_pixels = 100;
1613     sensor.dummy_pixel = 58;
1614     sensor.fau_gain_white_ref = 160;
1615     sensor.gain_white_ref = 160;
1616     sensor.exposure = { 0x2c09, 0x22b8, 0x10f0 };
1617     sensor.custom_regs = {};
1618     sensor.gamma = { 1.0f, 1.0f, 1.0f };
1619 
1620     {
1621         struct CustomSensorSettings {
1622             ValueFilterAny<unsigned> resolutions;
1623             unsigned register_dpihw;
1624             unsigned register_dpiset;
1625             int exposure_lperiod;
1626             ScanMethod method;
1627             Ratio pixel_count_ratio;
1628             int output_pixel_offset;
1629             int shading_pixel_offset;
1630             StaggerConfig stagger_y; // FIXME: review, may be incorrect
1631             GenesysRegisterSettingSet extra_custom_regs;
1632         };
1633 
1634         GenesysRegisterSettingSet regs_100_to_600 = {
1635             { 0x0c, 0x00 },
1636             { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0x2a },
1637             { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x08 },
1638             { 0x52, 0x0b }, { 0x53, 0x0e }, { 0x54, 0x11 }, { 0x55, 0x02 },
1639             { 0x56, 0x05 }, { 0x57, 0x08 }, { 0x58, 0x63 }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1640             { 0x70, 0x00 }, { 0x71, 0x02 },
1641             { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff },
1642             { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff },
1643             { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, { 0x7d, 0x90 },
1644             { 0x9e, 0x00 },
1645             { 0xaa, 0x00 },
1646         };
1647         GenesysRegisterSettingSet regs_1200 = {
1648             { 0x0c, 0x20 },
1649             { 0x16, 0x3b }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a },
1650             { 0x1a, 0x38 }, { 0x1b, 0x10 }, { 0x1c, 0x00 }, { 0x1d, 0x08 },
1651             { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b },
1652             { 0x56, 0x0e }, { 0x57, 0x11 }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1653             { 0x70, 0x08 }, { 0x71, 0x0c },
1654             { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff },
1655             { 0x77, 0x00 }, { 0x78, 0x01 }, { 0x79, 0xff },
1656             { 0x7a, 0x00 }, { 0x7b, 0x01 }, { 0x7c, 0xff }, { 0x7d, 0x90 },
1657             { 0x9e, 0xc0 },
1658             { 0xaa, 0x05 },
1659         };
1660         GenesysRegisterSettingSet regs_2400 = {
1661             { 0x0c, 0x20 },
1662             { 0x16, 0x3b }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a },
1663             { 0x1a, 0x38 }, { 0x1b, 0x10 }, { 0x1c, 0xc0 }, { 0x1d, 0x08 },
1664             { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b },
1665             { 0x56, 0x0e }, { 0x57, 0x11 }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1666             { 0x70, 0x08 }, { 0x71, 0x0a },
1667             { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff },
1668             { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
1669             { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, { 0x7d, 0x90 },
1670             { 0x9e, 0xc0 },
1671             { 0xaa, 0x05 },
1672         };
1673         GenesysRegisterSettingSet regs_4800 = {
1674             { 0x0c, 0x21 },
1675             { 0x16, 0x3b }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a },
1676             { 0x1a, 0x38 }, { 0x1b, 0x10 }, { 0x1c, 0xc1 }, { 0x1d, 0x08 },
1677             { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b },
1678             { 0x56, 0x0e }, { 0x57, 0x11 }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1679             { 0x70, 0x08 }, { 0x71, 0x0a },
1680             { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff },
1681             { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
1682             { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, { 0x7d, 0x90 },
1683             { 0x9e, 0xc0 },
1684             { 0xaa, 0x07 },
1685         };
1686         GenesysRegisterSettingSet regs_ta_any = {
1687             { 0x0c, 0x00 },
1688             { 0x16, 0x33 }, { 0x17, 0x4c }, { 0x18, 0x01 }, { 0x19, 0x2a },
1689             { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x08 },
1690             { 0x52, 0x0e }, { 0x53, 0x11 }, { 0x54, 0x02 }, { 0x55, 0x05 },
1691             { 0x56, 0x08 }, { 0x57, 0x0b }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0xc0 },
1692             { 0x70, 0x00 }, { 0x71, 0x02 },
1693             { 0x74, 0x00 }, { 0x75, 0x1c }, { 0x76, 0x7f },
1694             { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff },
1695             { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, { 0x7d, 0x90 },
1696             { 0x9e, 0x00 },
1697             { 0xaa, 0x00 },
1698         };
1699 
1700         CustomSensorSettings custom_settings[] = {
1701             {   { 100 }, 600, 100, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 1, 50, StaggerConfig{},
1702                 regs_100_to_600 },
1703             {   { 150 }, 600, 150, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 1, 50, StaggerConfig{},
1704                 regs_100_to_600 },
1705             {   { 200 }, 600, 200, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 2, 50, StaggerConfig{},
1706                 regs_100_to_600 },
1707             {   { 300 }, 600, 300, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 3, 50, StaggerConfig{},
1708                 regs_100_to_600 },
1709             {   { 400 }, 600, 400, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 4, 50, StaggerConfig{},
1710                 regs_100_to_600 },
1711             {   { 600 }, 600, 600, 8016, ScanMethod::FLATBED, Ratio{1, 8}, 7, 50, StaggerConfig{},
1712                 regs_100_to_600 },
1713             {   { 1200 }, 1200, 1200, 56064, ScanMethod::FLATBED, Ratio{1, 4}, 14, 0,
1714                 StaggerConfig{}, regs_1200 },
1715             {   { 2400 }, 2400, 2400, 56064, ScanMethod::FLATBED, Ratio{1, 2}, 29, 0,
1716                 StaggerConfig{0, 4}, regs_2400 },
1717             {   { 4800 }, 4800, 4800, 42752, ScanMethod::FLATBED, Ratio{1, 1}, 58, 0,
1718                 StaggerConfig{0, 8}, regs_4800 },
1719             {   { 100, 150, 200, 300, 400, 600, 1200}, 600, 600, 15624, ScanMethod::TRANSPARENCY,
1720                 Ratio{1, 1}, 58, 0, StaggerConfig{}, regs_ta_any }, // FIXME: review
1721             {   { 2400 }, 600, 600, 15624, ScanMethod::TRANSPARENCY,
1722                 Ratio{1, 1}, 58, 0, StaggerConfig{0, 4}, regs_ta_any }, // FIXME: review
1723             {   { 4800 }, 600, 600, 15624, ScanMethod::TRANSPARENCY,
1724                 Ratio{1, 1}, 58, 0, StaggerConfig{0, 8}, regs_ta_any }, // FIXME: review
1725         };
1726 
1727         auto base_custom_regs = sensor.custom_regs;
1728         for (const CustomSensorSettings& setting : custom_settings)
1729         {
1730             sensor.resolutions = setting.resolutions;
1731             sensor.register_dpihw = setting.register_dpihw;
1732             sensor.register_dpiset = setting.register_dpiset;
1733             sensor.shading_resolution = setting.register_dpihw;
1734             sensor.exposure_lperiod = setting.exposure_lperiod;
1735             sensor.method = setting.method;
1736             sensor.pixel_count_ratio = setting.pixel_count_ratio;
1737             sensor.output_pixel_offset = setting.output_pixel_offset;
1738             sensor.shading_pixel_offset = setting.shading_pixel_offset;
1739             sensor.stagger_y = setting.stagger_y;
1740             sensor.custom_regs = base_custom_regs;
1741             sensor.custom_regs.merge(setting.extra_custom_regs);
1742             s_sensors->push_back(sensor);
1743         }
1744     }
1745 
1746     sensor = Genesys_Sensor();
1747     sensor.sensor_id = SensorId::CCD_CANON_4400F; // gl843
1748     sensor.full_resolution = 4800;
1749     sensor.register_dpihw = 4800;
1750     sensor.black_pixels = 50*8;
1751     // 31 at 600 dpi, 58 at 1200 dpi
1752     sensor.dummy_pixel = 20;
1753     sensor.fau_gain_white_ref = 160;
1754     sensor.gain_white_ref = 160;
1755     sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 };
1756     sensor.gamma = { 1.0f, 1.0f, 1.0f };
1757 
1758     {
1759         struct CustomSensorSettings {
1760             ValueFilterAny<unsigned> resolutions;
1761             unsigned optical_resolution;
1762             unsigned register_dpiset;
1763             int exposure_lperiod;
1764             bool use_host_side_calib;
1765             int output_pixel_offset;
1766             std::vector<ScanMethod> methods;
1767             StaggerConfig stagger_y;
1768             GenesysRegisterSettingSet extra_custom_regs;
1769             GenesysRegisterSettingSet extra_custom_fe_regs;
1770         };
1771 
1772         CustomSensorSettings custom_settings[] = {
1773             {   { 300 }, 1200, 1200, 11640, false, 197, { ScanMethod::FLATBED }, StaggerConfig{}, {
1774                     { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a },
1775                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b },
1776                     { 0x52, 0x0a }, { 0x53, 0x0d }, { 0x54, 0x00 }, { 0x55, 0x03 },
1777                     { 0x56, 0x06 }, { 0x57, 0x08 }, { 0x58, 0x5b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1778                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x01 }, { 0x73, 0x03 },
1779                     { 0x74, 0x00 }, { 0x75, 0xf8 }, { 0x76, 0x38 },
1780                     { 0x77, 0x00 }, { 0x78, 0xfc }, { 0x79, 0x00 },
1781                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0xa4 },
1782                     { 0x9e, 0x2d },
1783                 }, {}
1784             },
1785             {   { 600 }, 1200, 2400, 11640, false, 392, { ScanMethod::FLATBED }, StaggerConfig{}, {
1786                     { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a },
1787                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b },
1788                     { 0x52, 0x0a }, { 0x53, 0x0d }, { 0x54, 0x00 }, { 0x55, 0x03 },
1789                     { 0x56, 0x06 }, { 0x57, 0x08 }, { 0x58, 0x5b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1790                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x01 }, { 0x73, 0x03 },
1791                     { 0x74, 0x00 }, { 0x75, 0xf8 }, { 0x76, 0x38 },
1792                     { 0x77, 0x00 }, { 0x78, 0xfc }, { 0x79, 0x00 },
1793                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0xa4 },
1794                     { 0x9e, 0x2d },
1795                 }, {}
1796             },
1797             {   { 1200 }, 1200, 4800, 11640, false, 794, { ScanMethod::FLATBED }, StaggerConfig{}, {
1798                     { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a },
1799                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b },
1800                     { 0x52, 0x0a }, { 0x53, 0x0d }, { 0x54, 0x00 }, { 0x55, 0x03 },
1801                     { 0x56, 0x06 }, { 0x57, 0x08 }, { 0x58, 0x5b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1802                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x01 }, { 0x73, 0x03 },
1803                     { 0x74, 0x00 }, { 0x75, 0xf8 }, { 0x76, 0x38 },
1804                     { 0x77, 0x00 }, { 0x78, 0xfc }, { 0x79, 0x00 },
1805                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0xa4 },
1806                     { 0x9e, 0x2d },
1807                 }, {}
1808             },
1809             {   { 1200 }, 1200, 4800, 33300, true, 5, { ScanMethod::TRANSPARENCY },
1810                 StaggerConfig{}, {
1811                     { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a },
1812                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b },
1813                     { 0x52, 0x0a }, { 0x53, 0x0d }, { 0x54, 0x00 }, { 0x55, 0x03 },
1814                     { 0x56, 0x06 }, { 0x57, 0x08 }, { 0x58, 0x5b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1815                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x00 }, { 0x73, 0x02 },
1816                     { 0x74, 0x00 }, { 0x75, 0xf8 }, { 0x76, 0x38 },
1817                     { 0x77, 0x00 }, { 0x78, 0xfc }, { 0x79, 0x00 },
1818                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0xa4 },
1819                     { 0x9e, 0x2d },
1820                 }, {}
1821             },
1822             {   { 2400 }, 2400, 4800, 33300, true, 10, { ScanMethod::TRANSPARENCY },
1823                 StaggerConfig{}, {
1824                     { 0x16, 0x13 }, { 0x17, 0x15 }, { 0x18, 0x10 }, { 0x19, 0x2a },
1825                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x01 }, { 0x1d, 0x75 },
1826                     { 0x52, 0x0b }, { 0x53, 0x0d }, { 0x54, 0x00 }, { 0x55, 0x03 },
1827                     { 0x56, 0x06 }, { 0x57, 0x09 }, { 0x58, 0x53 }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1828                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 },
1829                     { 0x74, 0x00 }, { 0x75, 0xff }, { 0x76, 0x00 },
1830                     { 0x77, 0x00 }, { 0x78, 0xff }, { 0x79, 0x00 },
1831                     { 0x7a, 0x00 }, { 0x7b, 0x54 }, { 0x7c, 0x92 },
1832                     { 0x9e, 0x2d },
1833                 }, {
1834                     { 0x03, 0x1f },
1835                 }
1836             },
1837             {   { 4800 }, 4800, 4800, 33300, true, -2063, { ScanMethod::TRANSPARENCY },
1838                 StaggerConfig{0, 8}, {
1839                     { 0x16, 0x13 }, { 0x17, 0x15 }, { 0x18, 0x10 }, { 0x19, 0x2a },
1840                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x61 }, { 0x1d, 0x75 },
1841                     { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b },
1842                     { 0x56, 0x0d }, { 0x57, 0x0f }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
1843                     { 0x70, 0x08 }, { 0x71, 0x0a }, { 0x72, 0x0a }, { 0x73, 0x0c },
1844                     { 0x74, 0x00 }, { 0x75, 0xff }, { 0x76, 0xff },
1845                     { 0x77, 0x00 }, { 0x78, 0xff }, { 0x79, 0xff },
1846                     { 0x7a, 0x00 }, { 0x7b, 0x54 }, { 0x7c, 0x92 },
1847                     { 0x9e, 0x2d },
1848                 }, {}
1849             }
1850         };
1851 
1852         for (const CustomSensorSettings& setting : custom_settings)
1853         {
1854             for (auto method : setting.methods) {
1855                 for (auto resolution : setting.resolutions.values()) {
1856                     sensor.resolutions = { resolution };
1857                     sensor.optical_resolution = setting.optical_resolution;
1858                     sensor.register_dpiset = setting.register_dpiset;
1859                     sensor.shading_resolution = resolution;
1860                     sensor.exposure_lperiod = setting.exposure_lperiod;
1861                     sensor.output_pixel_offset = setting.output_pixel_offset;
1862                     sensor.use_host_side_calib = setting.use_host_side_calib;
1863                     sensor.method = method;
1864                     sensor.stagger_y = setting.stagger_y;
1865                     sensor.custom_regs = setting.extra_custom_regs;
1866                     sensor.custom_fe_regs = setting.extra_custom_fe_regs;
1867                     s_sensors->push_back(sensor);
1868                 }
1869             }
1870         }
1871     }
1872 
1873 
1874     sensor = Genesys_Sensor();
1875     sensor.sensor_id = SensorId::CCD_CANON_5600F; // gl847
1876     sensor.full_resolution = 4800;
1877     sensor.register_dpihw = 4800;
1878     sensor.black_pixels = 50*8;
1879     sensor.dummy_pixel = 10;
1880     sensor.fau_gain_white_ref = 160;
1881     sensor.gain_white_ref = 160;
1882     sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 };
1883     sensor.gamma = { 1.0f, 1.0f, 1.0f };
1884     sensor.use_host_side_calib = true;
1885     {
1886         struct CustomSensorSettings {
1887             ValueFilterAny<unsigned> resolutions;
1888             unsigned optical_resolution;
1889             unsigned register_dpihw;
1890             unsigned register_dpiset;
1891             int exposure_lperiod;
1892             SensorExposure exposure;
1893             Ratio pixel_count_ratio;
1894             int output_pixel_offset;
1895             unsigned segment_size;
1896             std::vector<unsigned> segment_order;
1897             StaggerConfig stagger_x;
1898             StaggerConfig stagger_y;
1899             GenesysRegisterSettingSet custom_regs;
1900         };
1901 
1902         CustomSensorSettings custom_settings[] = {
1903             {   { 150 }, 2400, 600, 300, 4288, { 3983/2, 3983/2, 3983/2 }, Ratio{1, 8}, 10,
1904                 5418, std::vector<unsigned>{}, StaggerConfig{}, StaggerConfig{},  {
1905                     { 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
1906                     { 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
1907                     { 0x52, 0x0e }, { 0x53, 0x00 }, { 0x54, 0x02 }, { 0x55, 0x04 },
1908                     { 0x56, 0x06 }, { 0x57, 0x08 }, { 0x58, 0x52 }, { 0x59, 0x3a }, { 0x5a, 0x40 },
1909                     { 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
1910                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
1911                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
1912                 }
1913             },
1914             {   { 300 }, 2400, 600, 600, 5472, { 4558/2, 4558/2, 4558/2 }, Ratio{1, 8}, 110,
1915                 5418, std::vector<unsigned>{}, StaggerConfig{}, StaggerConfig{}, {
1916                     { 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
1917                     { 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
1918                     { 0x52, 0x0e }, { 0x53, 0x00 }, { 0x54, 0x02 }, { 0x55, 0x04 },
1919                     { 0x56, 0x06 }, { 0x57, 0x08 }, { 0x58, 0x52 }, { 0x59, 0x3a }, { 0x5a, 0x40 },
1920                     { 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
1921                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
1922                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
1923                 }
1924             },
1925             {   { 600 }, 2400, 600, 600, 10944, { 8701/2, 8701/2, 8701/2 }, Ratio{1, 4}, 155,
1926                 5418, std::vector<unsigned>{}, StaggerConfig{}, StaggerConfig{}, {
1927                     { 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
1928                     { 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
1929                     { 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 },
1930                     { 0x56, 0x0a }, { 0x57, 0x0c }, { 0x58, 0x72 }, { 0x59, 0x5a }, { 0x5a, 0x40 },
1931                     { 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
1932                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
1933                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
1934                 }
1935             },
1936             {   { 1200 }, 2400, 1200, 1200, 29120, { 17120/2, 17120/2, 17120/2 }, Ratio{1, 2}, 295,
1937                 5418, { 1, 0 }, StaggerConfig{}, StaggerConfig{}, {
1938                     { 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
1939                     { 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
1940                     { 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 },
1941                     { 0x56, 0x0a }, { 0x57, 0x0c }, { 0x58, 0x72 }, { 0x59, 0x5a }, { 0x5a, 0x40 },
1942                     { 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
1943                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
1944                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
1945                 }
1946             },
1947             {   { 2400 }, 2400, 2400, 2400, 43776, { 36725/2, 36725/2, 36725/2 }, Ratio{1, 1}, 600,
1948                 5418, { 0, 1, 2, 3 },
1949                 StaggerConfig{10, 15, 4, 9, 14, 19, 8, 13}, StaggerConfig{}, {
1950                     { 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
1951                     { 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
1952                     { 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 },
1953                     { 0x56, 0x0a }, { 0x57, 0x0c }, { 0x58, 0x72 }, { 0x59, 0x5a }, { 0x5a, 0x40 },
1954                     { 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
1955                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
1956                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
1957                 }
1958             },
1959             {   { 4800 }, 4800, 4800, 4800, 43776, { 36725/2, 36725/2, 36725/2 }, Ratio{1, 1}, 1000,
1960                 10784, { 0, 1, 2, 3 },
1961                 StaggerConfig{5, 9, 6, 10, 3, 7, 16, 20, 13, 17, 14, 18, 11, 15, 24, 28},
1962                 StaggerConfig{6, 0}, {
1963                     { 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
1964                     { 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
1965                     { 0x52, 0x0a }, { 0x53, 0x0c }, { 0x54, 0x0e }, { 0x55, 0x00 },
1966                     { 0x56, 0x02 }, { 0x57, 0x04 }, { 0x58, 0x32 }, { 0x59, 0x1a }, { 0x5a, 0x40 },
1967                     { 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
1968                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
1969                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
1970                 }
1971             }
1972         };
1973 
1974         for (const auto& setting : custom_settings) {
1975             for (auto method : { ScanMethod::FLATBED, ScanMethod::TRANSPARENCY }) {
1976                 sensor.method = method;
1977                 sensor.resolutions = setting.resolutions;
1978                 sensor.optical_resolution = setting.optical_resolution;
1979                 sensor.register_dpihw = setting.register_dpihw;
1980                 sensor.register_dpiset = setting.register_dpiset;
1981                 sensor.shading_resolution = setting.resolutions.values().front();
1982                 sensor.exposure_lperiod = setting.exposure_lperiod;
1983                 sensor.exposure = setting.exposure;
1984                 sensor.pixel_count_ratio = setting.pixel_count_ratio;
1985                 sensor.output_pixel_offset = setting.output_pixel_offset;
1986                 sensor.segment_size = setting.segment_size;
1987                 sensor.segment_order = setting.segment_order;
1988                 sensor.stagger_x = setting.stagger_x;
1989                 sensor.stagger_y = setting.stagger_y;
1990                 sensor.custom_regs = setting.custom_regs;
1991                 s_sensors->push_back(sensor);
1992             }
1993         }
1994     }
1995 
1996 
1997     sensor = Genesys_Sensor();
1998     sensor.sensor_id = SensorId::CCD_CANON_8400F; // gl843
1999     sensor.full_resolution = 3200;
2000     sensor.register_dpihw = 4800;
2001     sensor.black_pixels = 50*8;
2002     // 31 at 600 dpi, 58 at 1200 dpi
2003     sensor.dummy_pixel = 20;
2004     sensor.fau_gain_white_ref = 160;
2005     sensor.gain_white_ref = 160;
2006     sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 };
2007     sensor.custom_regs = {};
2008     sensor.gamma = { 1.0f, 1.0f, 1.0f };
2009 
2010     {
2011         struct CustomSensorSettings {
2012             ValueFilterAny<unsigned> resolutions;
2013             unsigned register_dpiset;
2014             Ratio pixel_count_ratio;
2015             int exposure_lperiod;
2016             int output_pixel_offset;
2017             int shading_pixel_offset;
2018             std::vector<ScanMethod> methods;
2019             StaggerConfig stagger_y;
2020             GenesysRegisterSettingSet extra_custom_regs;
2021             GenesysRegisterSettingSet custom_fe_regs;
2022         };
2023 
2024         CustomSensorSettings custom_settings[] = {
2025             {   { 400 }, 2400, Ratio{1, 4}, 7200, 2, 0, { ScanMethod::FLATBED },
2026                 StaggerConfig{}, {
2027                     { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x13 }, { 0x19, 0x2a },
2028                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x84 }, { 0x1e, 0xa0 },
2029                     { 0x52, 0x0d }, { 0x53, 0x10 }, { 0x54, 0x01 }, { 0x55, 0x04 },
2030                     { 0x56, 0x07 }, { 0x57, 0x0a }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2031                     { 0x70, 0x01 }, { 0x71, 0x02 }, { 0x72, 0x03 }, { 0x73, 0x04 },
2032                     { 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f },
2033                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2034                     { 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb },
2035                     { 0x80, 0x2a },
2036                 }, {}
2037             },
2038             {   { 800 }, 4800, Ratio{1, 4}, 7200, 5, 13, { ScanMethod::FLATBED },
2039                 StaggerConfig{}, {
2040                     { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x13 }, { 0x19, 0x2a },
2041                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x84 }, { 0x1e, 0xa0 },
2042                     { 0x52, 0x0d }, { 0x53, 0x10 }, { 0x54, 0x01 }, { 0x55, 0x04 },
2043                     { 0x56, 0x07 }, { 0x57, 0x0a }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2044                     { 0x70, 0x01 }, { 0x71, 0x02 }, { 0x72, 0x03 }, { 0x73, 0x04 },
2045                     { 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f },
2046                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2047                     { 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb },
2048                     { 0x80, 0x20 },
2049                 }, {}
2050             },
2051             {   { 1600 }, 4800, Ratio{1, 2}, 14400, 10, 8, { ScanMethod::FLATBED },
2052                 StaggerConfig{}, {
2053                     { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x11 }, { 0x19, 0x2a },
2054                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x84 }, { 0x1e, 0xa1 },
2055                     { 0x52, 0x0b }, { 0x53, 0x0e }, { 0x54, 0x11 }, { 0x55, 0x02 },
2056                     { 0x56, 0x05 }, { 0x57, 0x08 }, { 0x58, 0x63 }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2057                     { 0x70, 0x00 }, { 0x71, 0x01 }, { 0x72, 0x02 }, { 0x73, 0x03 },
2058                     { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff },
2059                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2060                     { 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 },
2061                     { 0x80, 0x28 },
2062                 }, {
2063                     { 0x03, 0x1f },
2064                 }
2065             },
2066             {   { 3200 }, 4800, Ratio{1, 1}, 28800, 20, -2, { ScanMethod::FLATBED },
2067                 StaggerConfig{0, 6}, {
2068                     { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a },
2069                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x84 }, { 0x1e, 0xa1 },
2070                     { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b },
2071                     { 0x56, 0x0e }, { 0x57, 0x11 }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2072                     { 0x70, 0x09 }, { 0x71, 0x0a }, { 0x72, 0x0b }, { 0x73, 0x0c },
2073                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 },
2074                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2075                     { 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 },
2076                     { 0x80, 0x2b },
2077                 }, {
2078                     { 0x03, 0x1f },
2079                 },
2080             },
2081             {   { 400 }, 2400, Ratio{1, 4}, 14400, 2, 0, { ScanMethod::TRANSPARENCY,
2082                                                            ScanMethod::TRANSPARENCY_INFRARED },
2083                 StaggerConfig{}, {
2084                     { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x13 }, { 0x19, 0x2a },
2085                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x84 }, { 0x1e, 0xa0 },
2086                     { 0x52, 0x0d }, { 0x53, 0x10 }, { 0x54, 0x01 }, { 0x55, 0x04 },
2087                     { 0x56, 0x07 }, { 0x57, 0x0a }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2088                     { 0x70, 0x01 }, { 0x71, 0x02 }, { 0x72, 0x03 }, { 0x73, 0x04 },
2089                     { 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f },
2090                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2091                     { 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb },
2092                     { 0x80, 0x20 },
2093                 }, {}
2094             },
2095             {   { 800 }, 4800, Ratio{1, 4}, 14400, 5, 13, { ScanMethod::TRANSPARENCY,
2096                                                             ScanMethod::TRANSPARENCY_INFRARED },
2097                 StaggerConfig{}, {
2098                     { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x13 }, { 0x19, 0x2a },
2099                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x84 }, { 0x1e, 0xa0 },
2100                     { 0x52, 0x0d }, { 0x53, 0x10 }, { 0x54, 0x01 }, { 0x55, 0x04 },
2101                     { 0x56, 0x07 }, { 0x57, 0x0a }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2102                     { 0x70, 0x00 }, { 0x71, 0x01 }, { 0x72, 0x02 }, { 0x73, 0x03 },
2103                     { 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f },
2104                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2105                     { 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb },
2106                     { 0x80, 0x20 },
2107                 }, {}
2108             },
2109             {   { 1600 }, 4800, Ratio{1, 2}, 28800, 10, 8, { ScanMethod::TRANSPARENCY,
2110                                                              ScanMethod::TRANSPARENCY_INFRARED },
2111                 StaggerConfig{}, {
2112                     { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x11 }, { 0x19, 0x2a },
2113                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x84 }, { 0x1e, 0xa0 },
2114                     { 0x52, 0x0b }, { 0x53, 0x0e }, { 0x54, 0x11 }, { 0x55, 0x02 },
2115                     { 0x56, 0x05 }, { 0x57, 0x08 }, { 0x58, 0x63 }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2116                     { 0x70, 0x00 }, { 0x71, 0x01 }, { 0x72, 0x02 }, { 0x73, 0x03 },
2117                     { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff },
2118                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2119                     { 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 },
2120                     { 0x80, 0x29 },
2121                 }, {
2122                     { 0x03, 0x1f },
2123                 },
2124             },
2125             {   { 3200 }, 4800, Ratio{1, 1}, 28800, 20, 10, { ScanMethod::TRANSPARENCY,
2126                                                               ScanMethod::TRANSPARENCY_INFRARED },
2127                 StaggerConfig{0, 6}, {
2128                     { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a },
2129                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x84 }, { 0x1e, 0xa0 },
2130                     { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b },
2131                     { 0x56, 0x0e }, { 0x57, 0x11 }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2132                     { 0x70, 0x09 }, { 0x71, 0x0a }, { 0x72, 0x0b }, { 0x73, 0x0c },
2133                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 },
2134                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2135                     { 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 },
2136                     { 0x80, 0x2b },
2137                 }, {
2138                     { 0x03, 0x1f },
2139                 },
2140             },
2141         };
2142 
2143         for (const CustomSensorSettings& setting : custom_settings)
2144         {
2145             for (auto method : setting.methods)
2146                 {for (auto resolution : setting.resolutions.values()) {
2147                     sensor.resolutions = { resolution };
2148                     sensor.shading_resolution = resolution;
2149                     sensor.register_dpiset = setting.register_dpiset;
2150                     sensor.pixel_count_ratio = setting.pixel_count_ratio;
2151                     sensor.exposure_lperiod = setting.exposure_lperiod;
2152                     sensor.output_pixel_offset = setting.output_pixel_offset;
2153                     sensor.shading_pixel_offset = setting.shading_pixel_offset;
2154                     sensor.method = method;
2155                     sensor.stagger_y = setting.stagger_y;
2156                     sensor.custom_regs = setting.extra_custom_regs;
2157                     sensor.custom_fe_regs = setting.custom_fe_regs;
2158                     s_sensors->push_back(sensor);
2159                 }
2160             }
2161         }
2162     }
2163 
2164 
2165     sensor = Genesys_Sensor();
2166     sensor.sensor_id = SensorId::CCD_CANON_8600F; // gl843
2167     sensor.full_resolution = 4800;
2168     sensor.register_dpihw = 4800;
2169     sensor.black_pixels = 31;
2170     sensor.dummy_pixel = 20;
2171     sensor.fau_gain_white_ref = 160;
2172     sensor.gain_white_ref = 160;
2173     sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 };
2174     sensor.custom_regs = {};
2175     sensor.gamma = { 1.0f, 1.0f, 1.0f };
2176 
2177     {
2178         struct CustomSensorSettings {
2179             ValueFilterAny<unsigned> resolutions;
2180             unsigned optical_resolution;
2181             unsigned register_dpiset;
2182             int exposure_lperiod;
2183             int output_pixel_offset;
2184             std::vector<ScanMethod> methods;
2185             StaggerConfig stagger_y;
2186             GenesysRegisterSettingSet extra_custom_regs;
2187             GenesysRegisterSettingSet custom_fe_regs;
2188         };
2189 
2190         CustomSensorSettings custom_settings[] = {
2191             {   { 300 }, 1200, 1200, 24000, 1, { ScanMethod::FLATBED }, StaggerConfig{}, {
2192                     { 0x0c, 0x00 },
2193                     { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a },
2194                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b },
2195                     { 0x52, 0x0c }, { 0x53, 0x0f }, { 0x54, 0x00 }, { 0x55, 0x03 },
2196                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 },
2197                     { 0x56, 0x06 }, { 0x57, 0x09 }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2198                     { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 },
2199                     { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 },
2200                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
2201                     { 0x9e, 0x2d },
2202                     { 0xaa, 0x00 },
2203                 },
2204                 {},
2205             },
2206             {   { 600 }, 1200, 2400, 24000, 2, { ScanMethod::FLATBED }, StaggerConfig{}, {
2207                     { 0x0c, 0x00 },
2208                     { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a },
2209                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b },
2210                     { 0x52, 0x0c }, { 0x53, 0x0f }, { 0x54, 0x00 }, { 0x55, 0x03 },
2211                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 },
2212                     { 0x56, 0x06 }, { 0x57, 0x09 }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2213                     { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 },
2214                     { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 },
2215                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
2216                     { 0x9e, 0x2d },
2217                     { 0xaa, 0x00 },
2218                 },
2219                 {},
2220             },
2221             {   { 1200 }, 1200, 4800, 24000, 5, { ScanMethod::FLATBED }, StaggerConfig{}, {
2222                     { 0x0c, 0x00 },
2223                     { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a },
2224                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b },
2225                     { 0x52, 0x0c }, { 0x53, 0x0f }, { 0x54, 0x00 }, { 0x55, 0x03 },
2226                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 },
2227                     { 0x56, 0x06 }, { 0x57, 0x09 }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2228                     { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 },
2229                     { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 },
2230                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
2231                     { 0x9e, 0x2d },
2232                     { 0xaa, 0x00 },
2233                 },
2234                 {},
2235             },
2236             {   { 300 }, 1200, 1200, 45000, 6, { ScanMethod::TRANSPARENCY,
2237                                                  ScanMethod::TRANSPARENCY_INFRARED },
2238                 StaggerConfig{}, {
2239                     { 0x0c, 0x00 },
2240                     { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a },
2241                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b },
2242                     { 0x52, 0x0c }, { 0x53, 0x0f }, { 0x54, 0x00 }, { 0x55, 0x03 },
2243                     { 0x56, 0x06 }, { 0x57, 0x09 }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2244                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 },
2245                     { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 },
2246                     { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 },
2247                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
2248                     { 0x9e, 0x2d },
2249                     { 0xaa, 0x00 },
2250                 },
2251                 {},
2252             },
2253             {   { 600 }, 1200, 2400, 45000, 11, { ScanMethod::TRANSPARENCY,
2254                                                   ScanMethod::TRANSPARENCY_INFRARED },
2255                 StaggerConfig{}, {
2256                     { 0x0c, 0x00 },
2257                     { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a },
2258                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b },
2259                     { 0x52, 0x0c }, { 0x53, 0x0f }, { 0x54, 0x00 }, { 0x55, 0x03 },
2260                     { 0x56, 0x06 }, { 0x57, 0x09 }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2261                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 },
2262                     { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 },
2263                     { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 },
2264                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
2265                     { 0x9e, 0x2d },
2266                     { 0xaa, 0x00 },
2267                 },
2268                 {},
2269             },
2270             {   { 1200 }, 1200, 4800, 45000, 23, { ScanMethod::TRANSPARENCY,
2271                                                    ScanMethod::TRANSPARENCY_INFRARED },
2272                 StaggerConfig{}, {
2273                     { 0x0c, 0x00 },
2274                     { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a },
2275                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b },
2276                     { 0x52, 0x0c }, { 0x53, 0x0f }, { 0x54, 0x00 }, { 0x55, 0x03 },
2277                     { 0x56, 0x06 }, { 0x57, 0x09 }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2278                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 },
2279                     { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 },
2280                     { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 },
2281                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
2282                     { 0x9e, 0x2d },
2283                     { 0xaa, 0x00 },
2284                 },
2285                 {},
2286             },
2287             {   { 2400 }, 2400, 4800, 45000, 10, { ScanMethod::TRANSPARENCY,
2288                                                    ScanMethod::TRANSPARENCY_INFRARED },
2289                 StaggerConfig{}, {
2290                     { 0x0c, 0x00 },
2291                     { 0x16, 0x13 }, { 0x17, 0x15 }, { 0x18, 0x10 }, { 0x19, 0x2a },
2292                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x01 }, { 0x1d, 0x75 },
2293                     { 0x52, 0x0c }, { 0x53, 0x0f }, { 0x54, 0x00 }, { 0x55, 0x03 },
2294                     { 0x56, 0x06 }, { 0x57, 0x09 }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2295                     { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 },
2296                     { 0x74, 0x03 }, { 0x75, 0xfe }, { 0x76, 0x00 },
2297                     { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 },
2298                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
2299                     { 0x9e, 0x2d },
2300                     { 0xaa, 0x00 },
2301                 },
2302                 {},
2303             },
2304             {   { 4800 }, 4800, 4800, 45000, -1982, { ScanMethod::TRANSPARENCY,
2305                                                       ScanMethod::TRANSPARENCY_INFRARED },
2306                 StaggerConfig{8, 0}, {
2307                     { 0x0c, 0x00 },
2308                     { 0x16, 0x13 }, { 0x17, 0x15 }, { 0x18, 0x10 }, { 0x19, 0x2a },
2309                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x61 }, { 0x1d, 0x75 },
2310                     { 0x52, 0x03 }, { 0x53, 0x06 }, { 0x54, 0x09 }, { 0x55, 0x0c },
2311                     { 0x56, 0x0f }, { 0x57, 0x00 }, { 0x58, 0x23 }, { 0x59, 0x00 }, { 0x5a, 0x40 },
2312                     { 0x70, 0x0a }, { 0x71, 0x0c }, { 0x72, 0x0c }, { 0x73, 0x0e },
2313                     { 0x74, 0x03 }, { 0x75, 0xff }, { 0x76, 0xff },
2314                     { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff },
2315                     { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 },
2316                     { 0x9e, 0x2d },
2317                     { 0xaa, 0x00 },
2318                 },
2319                 {   { 0x03, 0x1f },
2320                 },
2321             },
2322         };
2323 
2324         for (const CustomSensorSettings& setting : custom_settings) {
2325             for (auto method : setting.methods) {
2326                 for (auto resolution : setting.resolutions.values()) {
2327                     sensor.resolutions = { resolution };
2328                     sensor.optical_resolution = setting.optical_resolution;
2329                     sensor.register_dpiset = setting.register_dpiset;
2330                     sensor.shading_resolution = resolution;
2331                     sensor.output_pixel_offset = setting.output_pixel_offset;
2332                     sensor.method = method;
2333                     sensor.exposure_lperiod = setting.exposure_lperiod;
2334                     sensor.stagger_y = setting.stagger_y;
2335                     sensor.custom_regs = setting.extra_custom_regs;
2336                     sensor.custom_fe_regs = setting.custom_fe_regs;
2337                     s_sensors->push_back(sensor);
2338                 }
2339             }
2340         }
2341     }
2342 
2343 
2344     sensor = Genesys_Sensor();
2345     sensor.sensor_id = SensorId::CCD_HP_N6310; // gl847
2346     sensor.full_resolution = 2400;
2347     sensor.black_pixels = 96;
2348     sensor.dummy_pixel = 26;
2349     sensor.pixel_count_ratio = Ratio{1, 4};
2350     sensor.fau_gain_white_ref = 210;
2351     sensor.gain_white_ref = 230;
2352     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
2353     sensor.custom_regs = {
2354         { 0x16, 0x33 },
2355         { 0x17, 0x0c },
2356         { 0x18, 0x02 },
2357         { 0x19, 0x2a },
2358         { 0x1a, 0x30 },
2359         { 0x1b, 0x00 },
2360         { 0x1c, 0x00 },
2361         { 0x1d, 0x08 },
2362         { 0x52, 0x0b },
2363         { 0x53, 0x0e },
2364         { 0x54, 0x11 },
2365         { 0x55, 0x02 },
2366         { 0x56, 0x05 },
2367         { 0x57, 0x08 },
2368         { 0x58, 0x63 },
2369         { 0x59, 0x00 },
2370         { 0x5a, 0x40 },
2371     };
2372     sensor.gamma = { 1.0f, 1.0f, 1.0f };
2373     {
2374         struct CustomSensorSettings
2375         {
2376             ValueFilterAny<unsigned> resolutions;
2377             unsigned register_dpihw;
2378             unsigned shading_factor;
2379             int output_pixel_offset;
2380         };
2381 
2382         CustomSensorSettings custom_settings[] = {
2383             { { 75 }, 600, 8, 4 },
2384             { { 100 }, 600, 6, 5 },
2385             { { 150 }, 600, 4, 8 },
2386             { { 200 }, 600, 3, 10 },
2387             { { 300 }, 600, 2, 16 },
2388             { { 600 }, 600, 1, 32 },
2389             { { 1200 }, 1200, 1, 64 },
2390             { { 2400 }, 2400, 1, 128 },
2391         };
2392 
2393         auto base_custom_regs = sensor.custom_regs;
2394         for (const CustomSensorSettings& setting : custom_settings) {
2395             sensor.resolutions = setting.resolutions;
2396             sensor.register_dpiset = setting.resolutions.values()[0];
2397             sensor.register_dpihw = setting.register_dpihw;
2398             sensor.shading_resolution = setting.register_dpihw;
2399             sensor.shading_factor = setting.shading_factor;
2400             sensor.output_pixel_offset = setting.output_pixel_offset;
2401             s_sensors->push_back(sensor);
2402         }
2403     }
2404 
2405     sensor = Genesys_Sensor();
2406     sensor.sensor_id = SensorId::CIS_CANON_LIDE_110; // gl124
2407     sensor.full_resolution = 2400;
2408     sensor.black_pixels = 87;
2409     sensor.dummy_pixel = 16;
2410     sensor.fau_gain_white_ref = 210;
2411     sensor.gain_white_ref = 200;
2412     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
2413     sensor.gamma = { 2.2f, 2.2f, 2.2f };
2414 
2415     {
2416         struct CustomSensorSettings {
2417             ValueFilterAny<unsigned> resolutions;
2418             unsigned optical_resolution;
2419             unsigned register_dpihw;
2420             unsigned register_dpiset;
2421             unsigned shading_resolution;
2422             int exposure_lperiod;
2423             SensorExposure exposure;
2424             Ratio pixel_count_ratio;
2425             unsigned shading_factor;
2426             std::vector<unsigned> segment_order;
2427             GenesysRegisterSettingSet custom_regs;
2428         };
2429 
2430         CustomSensorSettings custom_settings[] = {
2431             {   { 75 }, 1200, 600, 150, 300, 4608, { 462, 609, 453 }, Ratio{1, 4}, 4,
2432                 std::vector<unsigned>{}, {
2433                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2434                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c },
2435                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2436                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2437                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2438                     { 0x61, 0x20 },
2439                     { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a },
2440                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2441                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2442                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2443                     { 0x88, 0x00 }, { 0x89, 0x65 },
2444                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
2445                     { 0x96, 0x00 }, { 0x97, 0x9a },
2446                     { 0x98, 0x21 },
2447                 }
2448             },
2449             {   { 100 }, 1200, 600, 200, 300, 4608, { 462, 609, 453 }, Ratio{1, 4}, 3,
2450                 std::vector<unsigned>{}, {
2451                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2452                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c },
2453                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2454                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2455                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2456                     { 0x61, 0x20 },
2457                     { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a },
2458                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2459                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2460                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2461                     { 0x88, 0x00 }, { 0x89, 0x65 },
2462                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
2463                     { 0x96, 0x00 }, { 0x97, 0x9a },
2464                     { 0x98, 0x21 },
2465                 }
2466             },
2467             {   { 150 }, 1200, 600, 300, 300, 4608, { 462, 609, 453 }, Ratio{1, 4}, 2,
2468                 std::vector<unsigned>{}, {
2469                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2470                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c },
2471                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2472                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2473                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2474                     { 0x61, 0x20 },
2475                     { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a },
2476                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2477                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2478                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2479                     { 0x88, 0x00 }, { 0x89, 0x65 },
2480                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
2481                     { 0x96, 0x00 }, { 0x97, 0x9a },
2482                     { 0x98, 0x21 },
2483                 }
2484             },
2485             {   { 300 }, 1200, 600, 600, 300, 4608, { 462, 609, 453 }, Ratio{1, 4}, 1,
2486                 std::vector<unsigned>{}, {
2487                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2488                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x0c },
2489                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2490                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2491                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2492                     { 0x61, 0x20 },
2493                     { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a },
2494                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2495                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2496                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2497                     { 0x88, 0x00 }, { 0x89, 0x65 },
2498                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
2499                     { 0x96, 0x00 }, { 0x97, 0x9a },
2500                     { 0x98, 0x21 },
2501                 }
2502             },
2503             {   { 600 }, 2400, 600, 600, 600, 5360, { 823, 1117, 805 }, Ratio{1, 4}, 1,
2504                 std::vector<unsigned>{}, {
2505                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2506                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x0a },
2507                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2508                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2509                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2510                     { 0x61, 0x20 },
2511                     { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a },
2512                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2513                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2514                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2515                     { 0x88, 0x00 }, { 0x89, 0x65 },
2516                     { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 },
2517                     { 0x96, 0x00 }, { 0x97, 0xa3 },
2518                     { 0x98, 0x21 },
2519                 },
2520             },
2521             {   { 1200 }, 2400, 1200, 1200, 1200, 10528, { 6071, 6670, 6042 }, Ratio{1, 4}, 1,
2522                 { 0, 1 }, {
2523                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2524                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 },{ 0x20, 0x08 },
2525                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2526                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2527                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2528                     { 0x61, 0x20 },
2529                     { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a },
2530                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2531                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2532                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2533                     { 0x88, 0x12 }, { 0x89, 0x47 },
2534                     { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 },
2535                     { 0x96, 0x00 }, { 0x97, 0xa3 },
2536                     { 0x98, 0x22 },
2537                 }
2538             },
2539             {   { 2400 }, 2400, 2400, 2400, 2400, 20864, { 7451, 8661, 7405 }, Ratio{1, 4}, 1,
2540                 { 0, 2, 1, 3 }, {
2541                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2542                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x06 },
2543                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2544                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2545                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2546                     { 0x61, 0x20 },
2547                     { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a },
2548                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2549                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2550                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2551                     { 0x88, 0x12 }, { 0x89, 0x47 },
2552                     { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 },
2553                     { 0x96, 0x00 }, { 0x97, 0xa3 },
2554                     { 0x98, 0x24 },
2555                 }
2556             }
2557         };
2558 
2559         for (const auto& setting : custom_settings) {
2560             sensor.resolutions = setting.resolutions;
2561             sensor.optical_resolution = setting.optical_resolution;
2562             sensor.register_dpihw = setting.register_dpihw;
2563             sensor.register_dpiset = setting.register_dpiset;
2564             sensor.shading_resolution = setting.shading_resolution;
2565             sensor.exposure_lperiod = setting.exposure_lperiod;
2566             sensor.exposure = setting.exposure;
2567             sensor.pixel_count_ratio = setting.pixel_count_ratio;
2568             sensor.shading_factor = setting.shading_factor;
2569             sensor.segment_order = setting.segment_order;
2570             sensor.custom_regs = setting.custom_regs;
2571 
2572             sensor.channels = { 1 };
2573             sensor.custom_regs.set_value(0x0c, 0x10);
2574             s_sensors->push_back(sensor);
2575 
2576             sensor.channels = { 3 };
2577             sensor.custom_regs.set_value(0x0c, 0x12);
2578             s_sensors->push_back(sensor);
2579         }
2580     }
2581 
2582     sensor = Genesys_Sensor();
2583     sensor.sensor_id = SensorId::CIS_CANON_LIDE_120; // gl124
2584     sensor.full_resolution = 2400;
2585     sensor.black_pixels = 87;
2586     sensor.dummy_pixel = 16;
2587     sensor.fau_gain_white_ref = 210;
2588     sensor.gain_white_ref = 200;
2589     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
2590     sensor.gamma = { 2.2f, 2.2f, 2.2f };
2591 
2592     {
2593         struct CustomSensorSettings {
2594             ValueFilterAny<unsigned> resolutions;
2595             unsigned optical_resolution;
2596             unsigned register_dpihw;
2597             unsigned register_dpiset;
2598             unsigned shading_resolution;
2599             int exposure_lperiod;
2600             SensorExposure exposure;
2601             Ratio pixel_count_ratio;
2602             unsigned shading_factor;
2603             std::vector<unsigned> segment_order;
2604             GenesysRegisterSettingSet custom_regs;
2605         };
2606 
2607         CustomSensorSettings custom_settings[] = {
2608             {   { 75 }, 1200, 600, 150, 300, 4608, { 1244, 1294, 1144 }, Ratio{1, 4}, 4,
2609                 std::vector<unsigned>{}, {
2610                     { 0x16, 0x15 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2611                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x02 },
2612                     { 0x52, 0x04 }, { 0x53, 0x06 }, { 0x54, 0x00 }, { 0x55, 0x02 },
2613                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2614                     { 0x5a, 0x3a }, { 0x5b, 0x00 }, { 0x5c, 0x00 },
2615                     { 0x61, 0x20 },
2616                     { 0x70, 0x00 }, { 0x71, 0x1f }, { 0x72, 0x08 }, { 0x73, 0x0a },
2617                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
2618                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2619                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2620                     { 0x88, 0x00 }, { 0x89, 0x5e },
2621                     { 0x93, 0x00 }, { 0x94, 0x09 }, { 0x95, 0xf8 },
2622                     { 0x96, 0x00 }, { 0x97, 0x70 },
2623                     { 0x98, 0x21 },
2624                 },
2625             },
2626             {   { 100 }, 1200, 600, 200, 300, 4608, { 1244, 1294, 1144 }, Ratio{1, 4}, 3,
2627                 std::vector<unsigned>{}, {
2628                     { 0x16, 0x15 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2629                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x02 },
2630                     { 0x52, 0x04 }, { 0x53, 0x06 }, { 0x54, 0x00 }, { 0x55, 0x02 },
2631                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2632                     { 0x5a, 0x3a }, { 0x5b, 0x00 }, { 0x5c, 0x00 },
2633                     { 0x61, 0x20 },
2634                     { 0x70, 0x00 }, { 0x71, 0x1f }, { 0x72, 0x08 }, { 0x73, 0x0a },
2635                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
2636                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2637                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2638                     { 0x88, 0x00 }, { 0x89, 0x5e },
2639                     { 0x93, 0x00 }, { 0x94, 0x09 }, { 0x95, 0xf8 },
2640                     { 0x96, 0x00 }, { 0x97, 0x70 },
2641                     { 0x98, 0x21 },
2642                 },
2643             },
2644             {   { 150 }, 1200, 600, 300, 300, 4608, { 1244, 1294, 1144 }, Ratio{1, 4}, 2,
2645                 std::vector<unsigned>{}, {
2646                     { 0x16, 0x15 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2647                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x02 },
2648                     { 0x52, 0x04 }, { 0x53, 0x06 }, { 0x54, 0x00 }, { 0x55, 0x02 },
2649                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2650                     { 0x5a, 0x3a }, { 0x5b, 0x00 }, { 0x5c, 0x00 },
2651                     { 0x61, 0x20 },
2652                     { 0x70, 0x00 }, { 0x71, 0x1f }, { 0x72, 0x08 }, { 0x73, 0x0a },
2653                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
2654                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2655                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2656                     { 0x88, 0x00 }, { 0x89, 0x5e },
2657                     { 0x93, 0x00 }, { 0x94, 0x09 }, { 0x95, 0xf8 },
2658                     { 0x96, 0x00 }, { 0x97, 0x70 },
2659                     { 0x98, 0x21 },
2660                 },
2661             },
2662             {   { 300 }, 1200, 600, 600, 300, 4608, { 1244, 1294, 1144 }, Ratio{1, 4}, 1,
2663                 std::vector<unsigned>{}, {
2664                     { 0x16, 0x15 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2665                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x02 },
2666                     { 0x52, 0x04 }, { 0x53, 0x06 }, { 0x54, 0x00 }, { 0x55, 0x02 },
2667                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2668                     { 0x5a, 0x3a }, { 0x5b, 0x00 }, { 0x5c, 0x00 },
2669                     { 0x61, 0x20 },
2670                     { 0x70, 0x00 }, { 0x71, 0x1f }, { 0x72, 0x08 }, { 0x73, 0x0a },
2671                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
2672                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2673                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2674                     { 0x88, 0x00 }, { 0x89, 0x5e },
2675                     { 0x93, 0x00 }, { 0x94, 0x09 }, { 0x95, 0xf8 },
2676                     { 0x96, 0x00 }, { 0x97, 0x70 },
2677                     { 0x98, 0x21 },
2678                 },
2679             },
2680             {   { 600 }, 2400, 600, 600, 600, 5360, { 2394, 2444, 2144 }, Ratio{1, 4}, 1,
2681                 std::vector<unsigned>{}, {
2682                     { 0x16, 0x11 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2683                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x02 },
2684                     { 0x52, 0x04 }, { 0x53, 0x06 }, { 0x54, 0x00 }, { 0x55, 0x02 },
2685                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2686                     { 0x5a, 0x3a }, { 0x5b, 0x00 }, { 0x5c, 0x00 },
2687                     { 0x61, 0x20 },
2688                     { 0x70, 0x1f }, { 0x71, 0x1f }, { 0x72, 0x08 }, { 0x73, 0x0a },
2689                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
2690                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2691                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2692                     { 0x88, 0x00 }, { 0x89, 0x5e },
2693                     { 0x93, 0x00 }, { 0x94, 0x13 }, { 0x95, 0xf0 },
2694                     { 0x96, 0x00 }, { 0x97, 0x8b },
2695                     { 0x98, 0x21 },
2696                 },
2697             },
2698             {   { 1200 }, 2400, 1200, 1200, 1200, 10528, { 4694, 4644, 4094 }, Ratio{1, 2}, 1,
2699                 std::vector<unsigned>{}, {
2700                     { 0x16, 0x15 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2701                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x02 },
2702                     { 0x52, 0x04 }, { 0x53, 0x06 }, { 0x54, 0x00 }, { 0x55, 0x02 },
2703                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2704                     { 0x5a, 0x3a }, { 0x5b, 0x00 }, { 0x5c, 0x00 },
2705                     { 0x61, 0x20 },
2706                     { 0x70, 0x1f }, { 0x71, 0x1f }, { 0x72, 0x08 }, { 0x73, 0x0a },
2707                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
2708                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2709                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2710                     { 0x88, 0x00 }, { 0x89, 0x5e },
2711                     { 0x93, 0x00 }, { 0x94, 0x27 }, { 0x95, 0xe0 },
2712                     { 0x96, 0x00 }, { 0x97, 0xc0 },
2713                     { 0x98, 0x21 },
2714                 },
2715             },
2716             {   { 2400 }, 2400, 2400, 2400, 2400, 20864, { 8944, 8144, 7994 }, Ratio{1, 1}, 1,
2717                 std::vector<unsigned>{}, {
2718                     { 0x16, 0x11 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2719                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x02 },
2720                     { 0x52, 0x04 }, { 0x53, 0x06 }, { 0x54, 0x00 }, { 0x55, 0x02 },
2721                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2722                     { 0x5a, 0x3a }, { 0x5b, 0x00 }, { 0x5c, 0x00 },
2723                     { 0x61, 0x20 },
2724                     { 0x70, 0x00 }, { 0x71, 0x1f }, { 0x72, 0x08 }, { 0x73, 0x0a },
2725                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
2726                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
2727                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2728                     { 0x88, 0x00 }, { 0x89, 0x5e },
2729                     { 0x93, 0x00 }, { 0x94, 0x4f }, { 0x95, 0xc0 },
2730                     { 0x96, 0x01 }, { 0x97, 0x2a },
2731                     { 0x98, 0x21 },
2732                 }
2733             },
2734         };
2735 
2736         for (const auto& setting : custom_settings) {
2737             sensor.resolutions = setting.resolutions;
2738             sensor.optical_resolution = setting.optical_resolution;
2739             sensor.register_dpihw = setting.register_dpihw;
2740             sensor.register_dpiset = setting.register_dpiset;
2741             sensor.shading_resolution = setting.shading_resolution;
2742             sensor.exposure_lperiod = setting.exposure_lperiod;
2743             sensor.exposure = setting.exposure;
2744             sensor.pixel_count_ratio = setting.pixel_count_ratio;
2745             sensor.shading_factor = setting.shading_factor;
2746             sensor.segment_order = setting.segment_order;
2747             sensor.custom_regs = setting.custom_regs;
2748 
2749             sensor.channels = { 1 };
2750             sensor.custom_regs.set_value(0x0c, 0x10);
2751             s_sensors->push_back(sensor);
2752 
2753             sensor.channels = { 3 };
2754             sensor.custom_regs.set_value(0x0c, 0x12);
2755             s_sensors->push_back(sensor);
2756         }
2757     }
2758 
2759     sensor = Genesys_Sensor();
2760     sensor.sensor_id = SensorId::CIS_CANON_LIDE_210; // gl124
2761     sensor.full_resolution = 4800;
2762     sensor.black_pixels = 87;
2763     sensor.dummy_pixel = 16;
2764     sensor.fau_gain_white_ref = 210;
2765     sensor.gain_white_ref = 200;
2766     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
2767     sensor.gamma = { 2.2f, 2.2f, 2.2f };
2768 
2769     {
2770         struct CustomSensorSettings {
2771             ValueFilterAny<unsigned> resolutions;
2772             unsigned optical_resolution;
2773             unsigned register_dpihw;
2774             unsigned register_dpiset;
2775             unsigned shading_resolution;
2776             int exposure_lperiod;
2777             SensorExposure exposure;
2778             Ratio pixel_count_ratio;
2779             unsigned shading_factor;
2780             std::vector<unsigned> segment_order;
2781             GenesysRegisterSettingSet custom_regs;
2782         };
2783 
2784         CustomSensorSettings custom_settings[] = {
2785             {   { 75 }, 2400, 600, 150, 300, 2768, { 388, 574, 393 }, Ratio{1, 8}, 4,
2786                 std::vector<unsigned>{}, {
2787                     // { 0x16, 0x00 }, // FIXME: check if default value is different
2788                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2789                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c },
2790                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2791                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2792                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2793                     { 0x61, 0x20 },
2794                     // { 0x70, 0x00 }, // FIXME: check if default value is different
2795                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2796                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2797                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2798                     { 0x88, 0x00 }, { 0x89, 0x65 },
2799                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
2800                     { 0x96, 0x00 }, { 0x97, 0x9a },
2801                     { 0x98, 0x21 },
2802                 }
2803             },
2804             {   { 100 }, 2400, 600, 200, 300, 2768, { 388, 574, 393 }, Ratio{1, 8}, 3,
2805                 std::vector<unsigned>{}, {
2806                     // { 0x16, 0x00 }, // FIXME: check if default value is different
2807                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2808                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c },
2809                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2810                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2811                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2812                     { 0x61, 0x20 },
2813                     // { 0x70, 0x00 }, // FIXME: check if default value is different
2814                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2815                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2816                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2817                     { 0x88, 0x00 }, { 0x89, 0x65 },
2818                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
2819                     { 0x96, 0x00 }, { 0x97, 0x9a },
2820                     { 0x98, 0x21 },
2821                 }
2822             },
2823             {   { 150 }, 2400, 600, 300, 300, 2768, { 388, 574, 393 }, Ratio{1, 8}, 2,
2824                 std::vector<unsigned>{}, {
2825                     // { 0x16, 0x00 }, // FIXME: check if default value is different
2826                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2827                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c },
2828                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2829                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2830                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2831                     { 0x61, 0x20 },
2832                     // { 0x70, 0x00 }, // FIXME: check if default value is different
2833                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2834                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2835                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2836                     { 0x88, 0x00 }, { 0x89, 0x65 },
2837                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
2838                     { 0x96, 0x00 }, { 0x97, 0x9a },
2839                     { 0x98, 0x21 },
2840                 }
2841             },
2842             {   { 300 }, 2400, 600, 600, 300, 2768, { 388, 574, 393 }, Ratio{1, 8}, 1,
2843                 std::vector<unsigned>{}, {
2844                     // { 0x16, 0x00 }, // FIXME: check if default value is different
2845                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2846                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c },
2847                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2848                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2849                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2850                     { 0x61, 0x20 },
2851                     // { 0x70, 0x00 }, // FIXME: check if default value is different
2852                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2853                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2854                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2855                     { 0x88, 0x00 }, { 0x89, 0x65 },
2856                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
2857                     { 0x96, 0x00 }, { 0x97, 0x9a },
2858                     { 0x98, 0x21 },
2859                 }
2860             },
2861             {   { 600 }, 4800, 600, 600, 600, 5360, { 388, 574, 393 }, Ratio{1, 8}, 1,
2862                 std::vector<unsigned>{}, {
2863                     // { 0x16, 0x00 }, // FIXME: check if default value is different
2864                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2865                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0a },
2866                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2867                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2868                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2869                     { 0x61, 0x20 },
2870                     // { 0x70, 0x00 }, // FIXME: check if default value is different
2871                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2872                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2873                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2874                     { 0x88, 0x00 }, { 0x89, 0x65 },
2875                     { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 },
2876                     { 0x96, 0x00 }, { 0x97, 0xa3 },
2877                     { 0x98, 0x21 },
2878                 }
2879             },
2880             {   { 1200 }, 4800, 1200, 1200, 1200, 10528, { 388, 574, 393 }, Ratio{1, 8}, 1, {0, 1}, {
2881                     // { 0x16, 0x00 }, // FIXME: check if default value is different
2882                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2883                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x08 },
2884                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2885                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2886                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2887                     { 0x61, 0x20 },
2888                     // { 0x70, 0x00 }, // FIXME: check if default value is different
2889                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2890                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2891                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2892                     { 0x88, 0x00 }, { 0x89, 0x65 },
2893                     { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 },
2894                     { 0x96, 0x00 }, { 0x97, 0xa3 },
2895                     { 0x98, 0x22 },
2896                 },
2897             },
2898             {   { 2400 }, 4800, 2400, 2400, 2400, 20864, { 6839, 8401, 6859 }, Ratio{1, 8}, 1,
2899                 {0, 2, 1, 3}, {
2900                     // { 0x16, 0x00 }, // FIXME: check if default value is different
2901                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2902                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x06 },
2903                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2904                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2905                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2906                     { 0x61, 0x20 },
2907                     // { 0x70, 0x00 }, // FIXME: check if default value is different
2908                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2909                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2910                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2911                     { 0x88, 0x12 }, { 0x89, 0x47 },
2912                     { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 },
2913                     { 0x96, 0x00 }, { 0x97, 0xa3 },
2914                     { 0x98, 0x24 },
2915                 },
2916             },
2917             {   { 4800 }, 4800, 4800, 4800, 4800, 41536, { 9735, 14661, 11345 }, Ratio{1, 8}, 1,
2918                 { 0, 2, 4, 6, 1, 3, 5, 7 }, {
2919                     // { 0x16, 0x00 }, // FIXME: check if default value is different
2920                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2921                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x04 },
2922                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2923                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2924                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2925                     { 0x61, 0x20 },
2926                     // { 0x70, 0x00 }, // FIXME: check if default value is different
2927                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e },
2928                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2929                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
2930                     { 0x88, 0x12 }, { 0x89, 0x47 },
2931                     { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 },
2932                     { 0x96, 0x00 }, { 0x97, 0xa5 },
2933                     { 0x98, 0x28 },
2934                 },
2935             }
2936         };
2937 
2938         for (const auto& setting : custom_settings) {
2939             sensor.resolutions = setting.resolutions;
2940             sensor.optical_resolution = setting.optical_resolution;
2941             sensor.register_dpihw = setting.register_dpihw;
2942             sensor.register_dpiset = setting.register_dpiset;
2943             sensor.shading_resolution = setting.shading_resolution;
2944             sensor.exposure_lperiod = setting.exposure_lperiod;
2945             sensor.exposure = setting.exposure;
2946             sensor.pixel_count_ratio = setting.pixel_count_ratio;
2947             sensor.shading_factor = setting.shading_factor;
2948             sensor.segment_order = setting.segment_order;
2949             sensor.custom_regs = setting.custom_regs;
2950 
2951             sensor.channels = { 1 };
2952             sensor.custom_regs.set_value(0x0c, 0x10);
2953             s_sensors->push_back(sensor);
2954 
2955             sensor.channels = { 3 };
2956             sensor.custom_regs.set_value(0x0c, 0x12);
2957             s_sensors->push_back(sensor);
2958         }
2959     }
2960 
2961     sensor = Genesys_Sensor();
2962     sensor.sensor_id = SensorId::CIS_CANON_LIDE_220; // gl124
2963     sensor.full_resolution = 4800;
2964     sensor.black_pixels = 87;
2965     sensor.dummy_pixel = 16;
2966     sensor.fau_gain_white_ref = 210;
2967     sensor.gain_white_ref = 200;
2968     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
2969     sensor.gamma = { 2.2f, 2.2f, 2.2f };
2970 
2971     {
2972         struct CustomSensorSettings {
2973             ValueFilterAny<unsigned> resolutions;
2974             unsigned optical_resolution;
2975             unsigned register_dpihw;
2976             unsigned register_dpiset;
2977             unsigned shading_resolution;
2978             int exposure_lperiod;
2979             SensorExposure exposure;
2980             Ratio pixel_count_ratio;
2981             unsigned shading_factor;
2982             std::vector<unsigned> segment_order;
2983             GenesysRegisterSettingSet custom_regs;
2984         };
2985 
2986         CustomSensorSettings custom_settings[] = {
2987             {   { 75 }, 2400, 600, 150, 300, 2768, { 388, 574, 393 }, Ratio{1, 8}, 4,
2988                 std::vector<unsigned>{}, {
2989                     // { 0x16, 0x00 }, // FIXME: check if default value is different
2990                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
2991                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c },
2992                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
2993                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
2994                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
2995                     { 0x61, 0x20 },
2996                     // { 0x70, 0x00 }, // FIXME: check if default value is different
2997                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
2998                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
2999                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
3000                     { 0x88, 0x00 }, { 0x89, 0x65 },
3001                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
3002                     { 0x96, 0x00 }, { 0x97, 0x9a },
3003                     { 0x98, 0x21 },
3004                 }
3005             },
3006             {   { 100 }, 2400, 600, 200, 300, 2768, { 388, 574, 393 }, Ratio{1, 8}, 3,
3007                 std::vector<unsigned>{}, {
3008                     // { 0x16, 0x00 }, // FIXME: check if default value is different
3009                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
3010                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c },
3011                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
3012                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
3013                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
3014                     { 0x61, 0x20 },
3015                     // { 0x70, 0x00 }, // FIXME: check if default value is different
3016                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
3017                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
3018                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
3019                     { 0x88, 0x00 }, { 0x89, 0x65 },
3020                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
3021                     { 0x96, 0x00 }, { 0x97, 0x9a },
3022                     { 0x98, 0x21 },
3023                 }
3024             },
3025             {   { 150 }, 2400, 600, 300, 300, 2768, { 388, 574, 393 }, Ratio{1, 8}, 2,
3026                 std::vector<unsigned>{}, {
3027                     // { 0x16, 0x00 }, // FIXME: check if default value is different
3028                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
3029                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c },
3030                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
3031                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
3032                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
3033                     { 0x61, 0x20 },
3034                     // { 0x70, 0x00 }, // FIXME: check if default value is different
3035                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
3036                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
3037                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
3038                     { 0x88, 0x00 }, { 0x89, 0x65 },
3039                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
3040                     { 0x96, 0x00 }, { 0x97, 0x9a },
3041                     { 0x98, 0x21 },
3042                 }
3043             },
3044             {   { 300 }, 2400, 600, 600, 300, 2768, { 388, 574, 393 }, Ratio{1, 8}, 1,
3045                 std::vector<unsigned>{}, {
3046                     // { 0x16, 0x00 }, // FIXME: check if default value is different
3047                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
3048                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c },
3049                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
3050                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
3051                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
3052                     { 0x61, 0x20 },
3053                     // { 0x70, 0x00 }, // FIXME: check if default value is different
3054                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
3055                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
3056                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
3057                     { 0x88, 0x00 }, { 0x89, 0x65 },
3058                     { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 },
3059                     { 0x96, 0x00 }, { 0x97, 0x9a },
3060                     { 0x98, 0x21 },
3061                 }
3062             },
3063             {   { 600 }, 4800, 600, 600, 600, 5360, { 388, 574, 393 }, Ratio{1, 8}, 1,
3064                 std::vector<unsigned>{}, {
3065                     // { 0x16, 0x00 }, // FIXME: check if default value is different
3066                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
3067                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0a },
3068                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
3069                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
3070                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
3071                     { 0x61, 0x20 },
3072                     // { 0x70, 0x00 }, // FIXME: check if default value is different
3073                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
3074                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
3075                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
3076                     { 0x88, 0x00 }, { 0x89, 0x65 },
3077                     { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 },
3078                     { 0x96, 0x00 }, { 0x97, 0xa3 },
3079                     { 0x98, 0x21 },
3080                 }
3081             },
3082             {   { 1200 }, 4800, 1200, 1200, 1200, 10528, { 388, 574, 393 }, Ratio{1, 8}, 1,
3083                 {0, 1}, {
3084                     // { 0x16, 0x00 }, // FIXME: check if default value is different
3085                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
3086                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x08 },
3087                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
3088                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
3089                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
3090                     { 0x61, 0x20 },
3091                     // { 0x70, 0x00 }, // FIXME: check if default value is different
3092                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
3093                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
3094                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
3095                     { 0x88, 0x00 }, { 0x89, 0x65 },
3096                     { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 },
3097                     { 0x96, 0x00 }, { 0x97, 0xa3 },
3098                     { 0x98, 0x22 },
3099                 }
3100             },
3101             {   { 2400 }, 4800, 2400, 2400, 2400, 20864, { 6839, 8401, 6859 }, Ratio{1, 8}, 1,
3102                 {0, 2, 1, 3}, {
3103                     // { 0x16, 0x00 }, // FIXME: check if default value is different
3104                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
3105                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x06 },
3106                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
3107                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
3108                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
3109                     { 0x61, 0x20 },
3110                     // { 0x70, 0x00 }, // FIXME: check if default value is different
3111                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
3112                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
3113                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
3114                     { 0x88, 0x12 }, { 0x89, 0x47 },
3115                     { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 },
3116                     { 0x96, 0x00 }, { 0x97, 0xa3 },
3117                     { 0x98, 0x24 },
3118                 },
3119             },
3120             {   { 4800 }, 4800, 4800, 4800, 4800, 41536, { 9735, 14661, 11345 }, Ratio{1, 8}, 1,
3121                 { 0, 2, 4, 6, 1, 3, 5, 7 }, {
3122                     // { 0x16, 0x00 }, // FIXME: check if default value is different
3123                     { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 },
3124                     { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x04 },
3125                     { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 },
3126                     { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 },
3127                     { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 },
3128                     { 0x61, 0x20 },
3129                     // { 0x70, 0x00 }, // FIXME: check if default value is different
3130                     { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f },
3131                     { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
3132                     { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
3133                     { 0x88, 0x12 }, { 0x89, 0x47 },
3134                     { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 },
3135                     { 0x96, 0x00 }, { 0x97, 0xa5 },
3136                     { 0x98, 0x28 },
3137                 },
3138             }
3139         };
3140 
3141         for (const auto& setting : custom_settings) {
3142             sensor.resolutions = setting.resolutions;
3143             sensor.optical_resolution = setting.optical_resolution;
3144             sensor.register_dpihw = setting.register_dpihw;
3145             sensor.register_dpiset = setting.register_dpiset;
3146             sensor.shading_resolution = setting.shading_resolution;
3147             sensor.exposure_lperiod = setting.exposure_lperiod;
3148             sensor.exposure = setting.exposure;
3149             sensor.pixel_count_ratio = setting.pixel_count_ratio;
3150             sensor.shading_factor = setting.shading_factor;
3151             sensor.segment_order = setting.segment_order;
3152             sensor.custom_regs = setting.custom_regs;
3153 
3154             sensor.channels = { 1 };
3155             sensor.custom_regs.set_value(0x0c, 0x10);
3156             s_sensors->push_back(sensor);
3157 
3158             sensor.channels = { 3 };
3159             sensor.custom_regs.set_value(0x0c, 0x12);
3160             s_sensors->push_back(sensor);
3161         }
3162     }
3163 
3164     sensor = Genesys_Sensor();
3165     sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICPRO_3600; // gl841
3166     sensor.full_resolution = 1200;
3167     sensor.black_pixels = 87;
3168     sensor.dummy_pixel = 87;
3169     sensor.fau_gain_white_ref = 210;
3170     sensor.gain_white_ref = 230;
3171     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
3172     sensor.custom_regs = {
3173         { 0x16, 0x33 }, { 0x17, 0x0b }, { 0x18, 0x11 }, { 0x19, 0x2a },
3174         { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0xc4 },
3175         { 0x52, 0x07 }, { 0x53, 0x0a }, { 0x54, 0x0c }, { 0x55, 0x00 },
3176         { 0x56, 0x02 }, { 0x57, 0x06 }, { 0x58, 0x22 }, { 0x59, 0x69 }, { 0x5a, 0x40 },
3177         { 0x70, 0x00 }, { 0x71, 0x00 }, { 0x72, 0x00 }, { 0x73, 0x00 },
3178     };
3179     sensor.gamma = { 1.0f, 1.0f, 1.0f };
3180     {
3181         struct CustomSensorSettings
3182         {
3183             ValueFilterAny<unsigned> resolutions;
3184             unsigned optical_resolution;
3185             unsigned register_dpihw;
3186             unsigned register_dpiset;
3187             int output_pixel_offset;
3188         };
3189 
3190         CustomSensorSettings custom_settings[] = {
3191             { { 75 }, 600, 600, 150, 11 },
3192             { { 100 }, 600, 600, 200, 14 },
3193             { { 150 }, 600, 600, 300, 22 },
3194             { { 200 }, 600, 600, 400, 29 },
3195             { { 300 }, 600, 600, 600, 44 },
3196             { { 600 }, 600, 600, 1200, 88 },
3197             { { 1200 }, 1200, 1200, 1200, 88 },
3198         };
3199 
3200         for (const CustomSensorSettings& setting : custom_settings) {
3201             sensor.resolutions = setting.resolutions;
3202             sensor.optical_resolution = setting.optical_resolution;
3203             sensor.register_dpihw = setting.register_dpihw;
3204             sensor.register_dpiset = setting.register_dpiset;
3205             sensor.shading_resolution = setting.register_dpihw;
3206             sensor.output_pixel_offset = setting.output_pixel_offset;
3207             s_sensors->push_back(sensor);
3208         }
3209     }
3210 
3211 
3212     sensor = Genesys_Sensor();
3213     sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7200; // gl842
3214     sensor.full_resolution = 7200;
3215     sensor.register_dpihw = 1200;
3216     sensor.black_pixels = 88; // TODO
3217     sensor.dummy_pixel = 19;
3218     sensor.fau_gain_white_ref = 210;
3219     sensor.gain_white_ref = 230;
3220     sensor.exposure = { 0x2b00, 0x2b00, 0x2b00 };
3221     sensor.exposure_lperiod = 0x694e;
3222     sensor.use_host_side_calib = true;
3223     sensor.custom_regs = {
3224         { 0x16, 0x3b }, { 0x17, 0x4b }, { 0x18, 0x10 }, { 0x19, 0x00 },
3225         { 0x1a, 0x24 }, { 0x1b, 0x00 }, { 0x1c, 0x40 }, { 0x1d, 0x84 },
3226         { 0x52, 0x09 }, { 0x53, 0x0c }, { 0x54, 0x0e }, { 0x55, 0x02 },
3227         { 0x56, 0x04 }, { 0x57, 0x07 }, { 0x58, 0x22 }, { 0x59, 0x69 }, { 0x5a, 0xc0 },
3228         { 0x70, 0x08 }, { 0x71, 0x09 }, { 0x72, 0x0b }, { 0x73, 0x0c },
3229         { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 },
3230         { 0x77, 0x00 }, { 0x78, 0x7f }, { 0x79, 0xff },
3231         { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, { 0x7d, 0x00 }, { 0x7f, 0x01 }
3232     };
3233     sensor.gamma = { 1.0f, 1.0f, 1.0f };
3234     {
3235         struct CustomSensorSettings
3236         {
3237             ValueFilterAny<unsigned> resolutions;
3238             ScanMethod method;
3239             Ratio pixel_count_ratio;
3240             int output_pixel_offset;
3241             unsigned register_dpiset;
3242             StaggerConfig stagger_y;
3243         };
3244 
3245         CustomSensorSettings custom_settings[] = {
3246             { { 900 }, ScanMethod::TRANSPARENCY, Ratio{8, 8}, 2, 150, StaggerConfig{} },
3247             { { 1800 }, ScanMethod::TRANSPARENCY, Ratio{4, 4}, 10, 300, StaggerConfig{} },
3248             { { 3600 }, ScanMethod::TRANSPARENCY, Ratio{2, 2}, 10, 600, StaggerConfig{} },
3249             { { 7200 }, ScanMethod::TRANSPARENCY, Ratio{1, 1}, 20, 1200, StaggerConfig{0, 4} },
3250         };
3251 
3252         for (const CustomSensorSettings& setting : custom_settings) {
3253             sensor.resolutions = setting.resolutions;
3254             sensor.method = setting.method;
3255             sensor.shading_resolution = setting.resolutions.values().front();
3256             sensor.pixel_count_ratio = setting.pixel_count_ratio;
3257             sensor.output_pixel_offset = setting.output_pixel_offset;
3258             sensor.register_dpiset = setting.register_dpiset;
3259             sensor.stagger_y = setting.stagger_y;
3260             s_sensors->push_back(sensor);
3261         }
3262     }
3263 
3264 
3265     sensor = Genesys_Sensor();
3266     sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7200I; // gl843
3267     sensor.full_resolution = 7200;
3268     sensor.register_dpihw = 1200;
3269     sensor.black_pixels = 88; // TODO
3270     sensor.dummy_pixel = 20;
3271     sensor.fau_gain_white_ref = 210;
3272     sensor.gain_white_ref = 230;
3273     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
3274     sensor.use_host_side_calib = true;
3275     sensor.custom_regs = {
3276         { 0x08, 0x00 },
3277         { 0x09, 0x00 },
3278         { 0x0a, 0x00 },
3279         { 0x16, 0x23 },
3280         { 0x17, 0x0c },
3281         { 0x18, 0x10 },
3282         { 0x19, 0x2a },
3283         { 0x1a, 0x00 },
3284         { 0x1b, 0x00 },
3285         { 0x1c, 0x21 },
3286         { 0x1d, 0x84 },
3287         { 0x52, 0x0a },
3288         { 0x53, 0x0d },
3289         { 0x54, 0x10 },
3290         { 0x55, 0x01 },
3291         { 0x56, 0x04 },
3292         { 0x57, 0x07 },
3293         { 0x58, 0x3a },
3294         { 0x59, 0x81 },
3295         { 0x5a, 0xc0 },
3296         { 0x70, 0x0a },
3297         { 0x71, 0x0b },
3298         { 0x72, 0x0c },
3299         { 0x73, 0x0d },
3300         { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 },
3301         { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
3302         { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 },
3303     };
3304     sensor.gamma = { 1.0f, 1.0f, 1.0f };
3305     {
3306         struct CustomSensorSettings
3307         {
3308             ValueFilterAny<unsigned> resolutions;
3309             ScanMethod method;
3310             unsigned shading_resolution;
3311             Ratio pixel_count_ratio;
3312             int output_pixel_offset;
3313             unsigned exposure_lperiod;
3314             unsigned register_dpiset;
3315             StaggerConfig stagger_y;
3316             GenesysRegisterSettingSet custom_fe_regs;
3317         };
3318 
3319         CustomSensorSettings custom_settings[] = {
3320             {   { 900 }, ScanMethod::TRANSPARENCY, 900, Ratio{8, 8}, 2, 0x2538, 150,
3321                 StaggerConfig{}, {} },
3322             {   { 1800 }, ScanMethod::TRANSPARENCY, 1800, Ratio{4, 4}, 5, 0x2538, 300,
3323                 StaggerConfig{}, {} },
3324             {   { 3600 }, ScanMethod::TRANSPARENCY, 3600, Ratio{2, 2}, 10, 0x2538, 600,
3325                 StaggerConfig{}, {} },
3326             {   { 7200 }, ScanMethod::TRANSPARENCY, 7200, Ratio{1, 1}, 20, 0x19c8, 1200,
3327                 StaggerConfig{4, 0}, {
3328                     { 0x02, 0x1b },
3329                     { 0x03, 0x14 },
3330                     { 0x04, 0x20 },
3331                 }
3332             },
3333             {   { 900 }, ScanMethod::TRANSPARENCY_INFRARED, 900, Ratio{8, 8}, 2, 0x1f54, 150,
3334                 StaggerConfig{}, {} },
3335             {   { 1800 }, ScanMethod::TRANSPARENCY_INFRARED, 1800, Ratio{4, 4}, 5, 0x1f54, 300,
3336                 StaggerConfig{}, {} },
3337             {   { 3600 }, ScanMethod::TRANSPARENCY_INFRARED, 3600, Ratio{2, 2}, 10, 0x1f54, 600,
3338                 StaggerConfig{}, {}},
3339             {   { 7200 }, ScanMethod::TRANSPARENCY_INFRARED, 7200, Ratio{1, 1}, 20, 0x1f54, 1200,
3340                 StaggerConfig{4, 0}, {} },
3341         };
3342 
3343         for (const CustomSensorSettings& setting : custom_settings) {
3344             sensor.resolutions = setting.resolutions;
3345             sensor.method = setting.method;
3346             sensor.shading_resolution = setting.shading_resolution;
3347             sensor.pixel_count_ratio = setting.pixel_count_ratio;
3348             sensor.output_pixel_offset = setting.output_pixel_offset;
3349             sensor.exposure_lperiod = setting.exposure_lperiod;
3350             sensor.register_dpiset = setting.register_dpiset;
3351             sensor.stagger_y = setting.stagger_y;
3352             sensor.custom_fe_regs = setting.custom_fe_regs;
3353             s_sensors->push_back(sensor);
3354         }
3355     }
3356 
3357 
3358     sensor = Genesys_Sensor();
3359     sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7300; // gl843
3360     sensor.full_resolution = 7200;
3361     sensor.method = ScanMethod::TRANSPARENCY;
3362     sensor.register_dpihw = 1200;
3363     sensor.black_pixels = 88; // TODO
3364     sensor.dummy_pixel = 20;
3365     sensor.fau_gain_white_ref = 210;
3366     sensor.gain_white_ref = 230;
3367     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
3368     sensor.exposure_lperiod = 0x2f44;
3369     sensor.use_host_side_calib = true;
3370     sensor.custom_regs = {
3371         { 0x08, 0x00 },
3372         { 0x09, 0x00 },
3373         { 0x0a, 0x00 },
3374         { 0x16, 0x27 },
3375         { 0x17, 0x0c },
3376         { 0x18, 0x10 },
3377         { 0x19, 0x2a },
3378         { 0x1a, 0x00 },
3379         { 0x1b, 0x00 },
3380         { 0x1c, 0x20 },
3381         { 0x1d, 0x84 },
3382         { 0x52, 0x0a },
3383         { 0x53, 0x0d },
3384         { 0x54, 0x0f },
3385         { 0x55, 0x01 },
3386         { 0x56, 0x04 },
3387         { 0x57, 0x07 },
3388         { 0x58, 0x31 },
3389         { 0x59, 0x79 },
3390         { 0x5a, 0xc0 },
3391         { 0x70, 0x0c },
3392         { 0x71, 0x0d },
3393         { 0x72, 0x0e },
3394         { 0x73, 0x0f },
3395         { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 },
3396         { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
3397         { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 },
3398     };
3399     sensor.gamma = { 1.0f, 1.0f, 1.0f };
3400     {
3401         struct CustomSensorSettings
3402         {
3403             ValueFilterAny<unsigned> resolutions;
3404             unsigned shading_resolution;
3405             Ratio pixel_count_ratio;
3406             int output_pixel_offset;
3407             unsigned register_dpiset;
3408             StaggerConfig stagger_y;
3409         };
3410 
3411         CustomSensorSettings custom_settings[] = {
3412             { { 900 }, 900, Ratio{8, 8}, 2, 150, StaggerConfig{} },
3413             { { 1800 }, 1800, Ratio{4, 4}, 5, 300, StaggerConfig{} },
3414             { { 3600 }, 3600, Ratio{2, 2}, 10, 600, StaggerConfig{} },
3415             { { 7200 }, 7200, Ratio{1, 1}, 20, 1200, StaggerConfig{4, 0} },
3416         };
3417 
3418         for (const CustomSensorSettings& setting : custom_settings) {
3419             sensor.resolutions = setting.resolutions;
3420             sensor.shading_resolution = setting.shading_resolution;
3421             sensor.pixel_count_ratio = setting.pixel_count_ratio;
3422             sensor.output_pixel_offset = setting.output_pixel_offset;
3423             sensor.register_dpiset = setting.register_dpiset;
3424             sensor.stagger_y = setting.stagger_y;
3425             s_sensors->push_back(sensor);
3426         }
3427     }
3428 
3429 
3430     sensor = Genesys_Sensor();
3431     sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7400; // gl845
3432     sensor.full_resolution = 7200;
3433     sensor.method = ScanMethod::TRANSPARENCY;
3434     sensor.register_dpihw = 1200;
3435     sensor.black_pixels = 88; // TODO
3436     sensor.dummy_pixel = 20;
3437     sensor.fau_gain_white_ref = 210;
3438     sensor.gain_white_ref = 230;
3439     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
3440     sensor.exposure_lperiod = 14000;
3441     sensor.use_host_side_calib = true;
3442     sensor.custom_regs = {
3443         { 0x08, 0x00 }, { 0x09, 0x00 }, { 0x0a, 0x00 },
3444         { 0x16, 0x27 }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a },
3445         { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x84 },
3446         { 0x52, 0x09 }, { 0x53, 0x0d }, { 0x54, 0x0f }, { 0x55, 0x01 },
3447         { 0x56, 0x04 }, { 0x57, 0x07 }, { 0x58, 0x31 }, { 0x59, 0x79 }, { 0x5a, 0xc0 },
3448         { 0x70, 0x0a }, { 0x71, 0x0b }, { 0x72, 0x0c }, { 0x73, 0x0d },
3449         { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 },
3450         { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
3451         { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, { 0x7d, 0x00 },
3452         { 0x87, 0x00 },
3453     };
3454     sensor.gamma = { 1.0f, 1.0f, 1.0f };
3455     {
3456         struct CustomSensorSettings
3457         {
3458             ValueFilterAny<unsigned> resolutions;
3459             unsigned register_dpiset;
3460             int output_pixel_offset;
3461             StaggerConfig stagger_y;
3462         };
3463 
3464         CustomSensorSettings custom_settings[] = {
3465             { { 600 }, 100, 10, StaggerConfig{} },
3466             { { 1200 }, 200, 20, StaggerConfig{} },
3467             { { 2400 }, 400, 40, StaggerConfig{} },
3468             { { 3600 }, 600, 60, StaggerConfig{} },
3469             { { 7200 }, 1200, 120, StaggerConfig{4, 0} },
3470         };
3471 
3472         for (const CustomSensorSettings& setting : custom_settings) {
3473             sensor.resolutions = setting.resolutions;
3474             sensor.shading_resolution = setting.resolutions.values()[0];
3475             sensor.register_dpiset = setting.register_dpiset;
3476             sensor.output_pixel_offset = setting.output_pixel_offset;
3477             sensor.stagger_y = setting.stagger_y;
3478             s_sensors->push_back(sensor);
3479         }
3480     }
3481 
3482     sensor = Genesys_Sensor();
3483     sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7500I; // gl843
3484     sensor.full_resolution = 7200;
3485     sensor.register_dpihw = 1200;
3486     sensor.black_pixels = 88; // TODO
3487     sensor.dummy_pixel = 20;
3488     sensor.fau_gain_white_ref = 210;
3489     sensor.gain_white_ref = 230;
3490     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
3491     sensor.use_host_side_calib = true;
3492     sensor.custom_regs = {
3493         { 0x08, 0x00 },
3494         { 0x09, 0x00 },
3495         { 0x0a, 0x00 },
3496         { 0x16, 0x27 },
3497         { 0x17, 0x0c },
3498         { 0x18, 0x10 },
3499         { 0x19, 0x2a },
3500         { 0x1a, 0x00 },
3501         { 0x1b, 0x00 },
3502         { 0x1c, 0x20 },
3503         { 0x1d, 0x84 },
3504         { 0x52, 0x0a },
3505         { 0x53, 0x0d },
3506         { 0x54, 0x0f },
3507         { 0x55, 0x01 },
3508         { 0x56, 0x04 },
3509         { 0x57, 0x07 },
3510         { 0x58, 0x31 },
3511         { 0x59, 0x79 },
3512         { 0x5a, 0xc0 },
3513         { 0x70, 0x0c },
3514         { 0x71, 0x0d },
3515         { 0x72, 0x0e },
3516         { 0x73, 0x0f },
3517         { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 },
3518         { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
3519         { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 },
3520     };
3521     sensor.gamma = { 1.0f, 1.0f, 1.0f };
3522     {
3523         struct CustomSensorSettings
3524         {
3525             ValueFilterAny<unsigned> resolutions;
3526             ScanMethod method;
3527             unsigned shading_resolution;
3528             Ratio pixel_count_ratio;
3529             int output_pixel_offset;
3530             unsigned exposure_lperiod;
3531             unsigned register_dpiset;
3532             StaggerConfig stagger_y;
3533         };
3534 
3535         CustomSensorSettings custom_settings[] = {
3536             {   { 900 }, ScanMethod::TRANSPARENCY, 900, Ratio{8, 8}, 2, 0x2f44, 150,
3537                 StaggerConfig{} },
3538             {   { 1800 }, ScanMethod::TRANSPARENCY, 1800, Ratio{4, 4}, 5, 0x2f44, 300,
3539                 StaggerConfig{} },
3540             {   { 3600 }, ScanMethod::TRANSPARENCY, 3600, Ratio{2, 2}, 10, 0x2f44, 600,
3541                 StaggerConfig{} },
3542             {   { 7200 }, ScanMethod::TRANSPARENCY, 7200, Ratio{1, 1}, 20, 0x2f44, 1200,
3543                 StaggerConfig{4, 0} },
3544             {   { 900 }, ScanMethod::TRANSPARENCY_INFRARED, 900, Ratio{8, 8}, 2, 0x2af8, 150,
3545                 StaggerConfig{} },
3546             {   { 1800 }, ScanMethod::TRANSPARENCY_INFRARED, 1800, Ratio{4, 4}, 5, 0x2af8, 300,
3547                 StaggerConfig{} },
3548             {   { 3600 }, ScanMethod::TRANSPARENCY_INFRARED, 3600, Ratio{2, 2}, 10, 0x2af8, 600,
3549                 StaggerConfig{} },
3550             {   { 7200 }, ScanMethod::TRANSPARENCY_INFRARED, 7200, Ratio{1, 1}, 20, 0x2af8, 1200,
3551                 StaggerConfig{4, 0} },
3552         };
3553 
3554         for (const CustomSensorSettings& setting : custom_settings) {
3555             sensor.resolutions = setting.resolutions;
3556             sensor.method = setting.method;
3557             sensor.shading_resolution = setting.shading_resolution;
3558             sensor.pixel_count_ratio = setting.pixel_count_ratio;
3559             sensor.output_pixel_offset = setting.output_pixel_offset;
3560             sensor.exposure_lperiod = setting.exposure_lperiod;
3561             sensor.register_dpiset = setting.register_dpiset;
3562             sensor.stagger_y = setting.stagger_y;
3563             s_sensors->push_back(sensor);
3564         }
3565     }
3566 
3567 
3568     sensor = Genesys_Sensor();
3569     sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_8200I; // gl845
3570     sensor.full_resolution = 7200;
3571     sensor.method = ScanMethod::TRANSPARENCY;
3572     sensor.register_dpihw = 1200;
3573     sensor.black_pixels = 88; // TODO
3574     sensor.dummy_pixel = 20;
3575     sensor.fau_gain_white_ref = 210;
3576     sensor.gain_white_ref = 230;
3577     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
3578     sensor.exposure_lperiod = 14000;
3579     sensor.use_host_side_calib = true;
3580     sensor.custom_regs = {
3581         { 0x08, 0x00 }, { 0x09, 0x00 }, { 0x0a, 0x00 },
3582         { 0x16, 0x27 }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a },
3583         { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x84 },
3584         { 0x52, 0x09 }, { 0x53, 0x0d }, { 0x54, 0x0f }, { 0x55, 0x01 },
3585         { 0x56, 0x04 }, { 0x57, 0x07 }, { 0x58, 0x31 }, { 0x59, 0x79 }, { 0x5a, 0xc0 },
3586         { 0x70, 0x0a }, { 0x71, 0x0b }, { 0x72, 0x0c }, { 0x73, 0x0d },
3587         { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 },
3588         { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
3589         { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, { 0x7d, 0x00 },
3590         { 0x87, 0x00 },
3591     };
3592     sensor.gamma = { 1.0f, 1.0f, 1.0f };
3593     {
3594         struct CustomSensorSettings
3595         {
3596             ValueFilterAny<unsigned> resolutions;
3597             ScanMethod method;
3598             unsigned register_dpiset;
3599             int output_pixel_offset;
3600             StaggerConfig stagger_y;
3601         };
3602 
3603         CustomSensorSettings custom_settings[] = {
3604             { { 900 },  ScanMethod::TRANSPARENCY, 150, 15, StaggerConfig{} },
3605             { { 1800 }, ScanMethod::TRANSPARENCY, 300, 30, StaggerConfig{} },
3606             { { 3600 }, ScanMethod::TRANSPARENCY, 600, 60, StaggerConfig{} },
3607             { { 7200 }, ScanMethod::TRANSPARENCY, 1200, 120, StaggerConfig{4, 0} },
3608             { { 900 },  ScanMethod::TRANSPARENCY_INFRARED, 150, 15, StaggerConfig{} },
3609             { { 1800 }, ScanMethod::TRANSPARENCY_INFRARED, 300, 30, StaggerConfig{} },
3610             { { 3600 }, ScanMethod::TRANSPARENCY_INFRARED, 600, 60, StaggerConfig{} },
3611             { { 7200 }, ScanMethod::TRANSPARENCY_INFRARED, 1200, 120, StaggerConfig{4, 0} },
3612         };
3613 
3614         for (const CustomSensorSettings& setting : custom_settings) {
3615             sensor.resolutions = setting.resolutions;
3616             sensor.method = setting.method;
3617             sensor.shading_resolution = setting.resolutions.values()[0];
3618             sensor.register_dpiset = setting.register_dpiset;
3619             sensor.output_pixel_offset = setting.output_pixel_offset;
3620             sensor.stagger_y = setting.stagger_y;
3621             s_sensors->push_back(sensor);
3622         }
3623     }
3624 
3625 
3626     sensor = Genesys_Sensor();
3627     sensor.sensor_id = SensorId::CCD_IMG101; // gl846
3628     sensor.resolutions = { 75, 100, 150, 300, 600, 1200 };
3629     sensor.exposure_lperiod = 11000;
3630     sensor.segment_size = 5136;
3631     sensor.segment_order = {0, 1};
3632     sensor.full_resolution = 1200;
3633     sensor.black_pixels = 31;
3634     sensor.dummy_pixel = 31;
3635     sensor.fau_gain_white_ref = 210;
3636     sensor.gain_white_ref = 200;
3637     sensor.exposure = { 0x0000, 0x0000, 0x0000 };
3638     sensor.custom_regs = {
3639         { 0x16, 0xbb }, { 0x17, 0x13 }, { 0x18, 0x10 }, { 0x19, 0xff },
3640         { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x06 },
3641         { 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 },
3642         { 0x56, 0x0a }, { 0x57, 0x00 }, { 0x58, 0x59 }, { 0x59, 0x31 }, { 0x5a, 0x40 },
3643         { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
3644         { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
3645         { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
3646     };
3647     sensor.gamma = { 1.7f, 1.7f, 1.7f };
3648     {
3649         struct CustomSensorSettings
3650         {
3651             ValueFilterAny<unsigned> resolutions;
3652             unsigned register_dpihw;
3653             Ratio pixel_count_ratio;
3654             unsigned shading_factor;
3655             GenesysRegisterSettingSet extra_custom_regs;
3656         };
3657 
3658         CustomSensorSettings custom_settings[] = {
3659             { { 75 }, 600, Ratio{1, 4}, 8, { { 0x7e, 0x00 } } },
3660             { { 100 }, 600, Ratio{1, 4}, 6, { { 0x7e, 0x00 } } },
3661             { { 150 }, 600, Ratio{1, 4}, 4, { { 0x7e, 0x00 } } },
3662             { { 300 }, 600, Ratio{1, 4}, 2, { { 0x7e, 0x00 } } },
3663             { { 600 }, 600, Ratio{1, 4}, 1, { { 0x7e, 0x01 } } },
3664             { { 1200 }, 1200, Ratio{1, 2}, 1, { { 0x7e, 0x01 } } },
3665         };
3666 
3667         auto base_custom_regs = sensor.custom_regs;
3668         for (const CustomSensorSettings& setting : custom_settings) {
3669             sensor.resolutions = setting.resolutions;
3670             sensor.register_dpihw = setting.register_dpihw;
3671             sensor.register_dpiset = setting.resolutions.values()[0];
3672             sensor.shading_resolution = setting.register_dpihw;
3673             sensor.pixel_count_ratio = setting.pixel_count_ratio;
3674             sensor.shading_factor = setting.shading_factor;
3675             sensor.custom_regs = base_custom_regs;
3676             sensor.custom_regs.merge(setting.extra_custom_regs);
3677             s_sensors->push_back(sensor);
3678         }
3679     }
3680 
3681 
3682     sensor = Genesys_Sensor();
3683     sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICBOOK_3800; // gl845
3684     sensor.resolutions = { 75, 100, 150, 300, 600, 1200 };
3685     sensor.exposure_lperiod = 11000;
3686     sensor.full_resolution = 1200;
3687     sensor.black_pixels = 31;
3688     sensor.dummy_pixel = 31;
3689     sensor.fau_gain_white_ref = 210;
3690     sensor.gain_white_ref = 200;
3691     sensor.exposure = { 0, 0, 0 };
3692     sensor.custom_regs = {
3693         { 0x16, 0xbb }, { 0x17, 0x13 }, { 0x18, 0x10 }, { 0x19, 0xff },
3694         { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x06 },
3695         { 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 },
3696         { 0x56, 0x0a }, { 0x57, 0x00 }, { 0x58, 0x59 }, { 0x59, 0x31 }, { 0x5a, 0x40 },
3697         { 0x70, 0x01 }, { 0x71, 0x00 }, { 0x72, 0x02 }, { 0x73, 0x01 },
3698         { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c },
3699         { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f },
3700         { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x7d, 0x20 },
3701         { 0x87, 0x02 },
3702     };
3703     sensor.gamma = { 1.7f, 1.7f, 1.7f };
3704     {
3705         struct CustomSensorSettings
3706         {
3707             ValueFilterAny<unsigned> resolutions;
3708             unsigned register_dpihw;
3709             Ratio pixel_count_ratio;
3710             unsigned shading_factor;
3711         };
3712 
3713         CustomSensorSettings custom_settings[] = {
3714             { { 75 }, 600, Ratio{1, 2}, 8 },
3715             { { 100 }, 600, Ratio{1, 2}, 6 },
3716             { { 150 }, 600, Ratio{1, 2}, 4 },
3717             { { 300 }, 600, Ratio{1, 2}, 2 },
3718             { { 600 }, 600, Ratio{1, 2}, 1 },
3719             { { 1200 }, 1200, Ratio{1, 1}, 1 },
3720         };
3721 
3722         for (const CustomSensorSettings& setting : custom_settings) {
3723             sensor.resolutions = setting.resolutions;
3724             sensor.register_dpihw = setting.register_dpihw;
3725             sensor.register_dpiset = setting.resolutions.values()[0];
3726             sensor.shading_resolution = setting.register_dpihw;
3727             sensor.pixel_count_ratio = setting.pixel_count_ratio;
3728             sensor.shading_factor = setting.shading_factor;
3729             s_sensors->push_back(sensor);
3730         }
3731     }
3732 
3733     sensor = Genesys_Sensor();
3734     sensor.sensor_id = SensorId::CIS_CANON_LIDE_80; // gl841
3735     sensor.full_resolution = 1200; // real hardware limit is 2400
3736     sensor.register_dpihw = 1200;
3737     sensor.black_pixels = 20;
3738     sensor.dummy_pixel = 6;
3739     sensor.fau_gain_white_ref = 150;
3740     sensor.gain_white_ref = 150;
3741     // maps to 0x70-0x73 for GL841
3742     sensor.exposure = { 0x1000, 0x1000, 0x0500 };
3743     sensor.custom_regs = {
3744         { 0x16, 0x00 }, { 0x17, 0x01 }, { 0x18, 0x00 }, { 0x19, 0x06 },
3745         { 0x1a, 0x00 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x04 },
3746         { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 },
3747         { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x29 }, { 0x59, 0x69 }, { 0x5a, 0x55 },
3748         { 0x70, 0x00 }, { 0x71, 0x05 }, { 0x72, 0x07 }, { 0x73, 0x09 },
3749     };
3750     sensor.gamma = { 1.0f, 1.0f, 1.0f };
3751     {
3752         struct CustomSensorSettings
3753         {
3754             ValueFilterAny<unsigned> resolutions;
3755             unsigned optical_resolution;
3756             unsigned register_dpiset;
3757             unsigned shading_resolution;
3758             unsigned shading_factor;
3759             int output_pixel_offset;
3760         };
3761 
3762         CustomSensorSettings custom_settings[] = {
3763             { { 75 }, 600, 150, 600, 8, 2 },
3764             { { 100 }, 600, 200, 600, 6, 3 },
3765             { { 150 }, 600, 300, 600, 4, 4 },
3766             { { 200 }, 600, 400, 600, 3, 6 },
3767             { { 300 }, 600, 600, 600, 2, 9 },
3768             { { 600 }, 600, 1200, 600, 1, 17 },
3769             { { 1200 }, 1200, 1200, 1200, 1, 35 },
3770         };
3771 
3772         for (const CustomSensorSettings& setting : custom_settings) {
3773             sensor.resolutions = setting.resolutions;
3774             sensor.optical_resolution = setting.optical_resolution;
3775             sensor.register_dpiset = setting.register_dpiset;
3776             sensor.shading_resolution = setting.shading_resolution;
3777             sensor.shading_factor = setting.shading_factor;
3778             sensor.output_pixel_offset = setting.output_pixel_offset;
3779             s_sensors->push_back(sensor);
3780         }
3781     }
3782 }
3783 
verify_sensor_tables()3784 void verify_sensor_tables()
3785 {
3786     std::map<SensorId, AsicType> sensor_to_asic;
3787     for (const auto& device : *s_usb_devices) {
3788         sensor_to_asic[device.model().sensor_id] = device.model().asic_type;
3789     }
3790     for (const auto& sensor : *s_sensors) {
3791         if (sensor_to_asic.count(sensor.sensor_id) == 0) {
3792             throw SaneException("Unknown asic for sensor");
3793         }
3794         auto asic_type = sensor_to_asic[sensor.sensor_id];
3795 
3796         if (sensor.full_resolution == 0) {
3797             throw SaneException("full_resolution is not defined");
3798         }
3799 
3800         if (sensor.register_dpiset == 0) {
3801             throw SaneException("register_dpiset is not defined");
3802         }
3803 
3804         if (asic_type != AsicType::GL646) {
3805             if (sensor.register_dpihw == 0) {
3806                 throw SaneException("register_dpihw is not defined");
3807             }
3808             if (sensor.shading_resolution == 0) {
3809                 throw SaneException("shading_resolution is not defined");
3810             }
3811         }
3812 
3813         if (asic_type == AsicType::GL841) {
3814             auto required_registers = {
3815                 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
3816                 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
3817                 0x70, 0x71, 0x72, 0x73,
3818             };
3819             for (auto address : required_registers) {
3820                 if (!sensor.custom_regs.has_reg(address)) {
3821                     throw SaneException("Required register is not present");
3822                 }
3823             }
3824         }
3825 
3826         if (asic_type == AsicType::GL842) {
3827             auto required_registers = {
3828                 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1c, 0x1d,
3829                 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
3830                 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d,
3831                 0x7f
3832             };
3833             for (auto address : required_registers) {
3834                 if (!sensor.custom_regs.has_reg(address)) {
3835                     throw SaneException("Required register is not present");
3836                 }
3837             }
3838         }
3839     }
3840 }
3841 
3842 
3843 } // namespace genesys
3844