1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2003 Oliver Rauch
4    Copyright (C) 2003-2005 Henning Meier-Geinitz <henning@meier-geinitz.de>
5    Copyright (C) 2004, 2005 Gerhard Jaeger <gerhard@gjaeger.de>
6    Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr>
7    Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
8    Copyright (C) 2007 Luke <iceyfor@gmail.com>
9    Copyright (C) 2010 Jack McGill <jmcgill85258@yahoo.com>
10    Copyright (C) 2010 Andrey Loginov <avloginov@gmail.com>,
11                    xerox travelscan device entry
12    Copyright (C) 2010 Chris Berry <s0457957@sms.ed.ac.uk> and Michael Rickmann <mrickma@gwdg.de>
13                  for Plustek Opticbook 3600 support
14    Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
15 
16    This file is part of the SANE package.
17 
18    This program is free software; you can redistribute it and/or
19    modify it under the terms of the GNU General Public License as
20    published by the Free Software Foundation; either version 2 of the
21    License, or (at your option) any later version.
22 
23    This program is distributed in the hope that it will be useful, but
24    WITHOUT ANY WARRANTY; without even the implied warranty of
25    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26    General Public License for more details.
27 
28    You should have received a copy of the GNU General Public License
29    along with this program.  If not, see <https://www.gnu.org/licenses/>.
30 
31    As a special exception, the authors of SANE give permission for
32    additional uses of the libraries contained in this release of SANE.
33 
34    The exception is that, if you link a SANE library with other files
35    to produce an executable, this does not by itself cause the
36    resulting executable to be covered by the GNU General Public
37    License.  Your use of that executable is in no way restricted on
38    account of linking the SANE library code into it.
39 
40    This exception does not, however, invalidate any other reasons why
41    the executable file might be covered by the GNU General Public
42    License.
43 
44    If you submit changes to SANE to the maintainers to be included in
45    a subsequent release, you agree by submitting the changes that
46    those changes may be distributed with this exception intact.
47 
48    If you write modifications of your own for SANE, it is your choice
49    whether to permit this exception to apply to your modifications.
50    If you do not wish that, delete this exception notice.
51 */
52 
53 #define DEBUG_DECLARE_ONLY
54 
55 #include "low.h"
56 
57 namespace genesys {
58 
59 StaticInit<std::vector<UsbDeviceEntry>> s_usb_devices;
60 
genesys_init_usb_device_tables()61 void genesys_init_usb_device_tables()
62 {
63     /*  Guidelines on calibration area sizes
64         ------------------------------------
65 
66         on many scanners scanning a single line takes around 10ms. In order not to take excessive
67         amount of time, the sizes of the calibration area are limited as follows:
68         2400 dpi or less: 4mm (would take ~4 seconds on 2400 dpi)
69         4800 dpi or less: 3mm (would take ~6 seconds on 4800 dpi)
70         anything more: 2mm (would take ~7 seconds on 9600 dpi)
71 
72         Optional properties
73         -------------------
74 
75         All fields of the Genesys_Model class are defined even if they use default value, with
76         the following exceptions:
77 
78         If the scanner does not have ScanMethod::TRANSPARENCY or ScanMethod::TRANSPARENCY_INFRARED,
79         the following properties are optional:
80 
81         model.x_offset_ta = 0.0;
82         model.y_offset_ta = 0.0;
83         model.x_size_ta = 0.0;
84         model.y_size_ta = 0.0;
85 
86         model.y_offset_sensor_to_ta = 0.0;
87         model.y_offset_calib_white_ta = 0.0;
88         model.y_size_calib_ta_mm = 0.0;
89 
90         If the scanner does not have ModelFlag::DARK_WHITE_CALIBRATION, then the following
91         properties are optional:
92 
93         model.y_offset_calib_dark_white_mm = 0.0;
94         model.y_size_calib_dark_white_mm = 0.0;
95     */
96 
97     s_usb_devices.init();
98 
99     Genesys_Model model;
100     model.name = "umax-astra-4500";
101     model.vendor = "UMAX";
102     model.model = "Astra 4500";
103     model.model_id = ModelId::UMAX_ASTRA_4500;
104     model.asic_type = AsicType::GL646;
105 
106     model.resolutions = {
107         {
108             { ScanMethod::FLATBED },
109             { 1200, 600, 300, 150, 75 },
110             { 2400, 1200, 600, 300, 150, 75 }
111         }
112     };
113     model.bpp_gray_values = { 8, 16 };
114     model.bpp_color_values = { 8, 16 };
115 
116     model.x_offset = 3.5;
117     model.y_offset = 7.5;
118     model.x_size = 218.0;
119     model.y_size = 299.0;
120 
121     model.y_offset_calib_white = 0.0;
122     model.y_size_calib_mm = 4.0;
123     model.x_offset_calib_black = 1.0;
124     model.x_size_calib_mm = 228.6;
125 
126     model.post_scan = 0.0;
127     model.eject_feed = 0.0;
128 
129     model.ld_shift_r = 0;
130     model.ld_shift_g = 8;
131     model.ld_shift_b = 16;
132 
133     model.line_mode_color_order = ColorOrder::BGR;
134 
135     model.is_cis = false;
136     model.is_sheetfed = false;
137     model.sensor_id = SensorId::CCD_UMAX;
138     model.adc_id = AdcId::WOLFSON_UMAX;
139     model.gpio_id = GpioId::UMAX;
140     model.motor_id = MotorId::UMAX;
141     model.flags = ModelFlag::UNTESTED;
142     model.buttons = GENESYS_HAS_NO_BUTTONS;
143     model.search_lines = 200;
144 
145     s_usb_devices->emplace_back(0x0638, 0x0a10, model);
146 
147 
148     model = Genesys_Model();
149     model.name = "canon-lide-50";
150     model.vendor = "Canon";
151     model.model = "LiDE 35/40/50";
152     model.model_id = ModelId::CANON_LIDE_50;
153     model.asic_type = AsicType::GL841;
154 
155     model.resolutions = {
156         {
157             { ScanMethod::FLATBED },
158             { 1200, 600, 300, 200, 150, 75 },
159             { 2400, 1200, 600, 300, 200, 150, 75 },
160         }
161     };
162 
163     model.bpp_gray_values = { 8, 16 };
164     model.bpp_color_values = { 8, 16 };
165 
166     model.x_offset = 0.42;
167     model.y_offset = 7.9;
168     model.x_size = 218.0;
169     model.y_size = 299.0;
170 
171     model.y_offset_calib_white = 3.0;
172     model.y_size_calib_mm = 3.0;
173     model.y_offset_calib_dark_white_mm = 1.0;
174     model.y_size_calib_dark_white_mm = 6.0;
175     model.x_size_calib_mm = 220.13334;
176     model.x_offset_calib_black = 0.0;
177 
178     model.post_scan = 0.0;
179     model.eject_feed = 0.0;
180 
181     model.ld_shift_r = 0;
182     model.ld_shift_g = 0;
183     model.ld_shift_b = 0;
184 
185     model.line_mode_color_order = ColorOrder::RGB;
186 
187     model.is_cis = true;
188     model.is_sheetfed = false;
189     model.sensor_id = SensorId::CIS_CANON_LIDE_35;
190     model.adc_id = AdcId::CANON_LIDE_35;
191     model.gpio_id = GpioId::CANON_LIDE_35;
192     model.motor_id = MotorId::CANON_LIDE_35;
193     model.flags = ModelFlag::DARK_WHITE_CALIBRATION |
194                   ModelFlag::CUSTOM_GAMMA;
195     model.buttons = GENESYS_HAS_SCAN_SW |
196                     GENESYS_HAS_FILE_SW |
197                     GENESYS_HAS_EMAIL_SW |
198                     GENESYS_HAS_COPY_SW;
199     model.search_lines = 400;
200 
201     s_usb_devices->emplace_back(0x04a9, 0x2213, model);
202 
203 
204     model = Genesys_Model();
205     model.name = "panasonic-kv-ss080";
206     model.vendor = "Panasonic";
207     model.model = "KV-SS080";
208     model.model_id = ModelId::PANASONIC_KV_SS080;
209     model.asic_type = AsicType::GL843;
210 
211     model.resolutions = {
212         {
213             { ScanMethod::FLATBED },
214             { 600, /* 500, 400,*/ 300, 200, 150, 100, 75 },
215             { 1200, 600, /* 500, 400, */ 300, 200, 150, 100, 75 },
216         }
217     };
218 
219     model.bpp_gray_values = { 8, 16 };
220     model.bpp_color_values = { 8, 16 };
221 
222     model.x_offset = 7.2;
223     model.y_offset = 14.7;
224     model.x_size = 217.7;
225     model.y_size = 300.0;
226 
227     model.y_offset_calib_white = 9.0;
228     model.y_size_calib_mm = 4.0;
229     model.x_offset_calib_black = 0.0;
230     model.x_size_calib_mm = 227.584;
231 
232     model.post_scan = 0.0;
233     model.eject_feed = 0.0;
234 
235     model.ld_shift_r = 0;
236     model.ld_shift_g = 8;
237     model.ld_shift_b = 16;
238 
239     model.line_mode_color_order = ColorOrder::RGB;
240 
241     model.is_cis = false;
242     model.is_sheetfed = false;
243     model.sensor_id = SensorId::CCD_KVSS080;
244     model.adc_id = AdcId::KVSS080;
245     model.gpio_id = GpioId::KVSS080;
246     model.motor_id = MotorId::KVSS080;
247     model.flags = ModelFlag::CUSTOM_GAMMA;
248     model.buttons = GENESYS_HAS_SCAN_SW;
249     model.search_lines = 100;
250 
251     s_usb_devices->emplace_back(0x04da, 0x100f, model);
252 
253 
254     model = Genesys_Model();
255     model.name = "hewlett-packard-scanjet-4850c";
256     model.vendor = "Hewlett Packard";
257     model.model = "ScanJet 4850C";
258     model.model_id = ModelId::HP_SCANJET_4850C;
259     model.asic_type = AsicType::GL843;
260 
261     model.resolutions = {
262         {
263             { ScanMethod::FLATBED },
264             { 2400, 1200, 600, 400, 300, 200, 150, 100 },
265             { 2400, 1200, 600, 400, 300, 200, 150, 100 },
266         }
267     };
268 
269     model.bpp_gray_values = { 8, 16 };
270     model.bpp_color_values = { 8, 16 };
271 
272     model.x_offset = 7.9;
273     model.y_offset = 10.0;
274     model.x_size = 219.6;
275     model.y_size = 314.5;
276 
277     model.y_offset_calib_white = 0.0;
278     model.y_size_calib_mm = 4.0;
279     model.x_offset_calib_black = 0.0;
280     model.x_size_calib_mm = 226.9067;
281 
282     model.post_scan = 0.0;
283     model.eject_feed = 0.0;
284 
285     model.ld_shift_r = 0;
286     model.ld_shift_g = 24;
287     model.ld_shift_b = 48;
288 
289     model.line_mode_color_order = ColorOrder::RGB;
290 
291     model.is_cis = false;
292     model.is_sheetfed = false;
293     model.sensor_id = SensorId::CCD_HP_4850C;
294     model.adc_id = AdcId::G4050;
295     model.gpio_id = GpioId::G4050;
296     model.motor_id = MotorId::G4050;
297     model.flags = ModelFlag::WARMUP |
298                   ModelFlag::SHADING_REPARK |
299                   ModelFlag::CUSTOM_GAMMA;
300     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW;
301     model.search_lines = 100;
302     s_usb_devices->emplace_back(0x03f0, 0x1b05, model);
303 
304 
305     model = Genesys_Model();
306     model.name = "hewlett-packard-scanjet-g4010";
307     model.vendor = "Hewlett Packard";
308     model.model = "ScanJet G4010";
309     model.model_id = ModelId::HP_SCANJET_G4010;
310     model.asic_type = AsicType::GL843;
311 
312     model.resolutions = {
313         {
314             { ScanMethod::FLATBED },
315             { 2400, 1200, 600, 400, 300, 200, 150, 100 },
316             { 2400, 1200, 600, 400, 300, 200, 150, 100 },
317         }
318     };
319 
320     model.bpp_gray_values = { 8, 16 };
321     model.bpp_color_values = { 8, 16 };
322 
323     model.x_offset = 8.0;
324     model.y_offset = 13.00;
325     model.x_size = 217.9;
326     model.y_size = 315.0;
327 
328     model.y_offset_calib_white = 3.0;
329     model.y_size_calib_mm = 4.0;
330     model.x_offset_calib_black = 0.0;
331     model.x_size_calib_mm = 226.9067;
332 
333     model.post_scan = 0.0;
334     model.eject_feed = 0.0;
335 
336     model.ld_shift_r = 0;
337     model.ld_shift_g = 24;
338     model.ld_shift_b = 48;
339     model.line_mode_color_order = ColorOrder::RGB;
340 
341     model.is_cis = false;
342     model.is_sheetfed = false;
343     model.sensor_id = SensorId::CCD_G4050;
344     model.adc_id = AdcId::G4050;
345     model.gpio_id = GpioId::G4050;
346     model.motor_id = MotorId::G4050;
347     model.flags = ModelFlag::WARMUP |
348                   ModelFlag::DARK_CALIBRATION |
349                   ModelFlag::CUSTOM_GAMMA;
350     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW;
351     model.search_lines = 100;
352 
353     s_usb_devices->emplace_back(0x03f0, 0x4505, model);
354 
355 
356     model = Genesys_Model();
357     model.name = "hewlett-packard-scanjet-g4050";
358     model.vendor = "Hewlett Packard";
359     model.model = "ScanJet G4050";
360     model.model_id = ModelId::HP_SCANJET_G4050;
361     model.asic_type = AsicType::GL843;
362 
363     model.resolutions = {
364         {
365             { ScanMethod::FLATBED },
366             { 2400, 1200, 600, 400, 300, 200, 150, 100 },
367             { 2400, 1200, 600, 400, 300, 200, 150, 100 },
368         }
369     };
370 
371     model.bpp_gray_values = { 8, 16 };
372     model.bpp_color_values = { 8, 16 };
373 
374     model.x_offset = 8.0;
375     model.y_offset = 10.00;
376     model.x_size = 217.9;
377     model.y_size = 315.0;
378 
379     model.y_offset_calib_white = 0.0;
380     model.y_size_calib_mm = 4.0;
381     model.x_offset_calib_black = 0.0;
382     model.x_size_calib_mm = 226.9067;
383 
384     model.post_scan = 0.0;
385     model.eject_feed = 0.0;
386 
387     model.ld_shift_r = 0;
388     model.ld_shift_g = 24;
389     model.ld_shift_b = 48;
390 
391     model.line_mode_color_order = ColorOrder::RGB;
392 
393     model.is_cis = false;
394     model.is_sheetfed = false;
395     model.sensor_id = SensorId::CCD_G4050;
396     model.adc_id = AdcId::G4050;
397     model.gpio_id = GpioId::G4050;
398     model.motor_id = MotorId::G4050;
399     model.flags = ModelFlag::WARMUP |
400                   ModelFlag::DARK_CALIBRATION |
401                   ModelFlag::CUSTOM_GAMMA;
402     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW;
403     model.search_lines = 100;
404 
405     s_usb_devices->emplace_back(0x03f0, 0x4605, model);
406 
407 
408     model = Genesys_Model();
409     model.name = "canon-canoscan-4400f";
410     model.vendor = "Canon";
411     model.model = "Canoscan 4400f";
412     model.model_id = ModelId::CANON_4400F;
413     model.asic_type = AsicType::GL843;
414 
415     model.resolutions = {
416         {
417             { ScanMethod::FLATBED },
418             { 1200, 600, 300 },
419             { 1200, 600, 300 },
420         }, {
421             { ScanMethod::TRANSPARENCY },
422             { 4800, 2400, 1200 },
423             { 9600, 4800, 2400, 1200 },
424         }
425     };
426 
427     model.bpp_gray_values = { 8, 16 };
428     model.bpp_color_values = { 8, 16 };
429 
430     model.x_offset = 6.0;
431     model.y_offset = 10.00;
432     model.x_size = 215.9;
433     model.y_size = 297.0;
434 
435     model.y_offset_calib_white = 2.0;
436     model.y_size_calib_mm = 4.0;
437     model.x_offset_calib_black = 0.0;
438     model.x_size_calib_mm = 241.3;
439 
440     model.x_offset_ta = 115.0;
441     model.y_offset_ta = 37.0;
442     model.x_size_ta = 35.0;
443     model.y_size_ta = 230.0;
444 
445     model.y_offset_sensor_to_ta = 23.0;
446     model.y_offset_calib_white_ta = 24.0;
447     model.y_size_calib_ta_mm = 2.0;
448 
449     model.post_scan = 0.0;
450     model.eject_feed = 0.0;
451 
452     model.ld_shift_r = 96;
453     model.ld_shift_g = 48;
454     model.ld_shift_b = 0;
455 
456     model.line_mode_color_order = ColorOrder::RGB;
457 
458     model.is_cis = false;
459     model.is_sheetfed = false;
460     model.sensor_id = SensorId::CCD_CANON_4400F;
461     model.adc_id = AdcId::CANON_4400F;
462     model.gpio_id = GpioId::CANON_4400F;
463     model.motor_id = MotorId::CANON_4400F;
464     model.flags = ModelFlag::WARMUP |
465                   ModelFlag::DARK_CALIBRATION |
466                   ModelFlag::CUSTOM_GAMMA |
467                   ModelFlag::SHADING_REPARK |
468                   ModelFlag::UTA_NO_SECONDARY_MOTOR;
469 
470     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW;
471     model.search_lines = 100;
472 
473     s_usb_devices->emplace_back(0x04a9, 0x2228, model);
474 
475 
476     model = Genesys_Model();
477     model.name = "canon-canoscan-8400f";
478     model.vendor = "Canon";
479     model.model = "Canoscan 8400f";
480     model.model_id = ModelId::CANON_8400F;
481     model.asic_type = AsicType::GL843;
482 
483     model.resolutions = {
484         {
485             { ScanMethod::FLATBED },
486             { 3200, 1600, 800, 400 },
487             { 3200, 1600, 800, 400 },
488         }, {
489             { ScanMethod::TRANSPARENCY },
490             { 3200, 1600, 800, 400 },
491             { 3200, 1600, 800, 400 },
492         }, {
493             { ScanMethod::TRANSPARENCY_INFRARED },
494             { 3200, 1600, 800, 400 },
495             { 3200, 1600, 800, 400 },
496         }
497     };
498 
499     model.bpp_gray_values = { 8, 16 };
500     model.bpp_color_values = { 8, 16 };
501 
502     model.x_offset = 5.5;
503     model.y_offset = 17.00;
504     model.x_size = 219.9;
505     model.y_size = 300.0;
506 
507     model.y_offset_calib_white = 0.0;
508     model.y_size_calib_mm = 3.0;
509     model.x_offset_calib_black = 10.0;
510     model.x_size_calib_mm = 225.425;
511 
512     model.x_offset_ta = 75.0;
513     model.y_offset_ta = 45.00;
514     model.x_size_ta = 75.0;
515     model.y_size_ta = 230.0;
516 
517     model.y_offset_sensor_to_ta = 22.0;
518     model.y_offset_calib_white_ta = 25.0;
519     model.y_size_calib_ta_mm = 3.0;
520 
521     model.post_scan = 0.0;
522     model.eject_feed = 0.0;
523 
524     model.ld_shift_r = 0;
525     model.ld_shift_g = 24;
526     model.ld_shift_b = 48;
527 
528     model.line_mode_color_order = ColorOrder::RGB;
529 
530     model.is_cis = false;
531     model.is_sheetfed = false;
532     model.sensor_id = SensorId::CCD_CANON_8400F;
533     model.adc_id = AdcId::CANON_8400F;
534     model.gpio_id = GpioId::CANON_8400F;
535     model.motor_id = MotorId::CANON_8400F;
536     model.flags = ModelFlag::WARMUP |
537                   ModelFlag::DARK_CALIBRATION |
538                   ModelFlag::CUSTOM_GAMMA |
539                   ModelFlag::SHADING_REPARK;
540     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW;
541     model.search_lines = 100;
542 
543     s_usb_devices->emplace_back(0x04a9, 0x221e, model);
544 
545 
546     model = Genesys_Model();
547     model.name = "canon-canoscan-8600f";
548     model.vendor = "Canon";
549     model.model = "Canoscan 8600f";
550     model.model_id = ModelId::CANON_8600F;
551     model.asic_type = AsicType::GL843;
552 
553     model.resolutions = {
554         {
555             { ScanMethod::FLATBED },
556             { 1200, 600, 300 },
557             { 1200, 600, 300 },
558         }, {
559             { ScanMethod::TRANSPARENCY, ScanMethod::TRANSPARENCY_INFRARED },
560             { 4800, 2400, 1200, 600, 300 },
561             { 4800, 2400, 1200, 600, 300 },
562         }
563     };
564 
565     model.bpp_gray_values = { 8, 16 };
566     model.bpp_color_values = { 8, 16 };
567 
568     model.x_offset = 24.0;
569     model.y_offset = 10.0;
570     model.x_size = 216.0;
571     model.y_size = 297.0;
572 
573     model.y_offset_calib_white = 0.0;
574     model.y_size_calib_mm = 4.0;
575     model.x_offset_calib_black = 8.0;
576     model.x_size_calib_mm = 240.70734;
577 
578     model.x_offset_ta = 97.0;
579     model.y_offset_ta = 38.5;
580     model.x_size_ta = 70.0;
581     model.y_size_ta = 230.0;
582 
583     model.y_offset_sensor_to_ta = 23.0;
584     model.y_offset_calib_white_ta = 25.5;
585     model.y_size_calib_ta_mm = 3.0;
586 
587     model.post_scan = 0.0;
588     model.eject_feed = 0.0;
589 
590     model.ld_shift_r = 0;
591     model.ld_shift_g = 48;
592     model.ld_shift_b = 96;
593 
594     model.line_mode_color_order = ColorOrder::RGB;
595 
596     model.is_cis = false;
597     model.is_sheetfed = false;
598     model.sensor_id = SensorId::CCD_CANON_8600F;
599     model.adc_id = AdcId::CANON_8600F;
600     model.gpio_id = GpioId::CANON_8600F;
601     model.motor_id = MotorId::CANON_8600F;
602     model.flags = ModelFlag::WARMUP |
603                   ModelFlag::DARK_CALIBRATION |
604                   ModelFlag::CUSTOM_GAMMA |
605                   ModelFlag::SHADING_REPARK;
606     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW;
607     model.search_lines = 100;
608 
609     s_usb_devices->emplace_back(0x04a9, 0x2229, model);
610 
611 
612     model = Genesys_Model();
613     model.name = "canon-lide-100";
614     model.vendor = "Canon";
615     model.model = "LiDE 100";
616     model.model_id = ModelId::CANON_LIDE_100;
617     model.asic_type = AsicType::GL847;
618 
619     model.resolutions = {
620         {
621             { ScanMethod::FLATBED },
622             { 2400, 1200, 600, 300, 200, 150, 100, 75 },
623             { 4800, 2400, 1200, 600, 300, 200, 150, 100, 75 },
624         }
625     };
626 
627     model.bpp_gray_values = { 8, 16 };
628     model.bpp_color_values = { 8, 16 };
629 
630     model.x_offset = 1.1;
631     model.y_offset = 8.3;
632     model.x_size = 216.07;
633     model.y_size = 299.0;
634 
635     model.y_offset_calib_white = 0.4233334;
636     model.y_size_calib_mm = 3.0;
637     model.x_offset_calib_black = 0.0;
638     model.x_size_calib_mm = 217.4241;
639 
640     model.post_scan = 0.0;
641     model.eject_feed = 0.0;
642 
643     model.ld_shift_r = 0;
644     model.ld_shift_g = 0;
645     model.ld_shift_b = 0;
646 
647     model.line_mode_color_order = ColorOrder::RGB;
648 
649     model.is_cis = true;
650     model.is_sheetfed = false;
651     model.sensor_id = SensorId::CIS_CANON_LIDE_100;
652     model.adc_id = AdcId::CANON_LIDE_200;
653     model.gpio_id = GpioId::CANON_LIDE_200;
654     model.motor_id = MotorId::CANON_LIDE_100;
655     model.flags = ModelFlag::SIS_SENSOR |
656                   ModelFlag::DARK_CALIBRATION |
657                   ModelFlag::SHADING_REPARK |
658                   ModelFlag::CUSTOM_GAMMA;
659     model.buttons = GENESYS_HAS_SCAN_SW |
660                     GENESYS_HAS_COPY_SW |
661                     GENESYS_HAS_EMAIL_SW |
662                     GENESYS_HAS_FILE_SW;
663     model.search_lines = 400;
664 
665     s_usb_devices->emplace_back(0x04a9, 0x1904, model);
666 
667 
668     model = Genesys_Model();
669     model.name = "canon-lide-110";
670     model.vendor = "Canon";
671     model.model = "LiDE 110";
672     model.model_id = ModelId::CANON_LIDE_110;
673     model.asic_type = AsicType::GL124;
674 
675     model.resolutions = {
676         {
677             { ScanMethod::FLATBED },
678             { 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75 },
679             { 4800, 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75 },
680         }
681     };
682 
683     model.bpp_gray_values = { 8, 16 };
684     model.bpp_color_values = { 8, 16 };
685 
686     model.x_offset = 2.2;
687     model.y_offset = 9.0;
688     model.x_size = 216.70;
689     model.y_size = 300.0;
690 
691     model.y_offset_calib_white = 0.0;
692     model.y_size_calib_mm = 3.0;
693     model.x_offset_calib_black = 0.0;
694     model.x_size_calib_mm = 218.7787;
695 
696     model.post_scan = 0.0;
697     model.eject_feed = 0.0;
698 
699     model.ld_shift_r = 0;
700     model.ld_shift_g = 0;
701     model.ld_shift_b = 0;
702     model.line_mode_color_order = ColorOrder::RGB;
703 
704     model.is_cis = true;
705     model.is_sheetfed = false;
706     model.sensor_id = SensorId::CIS_CANON_LIDE_110;
707     model.adc_id = AdcId::CANON_LIDE_110;
708     model.gpio_id = GpioId::CANON_LIDE_110;
709     model.motor_id = MotorId::CANON_LIDE_110;
710     model.flags = ModelFlag::DARK_CALIBRATION |
711                   ModelFlag::SHADING_REPARK |
712                   ModelFlag::CUSTOM_GAMMA;
713     model.buttons = GENESYS_HAS_SCAN_SW |
714                     GENESYS_HAS_COPY_SW |
715                     GENESYS_HAS_EMAIL_SW |
716                     GENESYS_HAS_FILE_SW;
717     model.search_lines = 400;
718 
719     s_usb_devices->emplace_back(0x04a9, 0x1909, model);
720 
721 
722     model = Genesys_Model();
723     model.name = "canon-lide-120";
724     model.vendor = "Canon";
725     model.model = "LiDE 120";
726     model.model_id = ModelId::CANON_LIDE_120;
727     model.asic_type = AsicType::GL124;
728 
729     model.resolutions = {
730         {
731             { ScanMethod::FLATBED },
732             { 2400, 1200, 600, 300, 150, 100, 75 },
733             { 4800, 2400, 1200, 600, 300, 150, 100, 75 },
734         }
735     };
736 
737     model.bpp_gray_values = { 8, 16 };
738     model.bpp_color_values = { 8, 16 };
739 
740     model.x_offset = 0.0;
741     model.y_offset = 8.0;
742     model.x_size = 216.0;
743     model.y_size = 300.0;
744 
745     model.y_offset_calib_white = 1.0;
746     model.y_size_calib_mm = 3.0;
747     model.x_offset_calib_black = 0.0;
748     model.x_size_calib_mm = 216.0694;
749 
750     model.post_scan = 0.0;
751     model.eject_feed = 0.0;
752 
753     model.ld_shift_r = 0;
754     model.ld_shift_g = 0;
755     model.ld_shift_b = 0;
756     model.line_mode_color_order = ColorOrder::RGB;
757     model.is_cis = true;
758     model.is_sheetfed = false;
759     model.sensor_id = SensorId::CIS_CANON_LIDE_120;
760     model.adc_id = AdcId::CANON_LIDE_120;
761     model.gpio_id = GpioId::CANON_LIDE_120;
762     model.motor_id = MotorId::CANON_LIDE_120;
763     model.flags = ModelFlag::DARK_CALIBRATION |
764                   ModelFlag::SHADING_REPARK |
765                   ModelFlag::CUSTOM_GAMMA;
766     model.buttons = GENESYS_HAS_SCAN_SW |
767                     GENESYS_HAS_COPY_SW |
768                     GENESYS_HAS_EMAIL_SW |
769                     GENESYS_HAS_FILE_SW;
770     model.search_lines = 400;
771 
772     s_usb_devices->emplace_back(0x04a9, 0x190e, model);
773 
774 
775     model = Genesys_Model();
776     model.name = "canon-lide-210";
777     model.vendor = "Canon";
778     model.model = "LiDE 210";
779     model.model_id = ModelId::CANON_LIDE_210;
780     model.asic_type = AsicType::GL124;
781 
782     model.resolutions = {
783         {
784             { ScanMethod::FLATBED },
785             { 4800, 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75 },
786             { 4800, 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75 },
787         }
788     };
789 
790     model.bpp_gray_values = { 8, 16 };
791     model.bpp_color_values = { 8, 16 };
792 
793     model.x_offset = 2.1;
794     model.y_offset = 8.7;
795     model.x_size = 216.70;
796     model.y_size = 297.5;
797 
798     model.y_offset_calib_white = 0.0;
799     model.y_size_calib_mm = 3.0;
800     model.x_offset_calib_black = 0.0;
801     model.x_size_calib_mm = 218.7787;
802 
803     model.post_scan = 0.0;
804     model.eject_feed = 0.0;
805 
806     model.ld_shift_r = 0;
807     model.ld_shift_g = 0;
808     model.ld_shift_b = 0;
809 
810     model.line_mode_color_order = ColorOrder::RGB;
811 
812     model.is_cis = true;
813     model.is_sheetfed = false;
814     model.sensor_id = SensorId::CIS_CANON_LIDE_210;
815     model.adc_id = AdcId::CANON_LIDE_110;
816     model.gpio_id = GpioId::CANON_LIDE_210;
817     model.motor_id = MotorId::CANON_LIDE_210;
818     model.flags = ModelFlag::DARK_CALIBRATION |
819                   ModelFlag::SHADING_REPARK |
820                   ModelFlag::CUSTOM_GAMMA;
821     model.buttons = GENESYS_HAS_SCAN_SW |
822                     GENESYS_HAS_COPY_SW |
823                     GENESYS_HAS_EMAIL_SW |
824                     GENESYS_HAS_FILE_SW |
825                     GENESYS_HAS_EXTRA_SW;
826     model.search_lines = 400;
827 
828     s_usb_devices->emplace_back(0x04a9, 0x190a, model);
829 
830 
831     model = Genesys_Model();
832     model.name = "canon-lide-220";
833     model.vendor = "Canon";
834     model.model = "LiDE 220";
835     model.model_id = ModelId::CANON_LIDE_220;
836     model.asic_type = AsicType::GL124; // or a compatible one
837 
838     model.resolutions = {
839         {
840             { ScanMethod::FLATBED },
841             { 4800, 2400, 1200, 600, 300, 150, 100, 75 },
842             { 4800, 2400, 1200, 600, 300, 150, 100, 75 },
843         }
844     };
845 
846     model.bpp_gray_values = { 8, 16 };
847     model.bpp_color_values = { 8, 16 };
848 
849     model.x_offset = 2.1;
850     model.y_offset = 8.7;
851     model.x_size = 216.70;
852     model.y_size = 297.5;
853 
854     model.y_offset_calib_white = 0.0;
855     model.y_size_calib_mm = 3.0;
856     model.x_offset_calib_black = 0.0;
857     model.x_size_calib_mm = 218.7787;
858 
859     model.post_scan = 0.0;
860     model.eject_feed = 0.0;
861 
862     model.ld_shift_r = 0;
863     model.ld_shift_g = 0;
864     model.ld_shift_b = 0;
865 
866     model.line_mode_color_order = ColorOrder::RGB;
867     model.is_cis = true;
868     model.is_sheetfed = false;
869     model.sensor_id = SensorId::CIS_CANON_LIDE_220;
870     model.adc_id = AdcId::CANON_LIDE_110;
871     model.gpio_id = GpioId::CANON_LIDE_210;
872     model.motor_id = MotorId::CANON_LIDE_210;
873     model.flags = ModelFlag::DARK_CALIBRATION |
874                   ModelFlag::SHADING_REPARK |
875                   ModelFlag::CUSTOM_GAMMA;
876     model.buttons = GENESYS_HAS_SCAN_SW |
877                     GENESYS_HAS_COPY_SW |
878                     GENESYS_HAS_EMAIL_SW |
879                     GENESYS_HAS_FILE_SW |
880                     GENESYS_HAS_EXTRA_SW;
881     model.search_lines = 400;
882 
883     s_usb_devices->emplace_back(0x04a9, 0x190f, model);
884 
885 
886     model = Genesys_Model();
887     model.name = "canon-canoscan-5600f";
888     model.vendor = "Canon";
889     model.model = "CanoScan 5600F";
890     model.model_id = ModelId::CANON_5600F;
891     model.asic_type = AsicType::GL847;
892 
893     model.resolutions = {
894         {
895             { ScanMethod::FLATBED, ScanMethod::TRANSPARENCY },
896             { 4800, 2400, 1200, 600, 300, /*150*/ },
897             { 4800, 2400, 1200, 600, 300, /*150*/ },
898         }
899     };
900 
901     model.bpp_gray_values = { 8, 16 };
902     model.bpp_color_values = { 8, 16 };
903 
904     model.x_offset = 1.5;
905     model.y_offset = 10.4;
906     model.x_size = 219.00;
907     model.y_size = 305.0;
908 
909     model.y_offset_calib_white = 2.0;
910     model.y_size_calib_mm = 2.0;
911     model.x_offset_calib_black = 0.0;
912     model.x_size_calib_mm = 220.5;
913 
914     model.x_offset_ta = 93.0;
915     model.y_offset_ta = 42.4;
916     model.x_size_ta = 35.0;
917     model.y_size_ta = 230.0;
918 
919     model.y_offset_sensor_to_ta = 0;
920     model.y_offset_calib_white_ta = 21.4;
921     model.y_size_calib_ta_mm = 1.0;
922 
923     model.post_scan = 0.0;
924     model.eject_feed = 0.0;
925 
926     model.ld_shift_r = 0;
927     model.ld_shift_g = 32;
928     model.ld_shift_b = 64;
929 
930     model.line_mode_color_order = ColorOrder::RGB;
931 
932     model.is_cis = false;
933     model.is_sheetfed = false;
934     model.sensor_id = SensorId::CCD_CANON_5600F;
935     model.adc_id = AdcId::CANON_5600F;
936     model.gpio_id = GpioId::CANON_5600F;
937     model.motor_id = MotorId::CANON_5600F;
938     model.flags = ModelFlag::SIS_SENSOR |
939                   ModelFlag::INVERT_PIXEL_DATA |
940                   ModelFlag::DISABLE_ADC_CALIBRATION |
941                   ModelFlag::DISABLE_EXPOSURE_CALIBRATION |
942                   ModelFlag::HOST_SIDE_CALIBRATION_COMPLETE_SCAN |
943                   ModelFlag::DARK_CALIBRATION |
944                   ModelFlag::SHADING_REPARK |
945                   ModelFlag::UTA_NO_SECONDARY_MOTOR |
946                   ModelFlag::CUSTOM_GAMMA;
947     model.buttons = GENESYS_HAS_SCAN_SW |
948                     GENESYS_HAS_COPY_SW |
949                     GENESYS_HAS_EMAIL_SW |
950                     GENESYS_HAS_FILE_SW;
951     model.search_lines = 400;
952 
953     s_usb_devices->emplace_back(0x04a9, 0x1906, model);
954 
955 
956     model = Genesys_Model();
957     model.name = "canon-lide-700f";
958     model.vendor = "Canon";
959     model.model = "LiDE 700F";
960     model.model_id = ModelId::CANON_LIDE_700F;
961     model.asic_type = AsicType::GL847;
962 
963     model.resolutions = {
964         {
965             // FIXME: support 2400 ad 4800 dpi
966             { ScanMethod::FLATBED },
967             { 1200, 600, 300, 200, 150, 100, 75 },
968             { 1200, 600, 300, 200, 150, 100, 75 },
969         }
970     };
971 
972     model.bpp_gray_values = { 8, 16 };
973     model.bpp_color_values = { 8, 16 };
974 
975     model.x_offset = 3.1;
976     model.y_offset = 8.1;
977     model.x_size = 216.07;
978     model.y_size = 297.0;
979 
980     model.y_offset_calib_white = 0.4233334;
981     model.y_size_calib_mm = 3.0;
982     model.x_offset_calib_black = 0.0;
983     model.x_size_calib_mm = 219.6254;
984 
985     model.post_scan = 0.0;
986     model.eject_feed = 0.0;
987 
988     model.ld_shift_r = 0;
989     model.ld_shift_g = 0;
990     model.ld_shift_b = 0;
991 
992     model.line_mode_color_order = ColorOrder::RGB;
993 
994     model.is_cis = true;
995     model.is_sheetfed = false;
996     model.sensor_id = SensorId::CIS_CANON_LIDE_700F;
997     model.adc_id = AdcId::CANON_LIDE_700F;
998     model.gpio_id = GpioId::CANON_LIDE_700F;
999     model.motor_id = MotorId::CANON_LIDE_700;
1000     model.flags = ModelFlag::SIS_SENSOR |
1001                   ModelFlag::DARK_CALIBRATION |
1002                   ModelFlag::SHADING_REPARK |
1003                   ModelFlag::CUSTOM_GAMMA;
1004     model.buttons = GENESYS_HAS_SCAN_SW |
1005                     GENESYS_HAS_COPY_SW |
1006                     GENESYS_HAS_EMAIL_SW |
1007                     GENESYS_HAS_FILE_SW;
1008     model.search_lines = 400;
1009 
1010     s_usb_devices->emplace_back(0x04a9, 0x1907, model);
1011 
1012 
1013     model = Genesys_Model();
1014     model.name = "canon-lide-200";
1015     model.vendor = "Canon";
1016     model.model = "LiDE 200";
1017     model.model_id = ModelId::CANON_LIDE_200;
1018     model.asic_type = AsicType::GL847;
1019 
1020     model.resolutions = {
1021         {
1022             { ScanMethod::FLATBED },
1023             { 4800, 2400, 1200, 600, 300, 200, 150, 100, 75 },
1024             { 4800, 2400, 1200, 600, 300, 200, 150, 100, 75 },
1025         }
1026     };
1027 
1028     model.bpp_gray_values = { 8, 16 };
1029     model.bpp_color_values = { 8, 16 };
1030 
1031     model.x_offset = 1.1;
1032     model.y_offset = 8.3;
1033     model.x_size = 216.07;
1034     model.y_size = 299.0;
1035 
1036     model.y_offset_calib_white = 0.4233334;
1037     model.y_size_calib_mm = 3.0;
1038     model.x_offset_calib_black = 0.0;
1039     model.x_size_calib_mm = 217.4241;
1040 
1041     model.post_scan = 0.0;
1042     model.eject_feed = 0.0;
1043 
1044     model.ld_shift_r = 0;
1045     model.ld_shift_g = 0;
1046     model.ld_shift_b = 0;
1047 
1048     model.line_mode_color_order = ColorOrder::RGB;
1049     model.is_cis = true;
1050     model.is_sheetfed = false;
1051     model.sensor_id = SensorId::CIS_CANON_LIDE_200;
1052     model.adc_id = AdcId::CANON_LIDE_200;
1053     model.gpio_id = GpioId::CANON_LIDE_200;
1054     model.motor_id = MotorId::CANON_LIDE_200;
1055     model.flags = ModelFlag::SIS_SENSOR |
1056                   ModelFlag::DARK_CALIBRATION |
1057                   ModelFlag::SHADING_REPARK |
1058                   ModelFlag::CUSTOM_GAMMA;
1059     model.buttons = GENESYS_HAS_SCAN_SW |
1060                     GENESYS_HAS_COPY_SW |
1061                     GENESYS_HAS_EMAIL_SW |
1062                     GENESYS_HAS_FILE_SW;
1063     model.search_lines = 400;
1064 
1065     s_usb_devices->emplace_back(0x04a9, 0x1905, model);
1066 
1067 
1068     model = Genesys_Model();
1069     model.name = "canon-lide-60";
1070     model.vendor = "Canon";
1071     model.model = "LiDE 60";
1072     model.model_id = ModelId::CANON_LIDE_60;
1073     model.asic_type = AsicType::GL841;
1074 
1075     model.resolutions = {
1076         {
1077             { ScanMethod::FLATBED },
1078             { 1200, 600, 300, 150, 75 },
1079             { 2400, 1200, 600, 300, 150, 75 },
1080         }
1081     };
1082 
1083     model.bpp_gray_values = { 8, 16 };
1084     model.bpp_color_values = { 8, 16 };
1085 
1086     model.x_offset = 0.42;
1087     model.y_offset = 7.9;
1088     model.x_size = 218.0;
1089     model.y_size = 299.0;
1090 
1091     model.y_offset_calib_white = 3.0;
1092     model.y_size_calib_mm = 3.0;
1093     model.y_offset_calib_dark_white_mm = 1.0;
1094     model.y_size_calib_dark_white_mm = 6.0;
1095     model.x_offset_calib_black = 0.0;
1096     model.x_size_calib_mm = 220.13334;
1097 
1098     model.post_scan = 0.0;
1099     model.eject_feed = 0.0;
1100 
1101     model.ld_shift_r = 0;
1102     model.ld_shift_g = 0;
1103     model.ld_shift_b = 0;
1104     model.line_mode_color_order = ColorOrder::RGB;
1105 
1106     model.is_cis = true;
1107     model.is_sheetfed = false;
1108     model.sensor_id = SensorId::CIS_CANON_LIDE_60;
1109     model.adc_id = AdcId::CANON_LIDE_35;
1110     model.gpio_id = GpioId::CANON_LIDE_35;
1111     model.motor_id = MotorId::CANON_LIDE_60;
1112     model.flags = ModelFlag::DARK_WHITE_CALIBRATION |
1113                   ModelFlag::CUSTOM_GAMMA;
1114 
1115     model.buttons = GENESYS_HAS_COPY_SW |
1116                     GENESYS_HAS_SCAN_SW |
1117                     GENESYS_HAS_FILE_SW |
1118                     GENESYS_HAS_EMAIL_SW;
1119     model.search_lines = 400;
1120     s_usb_devices->emplace_back(0x04a9, 0x221c, model);
1121 
1122 
1123     model = Genesys_Model();
1124     model.name = "canon-lide-80";
1125     model.vendor = "Canon";
1126     model.model = "LiDE 80";
1127     model.model_id = ModelId::CANON_LIDE_80;
1128     model.asic_type = AsicType::GL841;
1129 
1130     model.resolutions = {
1131         {
1132             { ScanMethod::FLATBED },
1133             {       1200, 600, 300, 150, 100, 75 },
1134             { 2400, 1200, 600, 300, 150, 100, 75 },
1135         }
1136     };
1137 
1138     model.bpp_gray_values = { 8, 16 };
1139     model.bpp_color_values = { 8, 16 };
1140     model.x_offset = 0.42;
1141     model.y_offset = 7.90;
1142     model.x_size = 216.07;
1143     model.y_size = 299.0;
1144 
1145     model.y_offset_calib_white = 4.5;
1146     model.y_size_calib_mm = 3.0;
1147     model.y_offset_calib_dark_white_mm = 1.0;
1148     model.y_size_calib_dark_white_mm = 6.0;
1149     model.x_offset_calib_black = 0.0;
1150     model.x_size_calib_mm = 216.7467;
1151 
1152     model.post_scan = 0.0;
1153     model.eject_feed = 0.0;
1154 
1155     model.ld_shift_r = 0;
1156     model.ld_shift_g = 0;
1157     model.ld_shift_b = 0;
1158 
1159     model.line_mode_color_order = ColorOrder::RGB;
1160 
1161     model.is_cis = true;
1162     model.is_sheetfed = false;
1163     model.sensor_id = SensorId::CIS_CANON_LIDE_80;
1164     model.adc_id = AdcId::CANON_LIDE_80;
1165     model.gpio_id = GpioId::CANON_LIDE_80;
1166     model.motor_id = MotorId::CANON_LIDE_80;
1167     model.flags = ModelFlag::DARK_WHITE_CALIBRATION |
1168                   ModelFlag::CUSTOM_GAMMA;
1169     model.buttons = GENESYS_HAS_SCAN_SW |
1170                     GENESYS_HAS_FILE_SW |
1171                     GENESYS_HAS_EMAIL_SW |
1172                     GENESYS_HAS_COPY_SW;
1173     model.search_lines = 400;
1174 
1175     s_usb_devices->emplace_back(0x04a9, 0x2214, model);
1176 
1177 
1178     model = Genesys_Model();
1179     model.name = "canon-lide-90";
1180     model.vendor = "Canon";
1181     model.model = "LiDE 90";
1182     model.model_id = ModelId::CANON_LIDE_90;
1183     model.asic_type = AsicType::GL842;
1184 
1185     model.resolutions = {
1186         {
1187             { ScanMethod::FLATBED },
1188             { 2400, 1200, 600, 300 },
1189             { 2400, 1200, 600, 300 },
1190         }
1191     };
1192 
1193     model.bpp_gray_values = { 8, 16 };
1194     model.bpp_color_values = { 8, 16 };
1195     model.x_offset = 3.50;
1196     model.y_offset = 9.0;
1197     model.x_size = 219.0;
1198     model.y_size = 299.0;
1199 
1200     model.y_offset_calib_white = 0.0;
1201     model.y_size_calib_mm = 2.0;
1202     model.y_offset_calib_dark_white_mm = 0.0;
1203     model.y_size_calib_dark_white_mm = 0.0;
1204     model.x_offset_calib_black = 0.0;
1205     model.x_size_calib_mm = 221.5;
1206 
1207     model.post_scan = 0.0;
1208     model.eject_feed = 0.0;
1209 
1210     model.ld_shift_r = 0;
1211     model.ld_shift_g = 0;
1212     model.ld_shift_b = 0;
1213 
1214     model.line_mode_color_order = ColorOrder::RGB;
1215 
1216     model.is_cis = true;
1217     model.is_sheetfed = false;
1218     model.sensor_id = SensorId::CIS_CANON_LIDE_90;
1219     model.adc_id = AdcId::CANON_LIDE_90;
1220     model.gpio_id = GpioId::CANON_LIDE_90;
1221     model.motor_id = MotorId::CANON_LIDE_90;
1222     model.flags = ModelFlag::DISABLE_ADC_CALIBRATION |
1223                   ModelFlag::HOST_SIDE_CALIBRATION_COMPLETE_SCAN |
1224                   ModelFlag::USE_CONSTANT_FOR_DARK_CALIBRATION |
1225                   ModelFlag::DISABLE_FAST_FEEDING |
1226                   ModelFlag::SHADING_REPARK |
1227                   ModelFlag::CUSTOM_GAMMA;
1228     model.buttons = GENESYS_HAS_SCAN_SW |
1229                     GENESYS_HAS_FILE_SW |
1230                     GENESYS_HAS_EMAIL_SW |
1231                     GENESYS_HAS_COPY_SW;
1232     model.search_lines = 400;
1233 
1234     s_usb_devices->emplace_back(0x04a9, 0x1900, model);
1235 
1236 
1237     model = Genesys_Model();
1238     model.name = "hewlett-packard-scanjet-2300c";
1239     model.vendor = "Hewlett Packard";
1240     model.model = "ScanJet 2300c";
1241     model.model_id = ModelId::HP_SCANJET_2300C;
1242     model.asic_type = AsicType::GL646;
1243 
1244     model.resolutions = {
1245         {
1246             { ScanMethod::FLATBED },
1247             { 600, 300, 150, 75 },
1248             { 1200, 600, 300, 150, 75 },
1249         }
1250     };
1251 
1252     model.bpp_gray_values = { 8, 16 };
1253     model.bpp_color_values = { 8, 16 };
1254 
1255     model.x_offset = 6.5;
1256     model.y_offset = 8;
1257     model.x_size = 215.9;
1258     model.y_size = 295.0;
1259 
1260     model.y_offset_calib_white = 0.0;
1261     model.y_size_calib_mm = 4.0;
1262     model.x_offset_calib_black = 1.0;
1263     model.x_size_calib_mm = 227.2454;
1264 
1265     model.post_scan = 0.0;
1266     model.eject_feed = 0.0;
1267 
1268     model.ld_shift_r = 32;
1269     model.ld_shift_g = 16;
1270     model.ld_shift_b = 0;
1271 
1272     model.line_mode_color_order = ColorOrder::RGB;
1273     model.is_cis = false;
1274     model.is_sheetfed = false;
1275     model.sensor_id = SensorId::CCD_HP2300;
1276     model.adc_id = AdcId::WOLFSON_HP2300;
1277     model.gpio_id = GpioId::HP2300;
1278     model.motor_id = MotorId::HP2300;
1279     model.flags = ModelFlag::GAMMA_14BIT |
1280                   ModelFlag::DARK_CALIBRATION |
1281                   ModelFlag::CUSTOM_GAMMA;
1282     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW;
1283     model.search_lines = 132;
1284 
1285     s_usb_devices->emplace_back(0x03f0, 0x0901, model);
1286 
1287 
1288     model = Genesys_Model();
1289     model.name = "hewlett-packard-scanjet-2400c";
1290     model.vendor = "Hewlett Packard";
1291     model.model = "ScanJet 2400c";
1292     model.model_id = ModelId::HP_SCANJET_2400C;
1293     model.asic_type = AsicType::GL646;
1294 
1295     model.resolutions = {
1296         {
1297             { ScanMethod::FLATBED },
1298             { 1200, 600, 300, 150, 100, 50 },
1299             { 1200, 600, 300, 150, 100, 50 },
1300         }
1301     };
1302 
1303     model.bpp_gray_values = { 8, 16 };
1304     model.bpp_color_values = { 8, 16 };
1305 
1306     model.x_offset = 6.5;
1307     model.y_offset = 2.5;
1308     model.x_size = 220.0;
1309     model.y_size = 297.2;
1310 
1311     model.y_offset_calib_white = 0.0;
1312     model.y_size_calib_mm = 2.0; // FIXME: check if white area is really so small
1313     model.x_offset_calib_black = 1.0;
1314     model.x_size_calib_mm = 230.1241;
1315 
1316     model.post_scan = 0.0;
1317     model.eject_feed = 0.0;
1318 
1319     model.ld_shift_r = 0;
1320     model.ld_shift_g = 24;
1321     model.ld_shift_b = 48;
1322 
1323     model.line_mode_color_order = ColorOrder::RGB;
1324 
1325     model.is_cis = false;
1326     model.is_sheetfed = false;
1327     model.sensor_id = SensorId::CCD_HP2400;
1328     model.adc_id = AdcId::WOLFSON_HP2400;
1329     model.gpio_id = GpioId::HP2400;
1330     model.motor_id = MotorId::HP2400;
1331     model.flags = ModelFlag::GAMMA_14BIT |
1332                   ModelFlag::DARK_CALIBRATION |
1333                   ModelFlag::CUSTOM_GAMMA;
1334     model.buttons = GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_SCAN_SW;
1335     model.search_lines = 132;
1336 
1337     s_usb_devices->emplace_back(0x03f0, 0x0a01, model);
1338 
1339 
1340     model = Genesys_Model();
1341     model.name = "visioneer-strobe-xp200";
1342     model.vendor = "Visioneer";
1343     model.model = "Strobe XP200";
1344     model.model_id = ModelId::VISIONEER_STROBE_XP200;
1345     model.asic_type = AsicType::GL646;
1346 
1347     model.resolutions = {
1348         {
1349             { ScanMethod::FLATBED },
1350             { 600, 300, 200, 100, 75 },
1351             { 600, 300, 200, 100, 75 },
1352         }
1353     };
1354 
1355     model.bpp_gray_values = { 8, 16 };
1356     model.bpp_color_values = { 8, 16 };
1357 
1358     model.x_offset = 0.5;
1359     model.y_offset = 16.0;
1360     model.x_size = 215.9;
1361     model.y_size = 297.2;
1362 
1363     model.y_offset_calib_white = 0.0;
1364     model.y_size_calib_mm = 4.0;
1365     model.x_offset_calib_black = 0.0;
1366     model.x_size_calib_mm = 220.1334;
1367 
1368     model.post_scan = 0.0;
1369     model.eject_feed = 0.0;
1370 
1371     model.ld_shift_r = 0;
1372     model.ld_shift_g = 0;
1373     model.ld_shift_b = 0;
1374 
1375     model.line_mode_color_order = ColorOrder::RGB;
1376 
1377     model.is_cis = true;
1378     model.is_sheetfed = true;
1379     model.sensor_id = SensorId::CIS_XP200;
1380     model.adc_id = AdcId::AD_XP200;
1381     model.gpio_id = GpioId::XP200;
1382     model.motor_id = MotorId::XP200;
1383     model.flags = ModelFlag::GAMMA_14BIT |
1384                   ModelFlag::CUSTOM_GAMMA |
1385                   ModelFlag::DARK_CALIBRATION;
1386     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE;
1387     model.search_lines = 132;
1388 
1389     s_usb_devices->emplace_back(0x04a7, 0x0426, model);
1390 
1391 
1392     model = Genesys_Model();
1393     model.name = "hewlett-packard-scanjet-3670";
1394     model.vendor = "Hewlett Packard";
1395     model.model = "ScanJet 3670";
1396     model.model_id = ModelId::HP_SCANJET_3670;
1397     model.asic_type = AsicType::GL646;
1398 
1399     model.resolutions = {
1400         {
1401             { ScanMethod::FLATBED },
1402             { 1200, 600, 300, 150, 100, 75, 50 },
1403             { 1200, 600, 300, 150, 100, 75, 50 },
1404         }
1405     };
1406 
1407     model.bpp_gray_values = { 8, 16 };
1408     model.bpp_color_values = { 8, 16 };
1409 
1410     model.x_offset = 8.5;
1411     model.y_offset = 11.0;
1412     model.x_size = 215.9;
1413     model.y_size = 300.0;
1414 
1415     model.y_offset_calib_white = 0.0;
1416     model.y_size_calib_mm = 4.0;
1417     model.x_offset_calib_black = 1.0;
1418     model.x_size_calib_mm = 230.1241;
1419 
1420     model.post_scan = 0.0;
1421     model.eject_feed = 0.0;
1422 
1423     model.ld_shift_r = 0;
1424     model.ld_shift_g = 24;
1425     model.ld_shift_b = 48;
1426 
1427     model.line_mode_color_order = ColorOrder::RGB;
1428 
1429     model.is_cis = false;
1430     model.is_sheetfed = false;
1431     model.sensor_id = SensorId::CCD_HP3670;
1432     model.adc_id = AdcId::WOLFSON_HP3670;
1433     model.gpio_id = GpioId::HP3670;
1434     model.motor_id = MotorId::HP3670;
1435     model.flags = ModelFlag::WARMUP |
1436                   ModelFlag::GAMMA_14BIT |
1437                   ModelFlag::DARK_CALIBRATION |
1438                   ModelFlag::CUSTOM_GAMMA;
1439     model.buttons = GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_SCAN_SW;
1440     model.search_lines = 200;
1441 
1442     s_usb_devices->emplace_back(0x03f0, 0x1405, model);
1443 
1444 
1445     model = Genesys_Model();
1446     model.name = "plustek-opticpro-st12";
1447     model.vendor = "Plustek";
1448     model.model = "OpticPro ST12";
1449     model.model_id = ModelId::PLUSTEK_OPTICPRO_ST12;
1450     model.asic_type = AsicType::GL646;
1451 
1452     model.resolutions = {
1453         {
1454             { ScanMethod::FLATBED },
1455             { 600, 300, 150, 75 },
1456             { 1200, 600, 300, 150, 75 },
1457         }
1458     };
1459 
1460     model.bpp_gray_values = { 8, 16 };
1461     model.bpp_color_values = { 8, 16 };
1462 
1463     model.x_offset = 3.5;
1464     model.y_offset = 7.5;
1465     model.x_size = 218.0;
1466     model.y_size = 299.0;
1467 
1468     model.y_offset_calib_white = 0.0;
1469     model.y_size_calib_mm = 4.0;
1470     model.x_offset_calib_black = 1.0;
1471     model.x_size_calib_mm = 229.2774;
1472 
1473     model.post_scan = 0.0;
1474     model.eject_feed = 0.0;
1475 
1476     model.ld_shift_r = 0;
1477     model.ld_shift_g = 8;
1478     model.ld_shift_b = 16;
1479 
1480     model.line_mode_color_order = ColorOrder::BGR;
1481 
1482     model.is_cis = false;
1483     model.is_sheetfed = false;
1484     model.sensor_id = SensorId::CCD_ST12;
1485     model.adc_id = AdcId::WOLFSON_ST12;
1486     model.gpio_id = GpioId::ST12;
1487     model.motor_id = MotorId::UMAX;
1488     model.flags = ModelFlag::UNTESTED | ModelFlag::GAMMA_14BIT;
1489     model.buttons = GENESYS_HAS_NO_BUTTONS;
1490     model.search_lines = 200;
1491 
1492     s_usb_devices->emplace_back(0x07b3, 0x0600, model);
1493 
1494     model = Genesys_Model();
1495     model.name = "plustek-opticpro-st24";
1496     model.vendor = "Plustek";
1497     model.model = "OpticPro ST24";
1498     model.model_id = ModelId::PLUSTEK_OPTICPRO_ST24;
1499     model.asic_type = AsicType::GL646;
1500 
1501     model.resolutions = {
1502         {
1503             { ScanMethod::FLATBED },
1504             { 1200, 600, 300, 150, 75 },
1505             { 2400, 1200, 600, 300, 150, 75 },
1506         }
1507     };
1508 
1509     model.bpp_gray_values = { 8, 16 };
1510     model.bpp_color_values = { 8, 16 };
1511 
1512     model.x_offset = 3.5;
1513     model.y_offset = 7.5; // FIXME: incorrect, needs updating
1514     model.x_size = 218.0;
1515     model.y_size = 299.0;
1516 
1517     model.y_offset_calib_white = 0.0;
1518     model.y_size_calib_mm = 4.0;
1519     model.x_offset_calib_black = 1.0;
1520     model.x_size_calib_mm = 228.6;
1521 
1522     model.post_scan = 0.0;
1523     model.eject_feed = 0.0;
1524 
1525     model.ld_shift_r = 0;
1526     model.ld_shift_g = 8;
1527     model.ld_shift_b = 16;
1528 
1529     model.line_mode_color_order = ColorOrder::BGR;
1530 
1531     model.is_cis = false;
1532     model.is_sheetfed = false;
1533     model.sensor_id = SensorId::CCD_ST24;
1534     model.adc_id = AdcId::WOLFSON_ST24;
1535     model.gpio_id = GpioId::ST24;
1536     model.motor_id = MotorId::ST24;
1537     model.flags = ModelFlag::UNTESTED |
1538                   ModelFlag::GAMMA_14BIT |
1539                   ModelFlag::CUSTOM_GAMMA;
1540     model.buttons = GENESYS_HAS_NO_BUTTONS;
1541     model.search_lines = 200;
1542 
1543     s_usb_devices->emplace_back(0x07b3, 0x0601, model);
1544 
1545     model = Genesys_Model();
1546     model.name = "medion-md5345-model";
1547     model.vendor = "Medion";
1548     model.model = "MD5345/MD6228/MD6471";
1549     model.model_id = ModelId::MEDION_MD5345;
1550     model.asic_type = AsicType::GL646;
1551 
1552     model.resolutions = {
1553         {
1554             { ScanMethod::FLATBED },
1555             { 1200, 600, 400, 300, 200, 150, 100, 75, 50 },
1556             { 2400, 1200, 600, 400, 300, 200, 150, 100, 75, 50 },
1557         }
1558     };
1559 
1560     model.bpp_gray_values = { 8, 16 };
1561     model.bpp_color_values = { 8, 16 };
1562 
1563     model.x_offset = 0.30;
1564     model.y_offset = 4.0; // FIXME: incorrect, needs updating
1565     model.x_size = 220.0;
1566     model.y_size = 296.4;
1567 
1568     model.y_offset_calib_white = 0.00;
1569     model.y_size_calib_mm = 2.0;
1570     model.x_offset_calib_black = 0.00;
1571     model.x_size_calib_mm = 230.1241;
1572 
1573     model.post_scan = 0.0;
1574     model.eject_feed = 0.0;
1575 
1576     model.ld_shift_r = 96;
1577     model.ld_shift_g = 48;
1578     model.ld_shift_b = 0;
1579     model.line_mode_color_order = ColorOrder::RGB;
1580 
1581     model.is_cis = false;
1582     model.is_sheetfed = false;
1583     model.sensor_id = SensorId::CCD_5345;
1584     model.adc_id = AdcId::WOLFSON_5345;
1585     model.gpio_id = GpioId::MD_5345;
1586     model.motor_id = MotorId::MD_5345;
1587     model.flags = ModelFlag::WARMUP |
1588                   ModelFlag::GAMMA_14BIT |
1589                   ModelFlag::DARK_CALIBRATION |
1590                   ModelFlag::CUSTOM_GAMMA;
1591     model.buttons = GENESYS_HAS_COPY_SW |
1592                     GENESYS_HAS_EMAIL_SW |
1593                     GENESYS_HAS_POWER_SW |
1594                     GENESYS_HAS_OCR_SW |
1595                     GENESYS_HAS_SCAN_SW;
1596     model.search_lines = 200;
1597 
1598     s_usb_devices->emplace_back(0x0461, 0x0377, model);
1599 
1600     model = Genesys_Model();
1601     model.name = "visioneer-strobe-xp300";
1602     model.vendor = "Visioneer";
1603     model.model = "Strobe XP300";
1604     model.model_id = ModelId::VISIONEER_STROBE_XP300;
1605     model.asic_type = AsicType::GL841;
1606 
1607     model.resolutions = {
1608         {
1609             { ScanMethod::FLATBED },
1610             { 600, 300, 150, 75 },
1611             { 600, 300, 150, 75 },
1612         }
1613     };
1614 
1615     model.bpp_gray_values = { 8, 16 };
1616     model.bpp_color_values = { 8, 16 };
1617 
1618     model.x_offset = 0.0;
1619     model.y_offset = 1.0;
1620     model.x_size = 435.0;
1621     model.y_size = 511;
1622 
1623     model.y_offset_calib_white = 0.0;
1624     model.y_size_calib_mm = 4.0;
1625     model.x_offset_calib_black = 0.0;
1626     model.x_size_calib_mm = 433.4934;
1627 
1628     model.post_scan = 26.5;
1629     // this is larger than needed -- accounts for second sensor head, which is a calibration item
1630     model.eject_feed = 0.0;
1631     model.ld_shift_r = 0;
1632     model.ld_shift_g = 0;
1633     model.ld_shift_b = 0;
1634 
1635     model.line_mode_color_order = ColorOrder::RGB;
1636 
1637     model.is_cis = true;
1638     model.is_sheetfed = true;
1639     model.sensor_id = SensorId::CCD_XP300;
1640     model.adc_id = AdcId::WOLFSON_XP300;
1641     model.gpio_id = GpioId::XP300;
1642     model.motor_id = MotorId::XP300;
1643     model.flags = ModelFlag::DARK_CALIBRATION |
1644                   ModelFlag::CUSTOM_GAMMA;
1645     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE;
1646     model.search_lines = 400;
1647 
1648     s_usb_devices->emplace_back(0x04a7, 0x0474, model);
1649 
1650     model = Genesys_Model();
1651     model.name = "syscan-docketport-665";
1652     model.vendor = "Syscan/Ambir";
1653     model.model = "DocketPORT 665";
1654     model.model_id = ModelId::SYSCAN_DOCKETPORT_665;
1655     model.asic_type = AsicType::GL841;
1656 
1657     model.resolutions = {
1658         {
1659             { ScanMethod::FLATBED },
1660             { 600, 300, 150, 75 },
1661             { 1200, 600, 300, 150, 75 },
1662         }
1663     };
1664 
1665     model.bpp_gray_values = { 8, 16 };
1666     model.bpp_color_values = { 8, 16 };
1667 
1668     model.x_offset = 0.0;
1669     model.y_offset = 0.0;
1670     model.x_size = 108.0;
1671     model.y_size = 511;
1672 
1673     model.y_offset_calib_white = 0.0;
1674     model.y_size_calib_mm = 4.0;
1675     model.x_offset_calib_black = 0.0;
1676     model.x_size_calib_mm = 105.664;
1677 
1678     model.post_scan = 17.5;
1679     model.eject_feed = 0.0;
1680 
1681     model.ld_shift_r = 0;
1682     model.ld_shift_g = 0;
1683     model.ld_shift_b = 0;
1684 
1685     model.line_mode_color_order = ColorOrder::RGB;
1686 
1687     model.is_cis = true;
1688     model.is_sheetfed = true;
1689     model.sensor_id = SensorId::CCD_DP665;
1690     model.adc_id = AdcId::WOLFSON_XP300;
1691     model.gpio_id = GpioId::DP665;
1692     model.motor_id = MotorId::DP665;
1693     model.flags = ModelFlag::DARK_CALIBRATION |
1694                   ModelFlag::CUSTOM_GAMMA;
1695     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE;
1696     model.search_lines = 400;
1697 
1698     s_usb_devices->emplace_back(0x0a82, 0x4803, model);
1699 
1700     model = Genesys_Model();
1701     model.name = "visioneer-roadwarrior";
1702     model.vendor = "Visioneer";
1703     model.model = "Readwarrior";
1704     model.model_id = ModelId::VISIONEER_ROADWARRIOR;
1705     model.asic_type = AsicType::GL841;
1706 
1707     model.resolutions = {
1708         {
1709             { ScanMethod::FLATBED },
1710             { 600, 300, 150, 75 },
1711             { 1200, 600, 300, 150, 75 },
1712         }
1713     };
1714 
1715     model.bpp_gray_values = { 8, 16 };
1716     model.bpp_color_values = { 8, 16 };
1717 
1718     model.x_offset = 0.0;
1719     model.y_offset = 0.0;
1720     model.x_size = 220.0;
1721     model.y_size = 511;
1722 
1723     model.y_offset_calib_white = 0.0;
1724     model.y_size_calib_mm = 4.0;
1725     model.x_offset_calib_black = 0.0;
1726     model.x_size_calib_mm = 220.1334;
1727 
1728     model.post_scan = 16.0;
1729     model.eject_feed = 0.0;
1730 
1731     model.ld_shift_r = 0;
1732     model.ld_shift_g = 0;
1733     model.ld_shift_b = 0;
1734 
1735     model.line_mode_color_order = ColorOrder::RGB;
1736 
1737     model.is_cis = true;
1738     model.is_sheetfed = true;
1739     model.sensor_id = SensorId::CCD_ROADWARRIOR;
1740     model.adc_id = AdcId::WOLFSON_XP300;
1741     model.gpio_id = GpioId::DP665;
1742     model.motor_id = MotorId::ROADWARRIOR;
1743     model.flags = ModelFlag::CUSTOM_GAMMA |
1744                   ModelFlag::DARK_CALIBRATION;
1745     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE;
1746     model.search_lines = 400;
1747 
1748     s_usb_devices->emplace_back(0x04a7, 0x0494, model);
1749 
1750     model = Genesys_Model();
1751     model.name = "syscan-docketport-465";
1752     model.vendor = "Syscan";
1753     model.model = "DocketPORT 465";
1754     model.model_id = ModelId::SYSCAN_DOCKETPORT_465;
1755     model.asic_type = AsicType::GL841;
1756 
1757     model.resolutions = {
1758         {
1759             { ScanMethod::FLATBED },
1760             { 600, 300, 150, 75 },
1761             { 1200, 600, 300, 150, 75 },
1762         }
1763     };
1764 
1765     model.bpp_gray_values = { 8, 16 };
1766     model.bpp_color_values = { 8, 16 };
1767 
1768     model.x_offset = 0.0;
1769     model.y_offset = 0.0;
1770     model.x_size = 220.0;
1771     model.y_size = 511;
1772 
1773     model.y_offset_calib_white = 0.0;
1774     model.y_size_calib_mm = 4.0;
1775     model.x_offset_calib_black = 0.0;
1776     model.x_size_calib_mm = 220.1334;
1777 
1778     model.post_scan = 16.0;
1779     model.eject_feed = 0.0;
1780 
1781     model.ld_shift_r = 0;
1782     model.ld_shift_g = 0;
1783     model.ld_shift_b = 0;
1784 
1785     model.line_mode_color_order = ColorOrder::RGB;
1786 
1787     model.is_cis = true;
1788     model.is_sheetfed = true;
1789     model.sensor_id = SensorId::CCD_ROADWARRIOR;
1790     model.adc_id = AdcId::WOLFSON_XP300;
1791     model.gpio_id = GpioId::DP665;
1792     model.motor_id = MotorId::ROADWARRIOR;
1793     model.flags = ModelFlag::DISABLE_ADC_CALIBRATION |
1794                   ModelFlag::DISABLE_EXPOSURE_CALIBRATION |
1795                   ModelFlag::DISABLE_SHADING_CALIBRATION |
1796                   ModelFlag::CUSTOM_GAMMA |
1797                   ModelFlag::UNTESTED;
1798     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW;
1799     model.search_lines = 400;
1800 
1801     s_usb_devices->emplace_back(0x0a82, 0x4802, model);
1802 
1803 
1804     model = Genesys_Model();
1805     model.name = "visioneer-xp100-revision3";
1806     model.vendor = "Visioneer";
1807     model.model = "XP100 Revision 3";
1808     model.model_id = ModelId::VISIONEER_STROBE_XP100_REVISION3;
1809     model.asic_type = AsicType::GL841;
1810 
1811     model.resolutions = {
1812         {
1813             { ScanMethod::FLATBED },
1814             { 600, 300, 150, 75 },
1815             { 1200, 600, 300, 150, 75 },
1816         }
1817     };
1818 
1819     model.bpp_gray_values = { 8, 16 };
1820     model.bpp_color_values = { 8, 16 };
1821 
1822     model.x_offset = 0.0;
1823     model.y_offset = 0.0;
1824     model.x_size = 220.0;
1825     model.y_size = 511;
1826 
1827     model.y_offset_calib_white = 0.0;
1828     model.y_size_calib_mm = 4.0;
1829     model.x_offset_calib_black = 0.0;
1830     model.x_size_calib_mm = 220.1334;
1831 
1832     model.post_scan = 16.0;
1833     model.eject_feed = 0.0;
1834 
1835     model.ld_shift_r = 0;
1836     model.ld_shift_g = 0;
1837     model.ld_shift_b = 0;
1838 
1839     model.line_mode_color_order = ColorOrder::RGB;
1840 
1841     model.is_cis = true;
1842     model.is_sheetfed = true;
1843     model.sensor_id = SensorId::CCD_ROADWARRIOR;
1844     model.adc_id = AdcId::WOLFSON_XP300;
1845     model.gpio_id = GpioId::DP665;
1846     model.motor_id = MotorId::ROADWARRIOR;
1847     model.flags = ModelFlag::CUSTOM_GAMMA |
1848                   ModelFlag::DARK_CALIBRATION;
1849     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE;
1850     model.search_lines = 400;
1851 
1852     s_usb_devices->emplace_back(0x04a7, 0x049b, model);
1853 
1854     model = Genesys_Model();
1855     model.name = "pentax-dsmobile-600";
1856     model.vendor = "Pentax";
1857     model.model = "DSmobile 600";
1858     model.model_id = ModelId::PENTAX_DSMOBILE_600;
1859     model.asic_type = AsicType::GL841;
1860 
1861     model.resolutions = {
1862         {
1863             { ScanMethod::FLATBED },
1864             { 600, 300, 150, 75 },
1865             { 1200, 600, 300, 150, 75 },
1866         }
1867     };
1868 
1869     model.bpp_gray_values = { 8, 16 };
1870     model.bpp_color_values = { 8, 16 };
1871 
1872     model.x_offset = 0.0;
1873     model.y_offset = 0.0;
1874     model.x_size = 220.0;
1875     model.y_size = 511;
1876 
1877     model.y_offset_calib_white = 0.0;
1878     model.y_size_calib_mm = 4.0;
1879     model.x_offset_calib_black = 0.0;
1880     model.x_size_calib_mm = 220.1334;
1881 
1882     model.post_scan = 16.0;
1883     model.eject_feed = 0.0;
1884 
1885     model.ld_shift_r = 0;
1886     model.ld_shift_g = 0;
1887     model.ld_shift_b = 0;
1888 
1889     model.line_mode_color_order = ColorOrder::RGB;
1890 
1891     model.is_cis = true;
1892     model.is_sheetfed = true;
1893     model.sensor_id = SensorId::CCD_DSMOBILE600;
1894     model.adc_id = AdcId::WOLFSON_DSM600;
1895     model.gpio_id = GpioId::DP665;
1896     model.motor_id = MotorId::DSMOBILE_600;
1897     model.flags = ModelFlag::CUSTOM_GAMMA |
1898                   ModelFlag::DARK_CALIBRATION;
1899     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE;
1900     model.search_lines = 400;
1901 
1902     s_usb_devices->emplace_back(0x0a17, 0x3210, model);
1903     // clone, only usb id is different
1904     s_usb_devices->emplace_back(0x04f9, 0x2038, model);
1905 
1906     model = Genesys_Model();
1907     model.name = "syscan-docketport-467";
1908     model.vendor = "Syscan";
1909     model.model = "DocketPORT 467";
1910     model.model_id = ModelId::SYSCAN_DOCKETPORT_467;
1911     model.asic_type = AsicType::GL841;
1912 
1913     model.resolutions = {
1914         {
1915             { ScanMethod::FLATBED },
1916             { 600, 300, 150, 75 },
1917             { 1200, 600, 300, 150, 75 },
1918         }
1919     };
1920 
1921     model.bpp_gray_values = { 8, 16 };
1922     model.bpp_color_values = { 8, 16 };
1923 
1924     model.x_offset = 0.0;
1925     model.y_offset = 0.0;
1926     model.x_size = 220.0;
1927     model.y_size = 511;
1928 
1929     model.y_offset_calib_white = 0.0;
1930     model.y_size_calib_mm = 4.0;
1931     model.x_offset_calib_black = 0.0;
1932     model.x_size_calib_mm = 220.1334;
1933 
1934     model.post_scan = 16.0;
1935     model.eject_feed = 0.0;
1936 
1937     model.ld_shift_r = 0;
1938     model.ld_shift_g = 0;
1939     model.ld_shift_b = 0;
1940     model.line_mode_color_order = ColorOrder::RGB;
1941 
1942     model.is_cis = true;
1943     model.is_sheetfed = true;
1944     model.sensor_id = SensorId::CCD_DSMOBILE600;
1945     model.adc_id = AdcId::WOLFSON_DSM600;
1946     model.gpio_id = GpioId::DP665;
1947     model.motor_id = MotorId::DSMOBILE_600;
1948     model.flags = ModelFlag::CUSTOM_GAMMA |
1949                   ModelFlag::DARK_CALIBRATION;
1950     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE;
1951     model.search_lines = 400;
1952 
1953     s_usb_devices->emplace_back(0x1dcc, 0x4812, model);
1954 
1955     model = Genesys_Model();
1956     model.name = "syscan-docketport-685";
1957     model.vendor = "Syscan/Ambir";
1958     model.model = "DocketPORT 685";
1959     model.model_id = ModelId::SYSCAN_DOCKETPORT_685;
1960     model.asic_type = AsicType::GL841;
1961 
1962     model.resolutions = {
1963         {
1964             { ScanMethod::FLATBED },
1965             { 600, 300, 150, 75 },
1966             { 600, 300, 150, 75 },
1967         }
1968     };
1969 
1970     model.bpp_gray_values = { 8, 16 };
1971     model.bpp_color_values = { 8, 16 };
1972 
1973     model.x_offset = 0.0;
1974     model.y_offset = 1.0;
1975     model.x_size = 212.0;
1976     model.y_size = 500;
1977 
1978     model.y_offset_calib_white = 0.0;
1979     model.y_size_calib_mm = 4.0;
1980     model.x_offset_calib_black = 0.0;
1981     model.x_size_calib_mm = 212.5134;
1982 
1983     model.post_scan = 26.5;
1984     // this is larger than needed -- accounts for second sensor head, which is a calibration item
1985     model.eject_feed = 0.0;
1986     model.ld_shift_r = 0;
1987     model.ld_shift_g = 0;
1988     model.ld_shift_b = 0;
1989 
1990     model.line_mode_color_order = ColorOrder::RGB;
1991 
1992     model.is_cis = true;
1993     model.is_sheetfed = true;
1994     model.sensor_id = SensorId::CCD_DP685;
1995     model.adc_id = AdcId::WOLFSON_DSM600;
1996     model.gpio_id = GpioId::DP685;
1997     model.motor_id = MotorId::XP300;
1998     model.flags = ModelFlag::CUSTOM_GAMMA |
1999                   ModelFlag::DARK_CALIBRATION;
2000     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE;
2001     model.search_lines = 400;
2002 
2003 
2004     s_usb_devices->emplace_back(0x0a82, 0x480c, model);
2005 
2006 
2007     model = Genesys_Model();
2008     model.name = "syscan-docketport-485";
2009     model.vendor = "Syscan/Ambir";
2010     model.model = "DocketPORT 485";
2011     model.model_id = ModelId::SYSCAN_DOCKETPORT_485;
2012     model.asic_type = AsicType::GL841;
2013 
2014     model.resolutions = {
2015         {
2016             { ScanMethod::FLATBED },
2017             { 600, 300, 150, 75 },
2018             { 600, 300, 150, 75 },
2019         }
2020     };
2021 
2022     model.bpp_gray_values = { 8, 16 };
2023     model.bpp_color_values = { 8, 16 };
2024 
2025     model.x_offset = 0.0;
2026     model.y_offset = 1.0;
2027     model.x_size = 435.0;
2028     model.y_size = 511;
2029 
2030     model.y_offset_calib_white = 0.0;
2031     model.y_size_calib_mm = 4.0;
2032     model.x_offset_calib_black = 0.0;
2033     model.x_size_calib_mm = 433.4934;
2034 
2035     model.post_scan = 26.5;
2036     // this is larger than needed -- accounts for second sensor head, which is a calibration item
2037     model.eject_feed = 0.0;
2038     model.ld_shift_r = 0;
2039     model.ld_shift_g = 0;
2040     model.ld_shift_b = 0;
2041 
2042     model.line_mode_color_order = ColorOrder::RGB;
2043 
2044     model.is_cis = true;
2045     model.is_sheetfed = true;
2046     model.sensor_id = SensorId::CCD_XP300;
2047     model.adc_id = AdcId::WOLFSON_XP300;
2048     model.gpio_id = GpioId::XP300;
2049     model.motor_id = MotorId::XP300;
2050     model.flags = ModelFlag::CUSTOM_GAMMA |
2051                   ModelFlag::DARK_CALIBRATION;
2052     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE;
2053     model.search_lines = 400;
2054 
2055     s_usb_devices->emplace_back(0x0a82, 0x4800, model);
2056 
2057 
2058     model = Genesys_Model();
2059     model.name = "dct-docketport-487";
2060     model.vendor = "DCT";
2061     model.model = "DocketPORT 487";
2062     model.model_id = ModelId::DCT_DOCKETPORT_487;
2063     model.asic_type = AsicType::GL841;
2064 
2065     model.resolutions = {
2066         {
2067             { ScanMethod::FLATBED },
2068             { 600, 300, 150, 75 },
2069             { 600, 300, 150, 75 },
2070         }
2071     };
2072 
2073     model.bpp_gray_values = { 8, 16 };
2074     model.bpp_color_values = { 8, 16 };
2075 
2076     model.x_offset = 0.0;
2077     model.y_offset = 1.0;
2078     model.x_size = 435.0;
2079     model.y_size = 511;
2080 
2081     model.y_offset_calib_white = 0.0;
2082     model.y_size_calib_mm = 4.0;
2083     model.x_offset_calib_black = 0.0;
2084     model.x_size_calib_mm = 433.4934;
2085 
2086     model.post_scan = 26.5;
2087     // this is larger than needed -- accounts for second sensor head, which is a calibration item
2088     model.eject_feed = 0.0;
2089 
2090     model.ld_shift_r = 0;
2091     model.ld_shift_g = 0;
2092     model.ld_shift_b = 0;
2093 
2094     model.line_mode_color_order = ColorOrder::RGB;
2095 
2096     model.is_cis = true;
2097     model.is_sheetfed = true;
2098     model.sensor_id = SensorId::CCD_DOCKETPORT_487;
2099     model.adc_id = AdcId::WOLFSON_XP300;
2100     model.gpio_id = GpioId::XP300;
2101     model.motor_id = MotorId::XP300;
2102     model.flags = ModelFlag::DARK_CALIBRATION |
2103                   ModelFlag::CUSTOM_GAMMA |
2104                   ModelFlag::UNTESTED;
2105     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE;
2106     model.search_lines = 400;
2107 
2108     s_usb_devices->emplace_back(0x1dcc, 0x4810, model);
2109 
2110 
2111     model = Genesys_Model();
2112     model.name = "visioneer-7100-model";
2113     model.vendor = "Visioneer";
2114     model.model = "OneTouch 7100";
2115     model.model_id = ModelId::VISIONEER_7100;
2116     model.asic_type = AsicType::GL646;
2117 
2118     model.resolutions = {
2119         {
2120             { ScanMethod::FLATBED },
2121             { 1200, 600, 400, 300, 200, 150, 100, 75, 50 },
2122             { 2400, 1200, 600, 400, 300, 200, 150, 100, 75, 50 },
2123         }
2124     };
2125 
2126     model.bpp_gray_values = { 8, 16 };
2127     model.bpp_color_values = { 8, 16 };
2128 
2129     model.x_offset = 4.00;
2130     model.y_offset = 5.0; // FIXME: incorrect, needs updating
2131     model.x_size = 215.9;
2132     model.y_size = 296.4;
2133 
2134     model.y_offset_calib_white = 0.00;
2135     model.y_size_calib_mm = 4.0;
2136     model.x_offset_calib_black = 0.00;
2137     model.x_size_calib_mm = 230.1241;
2138 
2139     model.post_scan = 0.0;
2140     model.eject_feed = 0.0;
2141 
2142     model.ld_shift_r = 96;
2143     model.ld_shift_g = 48;
2144     model.ld_shift_b = 0;
2145     model.line_mode_color_order = ColorOrder::RGB;
2146 
2147     model.is_cis = false;
2148     model.is_sheetfed = false;
2149     model.sensor_id = SensorId::CCD_5345;
2150     model.adc_id = AdcId::WOLFSON_5345;
2151     model.gpio_id = GpioId::MD_5345;
2152     model.motor_id = MotorId::MD_5345;
2153     model.flags = ModelFlag::WARMUP |
2154                   ModelFlag::GAMMA_14BIT |
2155                   ModelFlag::DARK_CALIBRATION |
2156                   ModelFlag::CUSTOM_GAMMA;
2157     model.buttons = GENESYS_HAS_COPY_SW |
2158                     GENESYS_HAS_EMAIL_SW |
2159                     GENESYS_HAS_POWER_SW |
2160                     GENESYS_HAS_OCR_SW |
2161                     GENESYS_HAS_SCAN_SW;
2162     model.search_lines = 200;
2163 
2164     s_usb_devices->emplace_back(0x04a7, 0x0229, model);
2165 
2166 
2167     model = Genesys_Model();
2168     model.name = "xerox-2400-model";
2169     model.vendor = "Xerox";
2170     model.model = "OneTouch 2400";
2171     model.model_id = ModelId::XEROX_2400;
2172     model.asic_type = AsicType::GL646;
2173 
2174     model.resolutions = {
2175         {
2176             { ScanMethod::FLATBED },
2177             { 1200, 600, 400, 300, 200, 150, 100, 75, 50 },
2178             { 2400, 1200, 600, 400, 300, 200, 150, 100, 75, 50 },
2179         }
2180     };
2181 
2182     model.bpp_gray_values = { 8, 16 };
2183     model.bpp_color_values = { 8, 16 };
2184 
2185     model.x_offset = 4.00;
2186     model.y_offset = 5.0; // FIXME: incorrect, needs updating
2187     model.x_size = 215.9;
2188     model.y_size = 296.4;
2189 
2190     model.y_offset_calib_white = 0.00;
2191     model.y_size_calib_mm = 4.0;
2192     model.x_offset_calib_black = 0.00;
2193     model.x_size_calib_mm = 230.1241;
2194 
2195     model.post_scan = 0.0;
2196     model.eject_feed = 0.0;
2197 
2198     model.ld_shift_r = 96;
2199     model.ld_shift_g = 48;
2200     model.ld_shift_b = 0;
2201     model.line_mode_color_order = ColorOrder::RGB;
2202 
2203     model.is_cis = false;
2204     model.is_sheetfed = false;
2205     model.sensor_id = SensorId::CCD_5345;
2206     model.adc_id = AdcId::WOLFSON_5345;
2207     model.gpio_id = GpioId::MD_5345;
2208     model.motor_id = MotorId::MD_5345;
2209     model.flags = ModelFlag::WARMUP |
2210                   ModelFlag::GAMMA_14BIT |
2211                   ModelFlag::DARK_CALIBRATION |
2212                   ModelFlag::CUSTOM_GAMMA;
2213     model.buttons = GENESYS_HAS_COPY_SW |
2214                     GENESYS_HAS_EMAIL_SW |
2215                     GENESYS_HAS_POWER_SW |
2216                     GENESYS_HAS_OCR_SW |
2217                     GENESYS_HAS_SCAN_SW;
2218     model.search_lines = 200;
2219 
2220     s_usb_devices->emplace_back(0x0461, 0x038b, model);
2221 
2222 
2223     model = Genesys_Model();
2224     model.name = "xerox-travelscanner";
2225     model.vendor = "Xerox";
2226     model.model = "Travelscanner 100";
2227     model.model_id = ModelId::XEROX_TRAVELSCANNER_100;
2228     model.asic_type = AsicType::GL841;
2229 
2230     model.resolutions = {
2231         {
2232             { ScanMethod::FLATBED },
2233             { 600, 300, 150, 75 },
2234             { 1200, 600, 300, 150, 75 },
2235         }
2236     };
2237 
2238     model.bpp_gray_values = { 8, 16 };
2239     model.bpp_color_values = { 8, 16 };
2240 
2241     model.x_offset = 4.0;
2242     model.y_offset = 0.0;
2243     model.x_size = 220.0;
2244     model.y_size = 511;
2245 
2246     model.y_offset_calib_white = 0.0;
2247     model.y_size_calib_mm = 4.0;
2248     model.x_offset_calib_black = 0.0;
2249     model.x_size_calib_mm = 220.1334;
2250 
2251     model.post_scan = 16.0;
2252     model.eject_feed = 0.0;
2253 
2254     model.ld_shift_r = 0;
2255     model.ld_shift_g = 0;
2256     model.ld_shift_b = 0;
2257 
2258     model.line_mode_color_order = ColorOrder::RGB;
2259 
2260     model.is_cis = true;
2261     model.is_sheetfed = true;
2262     model.sensor_id = SensorId::CCD_ROADWARRIOR;
2263     model.adc_id = AdcId::WOLFSON_XP300;
2264     model.gpio_id = GpioId::DP665;
2265     model.motor_id = MotorId::ROADWARRIOR;
2266     model.flags = ModelFlag::CUSTOM_GAMMA |
2267                   ModelFlag::DARK_CALIBRATION;
2268     model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE;
2269     model.search_lines = 400;
2270 
2271     s_usb_devices->emplace_back(0x04a7, 0x04ac, model);
2272 
2273 
2274     model = Genesys_Model();
2275     model.name = "plustek-opticbook-3600";
2276     model.vendor = "PLUSTEK";
2277     model.model = "OpticBook 3600";
2278     model.model_id = ModelId::PLUSTEK_OPTICPRO_3600;
2279     model.asic_type = AsicType::GL841;
2280 
2281     model.resolutions = {
2282         {
2283             { ScanMethod::FLATBED },
2284             { /*1200,*/ 600, 400, 300, 200, 150, 100, 75 },
2285             { /*2400,*/ 1200, 600, 400, 300, 200, 150, 100, 75 },
2286         }
2287     };
2288 
2289     model.bpp_gray_values = { 8, 16 };
2290     model.bpp_color_values = { 8, 16 };
2291 
2292     model.x_offset = 0.42;
2293     model.y_offset = 6.75;
2294     model.x_size = 216.0;
2295     model.y_size = 297.0;
2296 
2297     model.y_offset_calib_white = 0.0;
2298     model.y_size_calib_mm = 4.0;
2299     model.x_offset_calib_black = 0.0;
2300     model.x_size_calib_mm = 213.7834;
2301 
2302     model.post_scan = 0.0;
2303     model.eject_feed = 0.0;
2304 
2305     model.ld_shift_r = 0;
2306     model.ld_shift_g = 24;
2307     model.ld_shift_b = 48;
2308 
2309     model.line_mode_color_order = ColorOrder::RGB;
2310 
2311     model.is_cis = false;
2312     model.is_sheetfed = false;
2313     model.sensor_id = SensorId::CCD_PLUSTEK_OPTICPRO_3600;
2314     model.adc_id = AdcId::PLUSTEK_OPTICPRO_3600;
2315     model.gpio_id = GpioId::PLUSTEK_OPTICPRO_3600;
2316     model.motor_id = MotorId::PLUSTEK_OPTICPRO_3600;
2317     model.flags = ModelFlag::UNTESTED |                // not fully working yet
2318                   ModelFlag::CUSTOM_GAMMA |
2319                   ModelFlag::DARK_CALIBRATION;
2320     model.buttons = GENESYS_HAS_NO_BUTTONS;
2321     model.search_lines = 200;
2322 
2323     s_usb_devices->emplace_back(0x07b3, 0x0900, model);
2324 
2325 
2326 
2327     model = Genesys_Model();
2328     model.name = "plustek-opticfilm-7200";
2329     model.vendor = "PLUSTEK";
2330     model.model = "OpticFilm 7200";
2331     model.model_id = ModelId::PLUSTEK_OPTICFILM_7200;
2332     model.asic_type = AsicType::GL842;
2333 
2334     model.resolutions = {
2335         {
2336             { ScanMethod::TRANSPARENCY },
2337             { 7200, 3600, 1800, 900 },
2338             { 7200, 3600, 1800, 900 },
2339         }
2340     };
2341 
2342     model.bpp_gray_values = { 16 };
2343     model.bpp_color_values = { 16 };
2344     model.default_method = ScanMethod::TRANSPARENCY;
2345 
2346     model.x_offset = 0.0;
2347     model.y_offset = 0.0;
2348     model.x_size = 36.0;
2349     model.y_size = 44.0;
2350 
2351     model.y_offset_calib_white = 0.0;
2352     model.y_size_calib_mm = 0.0;
2353     model.x_offset_calib_black = 6.5;
2354     model.x_size_calib_mm = 35.9834;
2355 
2356     model.x_offset_ta = 0.7f;
2357     model.y_offset_ta = 28.0;
2358     model.x_size_ta = 36.0;
2359     model.y_size_ta = 25.0;
2360 
2361     model.y_offset_sensor_to_ta = 0.0;
2362     model.y_offset_calib_black_ta = 6.5;
2363     model.y_offset_calib_white_ta = 0.0;
2364     model.y_size_calib_ta_mm = 2.0;
2365 
2366     model.post_scan = 0.0;
2367     model.eject_feed = 0.0;
2368 
2369     model.ld_shift_r = 0;
2370     model.ld_shift_g = 12;
2371     model.ld_shift_b = 24;
2372 
2373     model.line_mode_color_order = ColorOrder::RGB;
2374 
2375     model.is_cis = false;
2376     model.is_sheetfed = false;
2377 
2378     model.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7200;
2379     model.adc_id = AdcId::PLUSTEK_OPTICFILM_7200;
2380     model.gpio_id = GpioId::PLUSTEK_OPTICFILM_7200;
2381     model.motor_id = MotorId::PLUSTEK_OPTICFILM_7200;
2382 
2383     model.flags = ModelFlag::WARMUP |
2384                   ModelFlag::CUSTOM_GAMMA |
2385                   ModelFlag::DARK_CALIBRATION |
2386                   ModelFlag::SHADING_REPARK;
2387 
2388     model.search_lines = 200;
2389     s_usb_devices->emplace_back(0x07b3, 0x0807, model);
2390 
2391 
2392     model = Genesys_Model();
2393     model.name = "plustek-opticfilm-7200i";
2394     model.vendor = "PLUSTEK";
2395     model.model = "OpticFilm 7200i";
2396     model.model_id = ModelId::PLUSTEK_OPTICFILM_7200I;
2397     model.asic_type = AsicType::GL843;
2398 
2399     model.resolutions = {
2400         {
2401             { ScanMethod::TRANSPARENCY, ScanMethod::TRANSPARENCY_INFRARED },
2402             { 7200, 3600, 1800, 900 },
2403             { 7200, 3600, 1800, 900 },
2404         }
2405     };
2406 
2407     model.bpp_gray_values = { 16 };
2408     model.bpp_color_values = { 16 };
2409     model.default_method = ScanMethod::TRANSPARENCY;
2410 
2411     model.x_offset = 0.0;
2412     model.y_offset = 0.0;
2413     model.x_size = 36.0;
2414     model.y_size = 44.0;
2415 
2416     model.y_offset_calib_white = 0.0;
2417     model.y_size_calib_mm = 0.0;
2418     model.x_offset_calib_black = 6.5;
2419     model.x_size_calib_mm = 35.9834;
2420 
2421     model.x_offset_ta = 0.0;
2422     model.y_offset_ta = 29.0;
2423     model.x_size_ta = 36.0;
2424     model.y_size_ta = 24.0;
2425 
2426     model.y_offset_sensor_to_ta = 0.0;
2427     model.y_offset_calib_black_ta = 6.5;
2428     model.y_offset_calib_white_ta = 0.0;
2429     model.y_size_calib_ta_mm = 2.0;
2430 
2431     model.post_scan = 0.0;
2432     model.eject_feed = 0.0;
2433 
2434     model.ld_shift_r = 0;
2435     model.ld_shift_g = 12;
2436     model.ld_shift_b = 24;
2437 
2438     model.line_mode_color_order = ColorOrder::RGB;
2439 
2440     model.is_cis = false;
2441     model.is_sheetfed = false;
2442 
2443     model.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7200I;
2444     model.adc_id = AdcId::PLUSTEK_OPTICFILM_7200I;
2445     model.gpio_id = GpioId::PLUSTEK_OPTICFILM_7200I;
2446     model.motor_id = MotorId::PLUSTEK_OPTICFILM_7200I;
2447 
2448     model.flags = ModelFlag::WARMUP |
2449                   ModelFlag::CUSTOM_GAMMA |
2450                   ModelFlag::DARK_CALIBRATION |
2451                   ModelFlag::SHADING_REPARK |
2452                   ModelFlag::SWAP_16BIT_DATA;
2453 
2454     model.search_lines = 200;
2455     s_usb_devices->emplace_back(0x07b3, 0x0c04, model);
2456 
2457 
2458     // same as 7200i, just without the infrared channel
2459     model.name = "plustek-opticfilm-7200-v2";
2460     model.model = "OpticFilm 7200 v2";
2461     model.resolutions = {
2462         {
2463             { ScanMethod::TRANSPARENCY },
2464             { 7200, 3600, 1800, 900 },
2465             { 7200, 3600, 1800, 900 },
2466         }
2467     };
2468     s_usb_devices->emplace_back(0x07b3, 0x0c07, model);
2469 
2470 
2471     model = Genesys_Model();
2472     model.name = "plustek-opticfilm-7300";
2473     model.vendor = "PLUSTEK";
2474     model.model = "OpticFilm 7300";
2475     model.model_id = ModelId::PLUSTEK_OPTICFILM_7300;
2476     model.asic_type = AsicType::GL843;
2477 
2478     model.resolutions = {
2479         {
2480             { ScanMethod::TRANSPARENCY },
2481             { 7200, 3600, 1800, 900 },
2482             { 7200, 3600, 1800, 900 },
2483         }
2484     };
2485 
2486     model.bpp_gray_values = { 16 };
2487     model.bpp_color_values = { 16 };
2488     model.default_method = ScanMethod::TRANSPARENCY;
2489 
2490     model.x_offset = 0.0;
2491     model.y_offset = 0.0;
2492     model.x_size = 36.0;
2493     model.y_size = 44.0;
2494 
2495     model.y_offset_calib_white = 0.0;
2496     model.y_size_calib_mm = 0.0;
2497     model.x_offset_calib_black = 6.5;
2498     model.x_size_calib_mm = 35.9834;
2499 
2500     model.x_offset_ta = 0.0;
2501     model.y_offset_ta = 29.0;
2502     model.x_size_ta = 36.0;
2503     model.y_size_ta = 24.0;
2504 
2505     model.y_offset_sensor_to_ta = 0.0;
2506     model.y_offset_calib_black_ta = 6.5;
2507     model.y_offset_calib_white_ta = 0.0;
2508     model.y_size_calib_ta_mm = 2.0;
2509 
2510     model.post_scan = 0.0;
2511     model.eject_feed = 0.0;
2512 
2513     model.ld_shift_r = 0;
2514     model.ld_shift_g = 12;
2515     model.ld_shift_b = 24;
2516 
2517     model.line_mode_color_order = ColorOrder::RGB;
2518 
2519     model.is_cis = false;
2520     model.is_sheetfed = false;
2521 
2522     model.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7300;
2523     model.adc_id = AdcId::PLUSTEK_OPTICFILM_7300;
2524     model.gpio_id = GpioId::PLUSTEK_OPTICFILM_7300;
2525     model.motor_id = MotorId::PLUSTEK_OPTICFILM_7300;
2526 
2527     model.flags = ModelFlag::WARMUP |
2528                   ModelFlag::CUSTOM_GAMMA |
2529                   ModelFlag::DARK_CALIBRATION |
2530                   ModelFlag::SHADING_REPARK;
2531 
2532     model.search_lines = 200;
2533     s_usb_devices->emplace_back(0x07b3, 0x0c12, model);
2534 
2535 
2536     // same as 7300, same USB ID as 7400-v2
2537     model.name = "plustek-opticfilm-7400-v1";
2538     model.model = "OpticFilm 7400 (v1)";
2539     s_usb_devices->emplace_back(0x07b3, 0x0c3a, 0x0400, model);
2540 
2541 
2542     model = Genesys_Model();
2543     model.name = "plustek-opticfilm-7400-v2";
2544     model.vendor = "PLUSTEK";
2545     model.model = "OpticFilm 7400 (v2)";
2546     model.model_id = ModelId::PLUSTEK_OPTICFILM_7400;
2547     model.asic_type = AsicType::GL845;
2548 
2549     model.resolutions = {
2550         {
2551             { ScanMethod::TRANSPARENCY },
2552             { 7200, 3600, 2400, 1200, 600 },
2553             { 7200, 3600, 2400, 1200, 600 },
2554         }
2555     };
2556 
2557     model.bpp_gray_values = { 16 };
2558     model.bpp_color_values = { 16 };
2559     model.default_method = ScanMethod::TRANSPARENCY;
2560 
2561     model.x_offset = 0.0;
2562     model.y_offset = 0.0;
2563     model.x_size = 36.0;
2564     model.y_size = 44.0;
2565 
2566     model.y_offset_calib_white = 0.0;
2567     model.y_size_calib_mm = 0.0;
2568     model.x_offset_calib_black = 6.5;
2569     model.x_size_calib_mm = 36.83;
2570 
2571     model.x_offset_ta = 0.5;
2572     model.y_offset_ta = 29.0;
2573     model.x_size_ta = 36.33;
2574     model.y_size_ta = 25.0;
2575 
2576     model.y_offset_sensor_to_ta = 0.0;
2577     model.y_offset_calib_black_ta = 6.5;
2578     model.y_offset_calib_white_ta = 0.0;
2579     model.y_size_calib_ta_mm = 2.0;
2580 
2581     model.post_scan = 0.0;
2582     model.eject_feed = 0.0;
2583 
2584     model.ld_shift_r = 0;
2585     model.ld_shift_g = 12;
2586     model.ld_shift_b = 24;
2587 
2588     model.line_mode_color_order = ColorOrder::RGB;
2589 
2590     model.is_cis = false;
2591     model.is_sheetfed = false;
2592 
2593     model.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7400;
2594     model.adc_id = AdcId::PLUSTEK_OPTICFILM_7400;
2595     model.gpio_id = GpioId::PLUSTEK_OPTICFILM_7400;
2596     model.motor_id = MotorId::PLUSTEK_OPTICFILM_7400;
2597 
2598     model.flags = ModelFlag::CUSTOM_GAMMA |
2599                   ModelFlag::DARK_CALIBRATION |
2600                   ModelFlag::SHADING_REPARK;
2601 
2602     model.search_lines = 200;
2603     s_usb_devices->emplace_back(0x07b3, 0x0c3a, 0x0605, model);
2604 
2605 
2606     // same as 7400-v2
2607     model.name = "plustek-opticfilm-8100";
2608     model.model = "OpticFilm 8100";
2609     s_usb_devices->emplace_back(0x07b3, 0x130c, model);
2610 
2611 
2612     model = Genesys_Model();
2613     model.name = "plustek-opticfilm-7500i";
2614     model.vendor = "PLUSTEK";
2615     model.model = "OpticFilm 7500i";
2616     model.model_id = ModelId::PLUSTEK_OPTICFILM_7500I;
2617     model.asic_type = AsicType::GL843;
2618 
2619     model.resolutions = {
2620         {
2621             { ScanMethod::TRANSPARENCY, ScanMethod::TRANSPARENCY_INFRARED },
2622             { 7200, 3600, 1800, 900 },
2623             { 7200, 3600, 1800, 900 },
2624         }
2625     };
2626 
2627     model.bpp_gray_values = { 16 };
2628     model.bpp_color_values = { 16 };
2629     model.default_method = ScanMethod::TRANSPARENCY;
2630 
2631     model.x_offset = 0.0;
2632     model.y_offset = 0.0;
2633     model.x_size = 36.0;
2634     model.y_size = 44.0;
2635 
2636     model.y_offset_calib_white = 0.0;
2637     model.y_size_calib_mm = 0.0;
2638     model.x_offset_calib_black = 6.5;
2639 
2640     model.x_offset_ta = 0.0;
2641     model.y_offset_ta = 29.0;
2642     model.x_size_ta = 36.0;
2643     model.y_size_ta = 24.0;
2644     model.x_size_calib_mm = 35.9834;
2645 
2646     model.y_offset_sensor_to_ta = 0.0;
2647     model.y_offset_calib_black_ta = 6.5;
2648     model.y_offset_calib_white_ta = 0.0;
2649     model.y_size_calib_ta_mm = 2.0;
2650 
2651     model.post_scan = 0.0;
2652     model.eject_feed = 0.0;
2653 
2654     model.ld_shift_r = 0;
2655     model.ld_shift_g = 12;
2656     model.ld_shift_b = 24;
2657 
2658     model.line_mode_color_order = ColorOrder::RGB;
2659 
2660     model.is_cis = false;
2661     model.is_sheetfed = false;
2662 
2663     model.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7500I;
2664     model.adc_id = AdcId::PLUSTEK_OPTICFILM_7500I;
2665     model.gpio_id = GpioId::PLUSTEK_OPTICFILM_7500I;
2666     model.motor_id = MotorId::PLUSTEK_OPTICFILM_7500I;
2667 
2668     model.flags = ModelFlag::WARMUP |
2669                   ModelFlag::CUSTOM_GAMMA |
2670                   ModelFlag::DARK_CALIBRATION |
2671                   ModelFlag::SHADING_REPARK;
2672 
2673     model.search_lines = 200;
2674     s_usb_devices->emplace_back(0x07b3, 0x0c13, model);
2675 
2676 
2677     // same as 7500i
2678     model.name = "plustek-opticfilm-7600i-v1";
2679     model.model = "OpticFilm 7600i (v1)";
2680     s_usb_devices->emplace_back(0x07b3, 0x0c3b, 0x0400, model);
2681 
2682 
2683     model = Genesys_Model();
2684     model.name = "plustek-opticfilm-8200i";
2685     model.vendor = "PLUSTEK";
2686     model.model = "OpticFilm 8200i";
2687     model.model_id = ModelId::PLUSTEK_OPTICFILM_8200I;
2688     model.asic_type = AsicType::GL845;
2689 
2690     model.resolutions = {
2691         {
2692             { ScanMethod::TRANSPARENCY, ScanMethod::TRANSPARENCY_INFRARED },
2693             { 7200, 3600, 1800, 900 },
2694             { 7200, 3600, 1800, 900 },
2695         }
2696     };
2697 
2698     model.bpp_gray_values = { 16 };
2699     model.bpp_color_values = { 16 };
2700     model.default_method = ScanMethod::TRANSPARENCY;
2701 
2702     model.x_offset = 0.0;
2703     model.y_offset = 0.0;
2704     model.x_size = 36.0;
2705     model.y_size = 44.0;
2706 
2707     model.y_offset_calib_white = 0.0;
2708     model.y_size_calib_mm = 0.0;
2709     model.x_offset_calib_black = 6.5;
2710     model.x_size_calib_mm = 36.83;
2711 
2712     model.x_offset_ta = 0.5;
2713     model.y_offset_ta = 28.5;
2714     model.x_size_ta = 36.33;
2715     model.y_size_ta = 25.0;
2716 
2717     model.y_offset_sensor_to_ta = 0.0;
2718     model.y_offset_calib_black_ta = 6.5;
2719     model.y_offset_calib_white_ta = 0.0;
2720     model.y_size_calib_ta_mm = 2.0;
2721 
2722     model.post_scan = 0.0;
2723     model.eject_feed = 0.0;
2724 
2725     model.ld_shift_r = 0;
2726     model.ld_shift_g = 12;
2727     model.ld_shift_b = 24;
2728 
2729     model.line_mode_color_order = ColorOrder::RGB;
2730 
2731     model.is_cis = false;
2732     model.is_sheetfed = false;
2733 
2734     model.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_8200I;
2735     model.adc_id = AdcId::PLUSTEK_OPTICFILM_8200I;
2736     model.gpio_id = GpioId::PLUSTEK_OPTICFILM_8200I;
2737     model.motor_id = MotorId::PLUSTEK_OPTICFILM_8200I;
2738 
2739     model.flags = ModelFlag::CUSTOM_GAMMA |
2740                   ModelFlag::DARK_CALIBRATION |
2741                   ModelFlag::SHADING_REPARK;
2742 
2743     model.search_lines = 200;
2744     s_usb_devices->emplace_back(0x07b3, 0x130d, model);
2745 
2746 
2747     // same as 8200i
2748     model.name = "plustek-opticfilm-7600i-v2";
2749     model.model = "OpticFilm 7600i (v2)";
2750     s_usb_devices->emplace_back(0x07b3, 0x0c3b, 0x0605, model);
2751 
2752 
2753     model = Genesys_Model();
2754     model.name = "hewlett-packard-scanjet-N6310";
2755     model.vendor = "Hewlett Packard";
2756     model.model = "ScanJet N6310";
2757     model.model_id = ModelId::HP_SCANJET_N6310;
2758     model.asic_type = AsicType::GL847;
2759 
2760     model.resolutions = {
2761         {
2762             { ScanMethod::FLATBED },
2763             { 2400, 1200, 600, 400, 300, 200, 150, 100, 75 },
2764             { 2400, 1200, 600, 400, 300, 200, 150, 100, 75 },
2765         }
2766     };
2767 
2768     model.bpp_gray_values = { 8, 16 };
2769     model.bpp_color_values = { 8, 16 };
2770 
2771     model.x_offset = 6;
2772     model.y_offset = 2;
2773     model.x_size = 216;
2774     model.y_size = 511;
2775 
2776     model.y_offset_calib_white = 0.0;
2777     model.y_size_calib_mm = 4.0; // FIXME: y_offset is liely incorrect
2778     model.x_offset_calib_black = 0.0;
2779     model.x_size_calib_mm = 452.12;
2780 
2781     model.post_scan = 0;
2782     model.eject_feed = 0;
2783 
2784     model.ld_shift_r = 0;
2785     model.ld_shift_g = 0;
2786     model.ld_shift_b = 0;
2787 
2788     model.line_mode_color_order = ColorOrder::RGB;
2789 
2790     model.is_cis = false;
2791     model.is_sheetfed = false;
2792     model.sensor_id = SensorId::CCD_HP_N6310;
2793     model.adc_id = AdcId::CANON_LIDE_200;        // Not defined yet for N6310
2794     model.gpio_id = GpioId::HP_N6310;
2795     model.motor_id = MotorId::CANON_LIDE_200;    // Not defined yet for N6310
2796     model.flags = ModelFlag::UNTESTED |
2797                   ModelFlag::GAMMA_14BIT |
2798                   ModelFlag::DARK_CALIBRATION |
2799                   ModelFlag::CUSTOM_GAMMA |
2800                   ModelFlag::DISABLE_ADC_CALIBRATION |
2801                   ModelFlag::DISABLE_EXPOSURE_CALIBRATION |
2802                   ModelFlag::DISABLE_SHADING_CALIBRATION;
2803 
2804     model.buttons = GENESYS_HAS_NO_BUTTONS;
2805     model.search_lines = 100;
2806 
2807     s_usb_devices->emplace_back(0x03f0, 0x4705, model);
2808 
2809 
2810     model = Genesys_Model();
2811     model.name = "plustek-opticbook-3800";
2812     model.vendor = "PLUSTEK";
2813     model.model = "OpticBook 3800";
2814     model.model_id = ModelId::PLUSTEK_OPTICBOOK_3800;
2815     model.asic_type = AsicType::GL845;
2816 
2817     model.resolutions = {
2818         {
2819             { ScanMethod::FLATBED },
2820             { 1200, 600, 300, 150, 100, 75 },
2821             { 1200, 600, 300, 150, 100, 75 },
2822         }
2823     };
2824 
2825     model.bpp_gray_values = { 8, 16 };
2826     model.bpp_color_values = { 8, 16 };
2827 
2828     model.x_offset = 7.2;
2829     model.y_offset = 14.7;
2830     model.x_size = 217.7;
2831     model.y_size = 300.0;
2832 
2833     model.y_offset_calib_white = 9.0;
2834     model.y_size_calib_mm = 4.0;
2835     model.x_offset_calib_black = 0.0;
2836     model.x_size_calib_mm = 215.9;
2837 
2838     model.post_scan = 0.0;
2839     model.eject_feed = 0.0;
2840 
2841     model.ld_shift_r = 0;
2842     model.ld_shift_g = 24;
2843     model.ld_shift_b = 48;
2844 
2845     model.line_mode_color_order = ColorOrder::RGB;
2846 
2847     model.is_cis = false;
2848     model.is_sheetfed = false;
2849     model.sensor_id = SensorId::CCD_PLUSTEK_OPTICBOOK_3800;
2850     model.adc_id = AdcId::PLUSTEK_OPTICBOOK_3800;
2851     model.gpio_id = GpioId::PLUSTEK_OPTICBOOK_3800;
2852     model.motor_id = MotorId::PLUSTEK_OPTICBOOK_3800;
2853     model.flags = ModelFlag::CUSTOM_GAMMA;
2854     model.buttons = GENESYS_HAS_NO_BUTTONS;  // TODO there are 4 buttons to support
2855     model.search_lines = 100;
2856 
2857     s_usb_devices->emplace_back(0x07b3, 0x1300, model);
2858 
2859 
2860     model = Genesys_Model();
2861     model.name = "canon-image-formula-101";
2862     model.vendor = "Canon";
2863     model.model = "Image Formula 101";
2864     model.model_id = ModelId::CANON_IMAGE_FORMULA_101;
2865     model.asic_type = AsicType::GL846;
2866 
2867     model.resolutions = {
2868         {
2869             { ScanMethod::FLATBED },
2870             { 1200, 600, 300, 150, 100, 75 },
2871             { 1200, 600, 300, 150, 100, 75 },
2872         }
2873     };
2874 
2875     model.bpp_gray_values = { 8, 16 };
2876     model.bpp_color_values = { 8, 16 };
2877 
2878     model.x_offset = 7.2;
2879     model.y_offset = 14.7;
2880     model.x_size = 217.7;
2881     model.y_size = 300.0;
2882 
2883     model.y_offset_calib_white = 9.0;
2884     model.y_size_calib_mm = 4.0;
2885     model.x_offset_calib_black = 0.0;
2886     model.x_size_calib_mm = 228.6;
2887 
2888     model.post_scan = 0.0;
2889     model.eject_feed = 0.0;
2890 
2891     model.ld_shift_r = 0;
2892     model.ld_shift_g = 24;
2893     model.ld_shift_b = 48;
2894 
2895     model.line_mode_color_order = ColorOrder::RGB;
2896 
2897     model.is_cis = false;
2898     model.is_sheetfed = false;
2899     model.sensor_id = SensorId::CCD_IMG101;
2900     model.adc_id = AdcId::IMG101;
2901     model.gpio_id = GpioId::IMG101;
2902     model.motor_id = MotorId::IMG101;
2903     model.flags = ModelFlag::CUSTOM_GAMMA |
2904                   ModelFlag::UNTESTED;
2905     model.buttons = GENESYS_HAS_NO_BUTTONS ;
2906     model.search_lines = 100;
2907 
2908     s_usb_devices->emplace_back(0x1083, 0x162e, model);
2909 }
2910 
verify_usb_device_tables()2911 void verify_usb_device_tables()
2912 {
2913     for (const auto& device : *s_usb_devices) {
2914         const auto& model = device.model();
2915 
2916         if (model.x_size_calib_mm == 0.0f) {
2917             throw SaneException("Calibration width can't be zero");
2918         }
2919 
2920         if (model.has_method(ScanMethod::FLATBED)) {
2921             if (model.y_size_calib_mm == 0.0f) {
2922                 throw SaneException("Calibration size can't be zero");
2923             }
2924         }
2925         if (model.has_method(ScanMethod::TRANSPARENCY) ||
2926             model.has_method(ScanMethod::TRANSPARENCY_INFRARED))
2927         {
2928             if (model.y_size_calib_ta_mm == 0.0f) {
2929                 throw SaneException("Calibration size can't be zero");
2930             }
2931         }
2932     }
2933 }
2934 
2935 } // namespace genesys
2936