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