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