1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdint.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include <windows.h>
8 #include <wia.h>
9 #include <Sti.h>
10
11 #include <Python.h>
12
13 #include "properties.h"
14 #include "trace.h"
15 #include "util.h"
16
17 static const struct wia_prop_int g_possible_connect_status[] = {
18 { WIA_DEVICE_NOT_CONNECTED, "not_connected" },
19 { WIA_DEVICE_CONNECTED, "connected" },
20 { -1, NULL, },
21 };
22
23 static const struct wia_prop_int g_possible_access_rights[] = {
24 { WIA_ITEM_READ, "read" },
25 { WIA_ITEM_WRITE, "write" },
26 { WIA_ITEM_CAN_BE_DELETED, "can_be_deleted" },
27 { WIA_ITEM_RD, "read_can_be_deleted" },
28 { WIA_ITEM_RWD, "read_write_can_be_deleted" },
29 { -1, NULL, }
30 };
31
32 static const struct wia_prop_int g_possible_compression[] = {
33 { WIA_COMPRESSION_NONE, "none", },
34 { 100 /* WIA_COMPRESSION_AUTO ; Visual C++ 2010 doesn't know this value */, "auto", },
35 { WIA_COMPRESSION_BI_RLE4, "bi_rle4", },
36 { WIA_COMPRESSION_BI_RLE8, "bi_rle8", },
37 { WIA_COMPRESSION_G3, "g3", },
38 { WIA_COMPRESSION_G4, "g4", },
39 { WIA_COMPRESSION_JPEG, "jpeg", },
40 { WIA_COMPRESSION_JBIG, "jbig", },
41 { WIA_COMPRESSION_JPEG2K, "jpeg2k", },
42 { WIA_COMPRESSION_PNG, "png", },
43 { -1, NULL, },
44 };
45
46 static const struct wia_prop_int g_possible_datatype[] = {
47 { 100 /* WIA_DATA_AUTO ; Visual C++ 2010 doesn't know this value */, "auto", },
48 { WIA_DATA_COLOR, "color", },
49 { WIA_DATA_COLOR_DITHER, "color_dither", },
50 { WIA_DATA_COLOR_THRESHOLD, "color_threshold", },
51 { WIA_DATA_DITHER, "dither", },
52 { WIA_DATA_GRAYSCALE, "grayscale", },
53 { WIA_DATA_THRESHOLD, "threshold", },
54 { WIA_DATA_RAW_BGR, "raw_bgr", },
55 { WIA_DATA_RAW_CMY, "raw_cmy", },
56 { WIA_DATA_RAW_CMYK, "raw_cmyk", },
57 { WIA_DATA_RAW_RGB, "raw_rgb", },
58 { WIA_DATA_RAW_YUV, "raw_yuv", },
59 { WIA_DATA_RAW_YUVK, "raw_yuvk", },
60 { -1, NULL, },
61 };
62
63 static const struct wia_prop_clsid g_possible_format[] = {
64 { WiaImgFmt_BMP, "bmp", },
65 { WiaImgFmt_CIFF, "ciff", },
66 { WiaImgFmt_EXIF, "exif", },
67 { WiaImgFmt_FLASHPIX, "flashpix", },
68 { WiaImgFmt_GIF, "gif", },
69 { WiaImgFmt_ICO, "ico", },
70 { WiaImgFmt_JBIG, "jbig", },
71 { WiaImgFmt_JPEG, "jpeg", },
72 { WiaImgFmt_JPEG2K, "jpeg2k", },
73 { WiaImgFmt_JPEG2KX, "jpeg2kx", },
74 { WiaImgFmt_MEMORYBMP, "memorybmp", },
75 { WiaImgFmt_PDFA, "pdfa", },
76 { WiaImgFmt_PHOTOCD, "photocd", },
77 { WiaImgFmt_PICT, "pict", },
78 { WiaImgFmt_PNG, "png", },
79 { WiaImgFmt_RAW, "raw", },
80 { WiaImgFmt_RAWRGB, "rawrgb", },
81 { WiaImgFmt_TIFF, "tiff", },
82 { NULL, NULL, },
83 };
84
85 static const struct wia_prop_clsid g_possible_item_category[] = {
86 { WIA_CATEGORY_ROOT, "root", },
87 { WIA_CATEGORY_FLATBED, "flatbed", },
88 { WIA_CATEGORY_FEEDER, "feeder", },
89 { WIA_CATEGORY_FEEDER_FRONT, "feeder_front", },
90 { WIA_CATEGORY_FEEDER_BACK, "feeder_back", },
91 { WIA_CATEGORY_FILM, "film", },
92 { WIA_CATEGORY_FOLDER, "folder", },
93 { WIA_CATEGORY_FINISHED_FILE, "finished_file", },
94 { NULL, NULL, },
95 };
96
97 static const struct wia_prop_int g_possible_item_flags[] = {
98 { WiaItemTypeAnalyze, "analyze", },
99 { WiaItemTypeAudio, "audio", },
100 { WiaItemTypeBurst, "burst", },
101 { WiaItemTypeDeleted, "deleted", },
102 { WiaItemTypeDocument, "document", },
103 { WiaItemTypeDevice, "device", },
104 { WiaItemTypeDisconnected, "disconnected", },
105 { WiaItemTypeFile, "file", },
106 { WiaItemTypeFolder, "folder", },
107 { WiaItemTypeFree, "free", },
108 { WiaItemTypeGenerated, "generated", },
109 { WiaItemTypeHasAttachments, "has_attachments", },
110 { WiaItemTypeHPanorama, "hpanorama", },
111 { WiaItemTypeImage, "image", },
112 { WiaItemTypeProgrammableDataSource, "programmable_data_source", },
113 { WiaItemTypeRoot, "root", },
114 { WiaItemTypeStorage, "storage", },
115 { WiaItemTypeTransfer, "transfer", },
116 // WiaItemTypeTwainCapabilityPassThrough, // Jflesch> Doesn't exist ?
117 { WiaItemTypeVideo, "video", },
118 { WiaItemTypeVPanorama, "vpanorama", },
119 { -1, NULL },
120 };
121
122 static const struct wia_prop_int g_possible_planar[] = {
123 { WIA_PACKED_PIXEL, "pixel" },
124 { WIA_PLANAR, "planar" },
125 { -1, NULL, },
126 };
127
128 static const struct wia_prop_int g_possible_suppress_property_page[] = {
129 { WIA_PROPPAGE_CAMERA_ITEM_GENERAL, "camera_item_general", },
130 { WIA_PROPPAGE_SCANNER_ITEM_GENERAL, "scanner_item_general", },
131 { -1, NULL, },
132 };
133
134 static const struct wia_prop_int g_possible_tymed[] = {
135 { TYMED_CALLBACK, "callback", },
136 { TYMED_MULTIPAGE_CALLBACK, "multipage_callback", },
137 { TYMED_FILE, "file", },
138 { TYMED_MULTIPAGE_FILE, "multipage_file", },
139 { -1, NULL, },
140 };
141
142 static const struct wia_prop_int g_possible_dev_type[] = {
143 { StiDeviceTypeDefault, "default", },
144 { StiDeviceTypeScanner, "scanner", },
145 { StiDeviceTypeDigitalCamera, "digital_camera", },
146 { StiDeviceTypeStreamingVideo, "streaming_video", },
147 { -1, NULL, },
148 };
149
150 static const struct wia_prop_int g_possible_hw_config[] = {
151 { 1, "generic", }, // Generic WDM device
152 { 2, "scsi", }, // SCSI device
153 { 4, "usb", }, // USB device
154 { 8, "serial", }, // Serial device
155 { 16, "parallel", }, // Parallel device
156 { -1, NULL, },
157 };
158
159 static const struct wia_prop_int g_possible_document_handling_capabilities[] = {
160 { AUTO_SOURCE, "auto_source", },
161 { ADVANCED_DUP, "dup", },
162 { DETECT_FILM_TPA, "detect_film_tpa", },
163 { DETECT_STOR, "detect_stor", },
164 { FILM_TPA, "film_tpa", },
165 { STOR, "stor", },
166 { DETECT_FEED, "detect_feed", },
167 { DETECT_FLAT, "detect_flat", },
168 { DETECT_SCAN, "detect_scan", },
169 { DUP, "dup", },
170 { FEED, "feed", },
171 { FLAT, "flat", },
172 { DETECT_DUP, "detect_dup", },
173 { DETECT_DUP_AVAIL, "detect_dup_avail", },
174 { DETECT_FEED_AVAIL, "detect_feed_avail", },
175 { -1, NULL, },
176 };
177
178 static const struct wia_prop_int g_possible_document_handling_select[] = {
179 { FEEDER, "feeder", },
180 { FLATBED, "flatbed", },
181 { DUPLEX, "duplex", },
182 { AUTO_ADVANCE, "auto_advance", },
183 { FRONT_FIRST, "front_first", },
184 { BACK_FIRST, "back_first", },
185 { FRONT_ONLY, "front_only", },
186 { BACK_ONLY, "back_only", },
187 { NEXT_PAGE, "next_page", },
188 { PREFEED, "prefeed", },
189 { -1, NULL, },
190 };
191
192 static const struct wia_prop_int g_possible_document_handling_status[] = {
193 { FEED_READY, "feed_ready", },
194 { FLAT_READY, "flat_ready", },
195 { DUP_READY, "dup_ready", },
196 { FLAT_COVER_UP, "flat_cover_up", },
197 { PATH_COVER_UP, "path_cover_up", },
198 { PAPER_JAM, "paper_jam", },
199 { FILM_TPA_READY, "film_tpa_ready", },
200 { STORAGE_READY, "storage_ready", },
201 { STORAGE_FULL, "storage_full", },
202 { MULTIPLE_FEED, "multiple_feed", },
203 { DEVICE_ATTENTION, "device_attention", },
204 { LAMP_ERR, "lamp_err", },
205 { -1, NULL, },
206 };
207
208 static const struct wia_prop_int g_possible_horizontal_bed_registration[] = {
209 { LEFT_JUSTIFIED, "left_justified", },
210 { CENTERED, "centered", },
211 { RIGHT_JUSTIFIED, "right_justified", },
212 { -1, NULL, },
213 };
214
215 static const struct wia_prop_int g_possible_orientation[] = {
216 { LANDSCAPE, "landscape", },
217 { PORTRAIT, "portrait", },
218 { ROT180, "rot180", },
219 { ROT270, "rot270", },
220 { -1, NULL },
221 };
222
223 static const struct wia_prop_int g_possible_page_size[] = {
224 { WIA_PAGE_A4, "a4", },
225 { WIA_PAGE_CUSTOM, "custom", }, // see WIA_DPS_PAGE_HEIGHT and WIA_DPS_PAGE_WIDTH
226 { WIA_PAGE_LETTER, "letter", },
227 { WIA_PAGE_USLEGAL, "uslegal", },
228 { WIA_PAGE_USLETTER, "usletter", },
229 { WIA_PAGE_USLEDGER, "usledger", },
230 { WIA_PAGE_USSTATEMENT, "usstatement", },
231 { WIA_PAGE_BUSINESSCARD, "businesscard", },
232 { WIA_PAGE_ISO_A0, "iso_a0", },
233 { WIA_PAGE_ISO_A1, "iso_a1", },
234 { WIA_PAGE_ISO_A2, "iso_a2", },
235 { WIA_PAGE_ISO_A3, "iso_a3", },
236 { WIA_PAGE_ISO_A4, "iso_a4", },
237 { WIA_PAGE_ISO_A5, "iso_a5", },
238 { WIA_PAGE_ISO_A6, "iso_a6", },
239 { WIA_PAGE_ISO_A7, "iso_a7", },
240 { WIA_PAGE_ISO_A8, "iso_a8", },
241 { WIA_PAGE_ISO_A9, "iso_a9", },
242 { WIA_PAGE_ISO_A10, "iso_a10", },
243 { WIA_PAGE_ISO_B0, "iso_b0", },
244 { WIA_PAGE_ISO_B1, "iso_b1", },
245 { WIA_PAGE_ISO_B2, "iso_b2", },
246 { WIA_PAGE_ISO_B3, "iso_b3", },
247 { WIA_PAGE_ISO_B4, "iso_b4", },
248 { WIA_PAGE_ISO_B5, "iso_b5", },
249 { WIA_PAGE_ISO_B6, "iso_b6", },
250 { WIA_PAGE_ISO_B7, "iso_b7", },
251 { WIA_PAGE_ISO_B8, "iso_b8", },
252 { WIA_PAGE_ISO_B9, "iso_b9", },
253 { WIA_PAGE_ISO_B10, "iso_b10", },
254 { WIA_PAGE_ISO_C0, "iso_c0", },
255 { WIA_PAGE_ISO_C1, "iso_c1", },
256 { WIA_PAGE_ISO_C2, "iso_c2", },
257 { WIA_PAGE_ISO_C3, "iso_c3", },
258 { WIA_PAGE_ISO_C4, "iso_c4", },
259 { WIA_PAGE_ISO_C5, "iso_c5", },
260 { WIA_PAGE_ISO_C6, "iso_c6", },
261 { WIA_PAGE_ISO_C7, "iso_c7", },
262 { WIA_PAGE_ISO_C8, "iso_c8", },
263 { WIA_PAGE_ISO_C9, "iso_c9", },
264 { WIA_PAGE_ISO_C10, "iso_c10", },
265 { WIA_PAGE_JIS_B0, "jis_b0", },
266 { WIA_PAGE_JIS_B1, "jis_b1", },
267 { WIA_PAGE_JIS_B2, "jis_b2", },
268 { WIA_PAGE_JIS_B3, "jis_b3", },
269 { WIA_PAGE_JIS_B4, "jis_b4", },
270 { WIA_PAGE_JIS_B5, "jis_b5", },
271 { WIA_PAGE_JIS_B6, "jis_b6", },
272 { WIA_PAGE_JIS_B7, "jis_b7", },
273 { WIA_PAGE_JIS_B8, "jis_b8", },
274 { WIA_PAGE_JIS_B9, "jis_b9", },
275 { WIA_PAGE_JIS_B10, "jis_b10", },
276 { WIA_PAGE_JIS_2A, "jis_2a", },
277 { WIA_PAGE_JIS_4A, "jis_4a", },
278 { WIA_PAGE_DIN_2B, "din_2b", },
279 { WIA_PAGE_DIN_4B, "din_4b", },
280 { WIA_PAGE_AUTO, "auto", },
281 { WIA_PAGE_CUSTOM_BASE, "custom_base", },
282 { -1, NULL, },
283 };
284
285 static const struct wia_prop_int g_possible_preview[] = {
286 { WIA_FINAL_SCAN, "final_scan", },
287 { WIA_PREVIEW_SCAN, "preview_scan", },
288 { -1, NULL, },
289 };
290
291 static const struct wia_prop_int g_possible_sheet_feeder_registration[] = {
292 { LEFT_JUSTIFIED, "left_justified", },
293 { CENTERED, "centered", },
294 { RIGHT_JUSTIFIED, "right_justified", },
295 { -1, NULL },
296 };
297
298 static const struct wia_prop_int g_possible_show_preview_control[] = {
299 { WIA_SHOW_PREVIEW_CONTROL, "show_preview_control", },
300 { WIA_DONT_SHOW_PREVIEW_CONTROL, "dont_show_preview_control", },
301 { -1, NULL, },
302 };
303
304 static const struct wia_prop_int g_possible_vertical_bed_registration[] = {
305 { TOP_JUSTIFIED, "top_justified", },
306 { CENTERED, "centered", },
307 { BOTTOM_JUSTIFIED, "bottom_justified", },
308 { -1, NULL, },
309 };
310
311 static const struct wia_prop_int g_possible_auto_deskew[] = {
312 { WIA_AUTO_DESKEW_ON, "deskew_on", },
313 { WIA_AUTO_DESKEW_OFF, "deskew_off", },
314 { -1, NULL, },
315 };
316
317 static const struct wia_prop_int g_possible_intent[] = {
318 { WIA_INTENT_NONE, "none", },
319 { WIA_INTENT_IMAGE_TYPE_COLOR, "image_type_color", },
320 { WIA_INTENT_IMAGE_TYPE_GRAYSCALE, "image_type_grayscale", },
321 { WIA_INTENT_IMAGE_TYPE_TEXT, "image_type_text", },
322 { WIA_INTENT_IMAGE_TYPE_MASK, "image_type_mask", },
323 { WIA_INTENT_MINIMIZE_SIZE, "minimize_size", },
324 { WIA_INTENT_MAXIMIZE_QUALITY, "maximize_quality", },
325 { WIA_INTENT_SIZE_MASK, "size_mask", },
326 { WIA_INTENT_BEST_PREVIEW, "best_preview", },
327 { -1, NULL, },
328 };
329
330 static const struct wia_prop_int g_possible_film_scan_mode[] = {
331 { WIA_FILM_COLOR_SLIDE, "color_slide", },
332 { WIA_FILM_COLOR_NEGATIVE, "color_negative", },
333 { WIA_FILM_BW_NEGATIVE, "bw_negative", },
334 { -1, NULL, },
335 };
336
337 static const struct wia_prop_int g_possible_lamp[] = {
338 { WIA_LAMP_ON, "on", },
339 { WIA_LAMP_OFF, "off", },
340 { -1, NULL, },
341 };
342
343 static const struct wia_prop_int g_possible_photometric_interp[] = {
344 { WIA_PHOTO_WHITE_0, "white_0", }, // WHITE is 0, and BLACK is 1
345 { WIA_PHOTO_WHITE_1, "white_1", }, // WHITE is 1, and BLACK is 0
346 { -1, NULL, },
347 };
348
349 static const struct wia_prop_int g_possible_preview_type[] = {
350 { WIA_ADVANCED_PREVIEW, "advanced", },
351 { WIA_BASIC_PREVIEW, "basic", },
352 { -1, NULL, },
353 };
354
355 static const struct wia_prop_int g_possible_rotation[] = {
356 { PORTRAIT, "portrait", },
357 { LANDSCAPE, "landscape", },
358 { ROT180, "rot180", },
359 { ROT270, "rot270", },
360 { -1, NULL, },
361 };
362
363 static const struct wia_prop_int g_possible_segmentation[] = {
364 { WIA_USE_SEGMENTATION_FILTER, "true", },
365 { WIA_DONT_USE_SEGMENTATION_FILTER, "false", },
366 { -1, NULL, },
367 };
368
369 static PyObject *get_possible_values_int(const struct wia_property*);
370 static PyObject *get_possible_values_clsid(const struct wia_property*);
371 static PyObject *get_possible_values_none(const struct wia_property*);
372
373 static const struct wia_property _g_wia_all_properties[] =
374 {
375 {
376 WIA_DPA_CONNECT_STATUS, VT_I4, "connect_status", 0, g_possible_connect_status, get_possible_values_int,
377 },
378 {
379 WIA_DPA_DEVICE_TIME, VT_VECTOR | VT_UI2, "device_time", 0, NULL, get_possible_values_none,
380 },
381 {
382 WIA_DPA_FIRMWARE_VERSION, VT_BSTR, "firmware_version", 0, NULL, get_possible_values_none,
383 },
384 {
385 WIA_IPA_ACCESS_RIGHTS, VT_I4, "access_rights", 1, g_possible_access_rights, get_possible_values_int,
386 },
387 {
388 WIA_IPA_BITS_PER_CHANNEL, VT_I4, "bits_per_channel", 0, NULL, get_possible_values_none,
389 },
390 {
391 WIA_IPA_BUFFER_SIZE, VT_I4, "buffer_size", 0, NULL, get_possible_values_none,
392 },
393 {
394 WIA_IPA_BYTES_PER_LINE, VT_I4, "bytes_per_line", 0, NULL, get_possible_values_none,
395 },
396 {
397 WIA_IPA_CHANNELS_PER_PIXEL, VT_I4, "channels_per_pixel", 0, NULL, get_possible_values_none,
398 },
399 {
400 WIA_IPA_COLOR_PROFILE, VT_I4, "color_profile", 0, NULL, get_possible_values_none,
401 },
402 {
403 WIA_IPA_COMPRESSION, VT_I4, "compression", 1, g_possible_compression, get_possible_values_int,
404 },
405 {
406 WIA_IPA_DATATYPE, VT_I4, "datatype", 1, g_possible_datatype, get_possible_values_int,
407 },
408 {
409 WIA_IPA_DEPTH, VT_I4, "depth", 1, NULL, get_possible_values_none,
410 },
411 {
412 WIA_IPA_FILENAME_EXTENSION, VT_BSTR, "filename_extension", 0, NULL, get_possible_values_none,
413 },
414 {
415 WIA_IPA_FORMAT, VT_CLSID, "format", 1, g_possible_format, get_possible_values_clsid,
416 },
417 {
418 WIA_IPA_FULL_ITEM_NAME, VT_BSTR, "full_item_name", 0, NULL, get_possible_values_none,
419 },
420 {
421 WIA_IPA_GAMMA_CURVES, VT_I4, "gamma_curves", 0, NULL, get_possible_values_none,
422 },
423 {
424 WIA_IPA_ICM_PROFILE_NAME, VT_BSTR, "icm_profile_name", 0, NULL, get_possible_values_none,
425 },
426 {
427 WIA_IPA_ITEM_CATEGORY, VT_CLSID, "item_category", 0, g_possible_item_category, get_possible_values_clsid,
428 },
429 {
430 WIA_IPA_ITEM_FLAGS, VT_I4, "item_flags", 0, g_possible_item_flags, get_possible_values_int,
431 },
432 {
433 WIA_IPA_ITEM_NAME, VT_BSTR, "item_name", 0, NULL, get_possible_values_none,
434 },
435 {
436 WIA_IPA_ITEM_SIZE, VT_I4, "item_size", 0, NULL, get_possible_values_none,
437 },
438 {
439 WIA_IPA_ITEM_TIME, VT_UI2 | VT_VECTOR, "item_time", 1, NULL, get_possible_values_none,
440 },
441 {
442 WIA_IPA_ITEMS_STORED, VT_I4, "items_stored", 1, NULL, get_possible_values_none,
443 },
444 {
445 WIA_IPA_MIN_BUFFER_SIZE, VT_I4, "buffer_size", 0, NULL, get_possible_values_none,
446 },
447 {
448 WIA_IPA_NUMBER_OF_LINES, VT_I4, "number_of_lines", 0, NULL, get_possible_values_none,
449 },
450 {
451 WIA_IPA_PIXELS_PER_LINE, VT_I4, "pixels_per_line", 0, NULL, get_possible_values_none,
452 },
453 {
454 WIA_IPA_PLANAR, VT_I4, "planar", 1, g_possible_planar, get_possible_values_int,
455 },
456 {
457 WIA_IPA_PREFERRED_FORMAT, VT_CLSID, "preferred_format", 0, g_possible_format, get_possible_values_clsid,
458 },
459 {
460 WIA_IPA_PROP_STREAM_COMPAT_ID, VT_CLSID, "prop_stream_compat_id", 0, NULL, get_possible_values_clsid,
461 },
462 {
463 WIA_IPA_RAW_BITS_PER_CHANNEL, VT_UI1 | VT_VECTOR, "raw_bits_per_channel", 0, NULL, get_possible_values_none,
464 },
465 {
466 WIA_IPA_REGION_TYPE, VT_I4, "region_type", 0, NULL, get_possible_values_none,
467 },
468 {
469 WIA_IPA_SUPPRESS_PROPERTY_PAGE, VT_I4, "suppress_property_page", 0, g_possible_suppress_property_page,
470 get_possible_values_int,
471 },
472 {
473 WIA_IPA_TYMED, VT_I4, "tymed", 1, g_possible_tymed, get_possible_values_int,
474 },
475 {
476 WIA_IPA_UPLOAD_ITEM_SIZE, VT_I4, "upload_item_size", 1, NULL, get_possible_values_none,
477 },
478 {
479 WIA_DIP_DEV_ID, VT_BSTR, "dev_id", 0, NULL, get_possible_values_none,
480 },
481 {
482 WIA_DIP_VEND_DESC, VT_BSTR, "vend_desc", 0, NULL, get_possible_values_none,
483 },
484 {
485 WIA_DIP_DEV_DESC, VT_BSTR, "dev_desc", 0, NULL, get_possible_values_none,
486 },
487 {
488 WIA_DIP_DEV_TYPE, VT_I4, "dev_type", 0, g_possible_dev_type, get_possible_values_int,
489 },
490 {
491 WIA_DIP_PORT_NAME, VT_BSTR, "port_name", 0, NULL, get_possible_values_none,
492 },
493 {
494 WIA_DIP_DEV_NAME, VT_BSTR, "dev_name", 0, NULL, get_possible_values_none,
495 },
496 {
497 WIA_DIP_SERVER_NAME, VT_BSTR, "server_name", 0, NULL, get_possible_values_none,
498 },
499 {
500 WIA_DIP_REMOTE_DEV_ID, VT_BSTR, "remote_dev_id", 0, NULL, get_possible_values_none,
501 },
502 {
503 WIA_DIP_UI_CLSID, VT_BSTR, "ui_clsid", 0, NULL, get_possible_values_none,
504 },
505 {
506 WIA_DIP_HW_CONFIG, VT_I4, "hw_config", 0, g_possible_hw_config, get_possible_values_int,
507 },
508 {
509 WIA_DIP_BAUDRATE, VT_BSTR, "baudrate", 0, NULL, get_possible_values_none,
510 },
511 {
512 WIA_DIP_STI_GEN_CAPABILITIES, VT_I4, "sti_gen_capabilities", 0, NULL, get_possible_values_none,
513 },
514 {
515 WIA_DIP_WIA_VERSION, VT_BSTR, "wia_version", 0, NULL, get_possible_values_none,
516 },
517 {
518 WIA_DIP_DRIVER_VERSION, VT_BSTR, "driver_version", 0, NULL, get_possible_values_none,
519 },
520 {
521 WIA_DIP_PNP_ID, VT_BSTR, "pnp_id", 0, NULL, get_possible_values_none,
522 },
523 {
524 WIA_DIP_STI_DRIVER_VERSION, VT_BSTR, "sti_driver_version", 0, NULL, get_possible_values_none,
525 },
526 {
527 WIA_DPS_DEVICE_ID, VT_BSTR, "device_id", 0, NULL, get_possible_values_none,
528 },
529 {
530 WIA_DPS_DOCUMENT_HANDLING_CAPABILITIES, VT_I4,
531 "document_handling_capabilities", 0, g_possible_document_handling_capabilities,
532 get_possible_values_int,
533 },
534 {
535 WIA_DPS_DOCUMENT_HANDLING_SELECT, VT_I4, "document_handling_select", 1, g_possible_document_handling_select,
536 get_possible_values_int,
537 },
538 {
539 WIA_DPS_DOCUMENT_HANDLING_STATUS, VT_I4, "document_handling_status", 0, g_possible_document_handling_status,
540 get_possible_values_int,
541 },
542 {
543 WIA_DPS_ENDORSER_CHARACTERS, VT_BSTR, "endorser_characters", 0, NULL, get_possible_values_none,
544 },
545 {
546 WIA_DPS_ENDORSER_STRING, VT_BSTR, "endorser_string", 1, NULL, get_possible_values_none,
547 },
548 {
549 WIA_DPS_GLOBAL_IDENTITY, VT_BSTR, "global_identity", 0, NULL, get_possible_values_none,
550 },
551 {
552 WIA_DPS_HORIZONTAL_BED_REGISTRATION, VT_I4,
553 "horizontal_bed_registration", 0, g_possible_horizontal_bed_registration,
554 get_possible_values_int,
555 },
556 {
557 WIA_DPS_HORIZONTAL_BED_SIZE, VT_I4, "horizontal_bed_size", 0, NULL, get_possible_values_none,
558 },
559 {
560 WIA_DPS_HORIZONTAL_SHEET_FEED_SIZE, VT_I4, "horizontal_sheet_feed_size", 0, NULL, get_possible_values_none,
561 },
562 {
563 WIA_DPS_MAX_SCAN_TIME, VT_I4, "max_scan_time", 0, NULL, get_possible_values_none,
564 },
565 {
566 WIA_DPS_MIN_HORIZONTAL_SHEET_FEED_SIZE, VT_I4, "min_horizontal_sheet_feed_size", 0, NULL,
567 get_possible_values_none,
568 },
569 {
570 WIA_DPS_MIN_VERTICAL_SHEET_FEED_SIZE, VT_I4, "min_vertical_sheet_feed_size", 0, NULL, get_possible_values_none,
571 },
572 {
573 WIA_DPS_OPTICAL_XRES, VT_I4, "optical_xres", 0, NULL, get_possible_values_none,
574 },
575 {
576 WIA_DPS_OPTICAL_YRES, VT_I4, "optical_yres", 0, NULL, get_possible_values_none,
577 },
578 // TODO(JFlesch): Visual C++ says WIA_DPS_ORIENTATION doesn't exist ?!
579 //{
580 // WIA_DPS_ORIENTATION, VT_I4, "orientation", 1, g_possible_orientation, get_possible_values_int,
581 //},
582 {
583 WIA_DPS_PAD_COLOR, VT_UI1 | VT_VECTOR, "pad_color", 0, NULL, get_possible_values_none,
584 },
585 {
586 WIA_DPS_PAGE_HEIGHT, VT_I4, "page_height", 0, NULL, get_possible_values_none,
587 },
588 {
589 WIA_DPS_PAGE_SIZE, VT_I4, "page_size", 1, g_possible_page_size, get_possible_values_int,
590 },
591 {
592 WIA_DPS_PAGE_WIDTH, VT_I4, "page_width", 0, NULL, get_possible_values_none,
593 },
594 {
595 WIA_DPS_PAGES, VT_I4, "pages", 1, NULL, get_possible_values_none,
596 },
597 {
598 WIA_DPS_PLATEN_COLOR, VT_UI1 | VT_VECTOR, "platen_color", 0, NULL, get_possible_values_none,
599 },
600 {
601 WIA_DPS_PREVIEW, VT_I4, "preview", 1, g_possible_preview, get_possible_values_int,
602 },
603 {
604 WIA_DPS_SCAN_AHEAD_PAGES, VT_I4, "scan_ahead_pages", 1, NULL, get_possible_values_none,
605 },
606 {
607 WIA_DPS_SCAN_AVAILABLE_ITEM, VT_I4, "scan_available_item", 1, NULL, get_possible_values_none,
608 },
609 {
610 WIA_DPS_SERVICE_ID, VT_BSTR, "service_id", 0, NULL, get_possible_values_none,
611 },
612 {
613 WIA_DPS_SHEET_FEEDER_REGISTRATION, VT_I4,
614 "sheet_feeder_registration", 0, g_possible_sheet_feeder_registration,
615 get_possible_values_int,
616 },
617 {
618 WIA_DPS_SHOW_PREVIEW_CONTROL, VT_I4, "show_preview_control", 0, g_possible_show_preview_control,
619 get_possible_values_int,
620 },
621 {
622 WIA_DPS_USER_NAME, VT_BSTR, "user_name", 0, NULL, get_possible_values_none,
623 },
624 {
625 WIA_DPS_VERTICAL_BED_REGISTRATION, VT_I4, "vertical_bed_registration", 0, g_possible_vertical_bed_registration,
626 get_possible_values_int,
627 },
628 {
629 WIA_DPS_VERTICAL_BED_SIZE, VT_I4, "vertical_bed_size", 0, NULL, get_possible_values_none,
630 },
631 {
632 WIA_DPS_VERTICAL_SHEET_FEED_SIZE, VT_I4, "vertical_sheet_feed_size", 0, NULL, get_possible_values_none,
633 },
634 {
635 WIA_IPS_AUTO_DESKEW, VT_I4, "auto_deskew", 1, g_possible_auto_deskew, get_possible_values_int,
636 },
637 {
638 WIA_IPS_BRIGHTNESS, VT_I4, "brightness", 1, NULL, get_possible_values_none,
639 },
640 {
641 WIA_IPS_CONTRAST, VT_I4, "contrast", 1, NULL, get_possible_values_none,
642 },
643 {
644 WIA_IPS_CUR_INTENT, VT_I4, "current_intent", 1, g_possible_intent, get_possible_values_int,
645 },
646 {
647 WIA_IPS_DESKEW_X, VT_I4, "deskew_x", 1, NULL, get_possible_values_none,
648 },
649 {
650 WIA_IPS_DESKEW_Y, VT_I4, "deskew_y", 1, NULL, get_possible_values_none,
651 },
652 {
653 WIA_IPS_DOCUMENT_HANDLING_SELECT, VT_I4, "document_handling_select", 1, g_possible_document_handling_select,
654 get_possible_values_int,
655 },
656 {
657 WIA_IPS_FILM_NODE_NAME, VT_BSTR, "film_node_name", 0, NULL, get_possible_values_none,
658 },
659 {
660 WIA_IPS_FILM_SCAN_MODE, VT_I4, "file_scan_mode", 1, g_possible_film_scan_mode, get_possible_values_int,
661 },
662 {
663 WIA_IPS_INVERT, VT_I4, "invert", 0, NULL, get_possible_values_none,
664 },
665 {
666 WIA_IPA_ITEMS_STORED, VT_I4, "items_stored", 0, NULL, get_possible_values_none,
667 },
668 {
669 WIA_IPS_LAMP, VT_I4, "lamp", 1, g_possible_lamp, get_possible_values_int,
670 },
671 {
672 WIA_IPS_LAMP_AUTO_OFF, VT_UI4, "lamp_auto_off", 1, NULL, get_possible_values_none,
673 },
674 {
675 WIA_IPS_MAX_HORIZONTAL_SIZE, VT_I4, "max_horizontal_size", 0, NULL, get_possible_values_none,
676 },
677 {
678 WIA_IPS_MAX_VERTICAL_SIZE, VT_I4, "max_vertical_size", 0, NULL, get_possible_values_none,
679 },
680 {
681 WIA_IPS_MIN_HORIZONTAL_SIZE, VT_I4, "min_horizontal_size", 0, NULL, get_possible_values_none,
682 },
683 {
684 WIA_IPS_MIN_VERTICAL_SIZE, VT_I4, "min_vertical_size", 0, NULL, get_possible_values_none,
685 },
686 {
687 WIA_IPS_MIRROR, VT_I4, "mirror", 0, NULL, get_possible_values_none,
688 },
689 {
690 WIA_IPS_OPTICAL_XRES, VT_I4, "optical_xres", 0, NULL, get_possible_values_none,
691 },
692 {
693 WIA_IPS_OPTICAL_YRES, VT_I4, "optical_yres", 0, NULL, get_possible_values_none,
694 },
695 {
696 WIA_IPS_ORIENTATION, VT_I4, "orientation", 1, g_possible_orientation, get_possible_values_int,
697 },
698 {
699 WIA_IPS_PAGE_SIZE, VT_I4, "page_size", 1, g_possible_page_size, get_possible_values_int,
700 },
701 {
702 WIA_IPS_PAGE_HEIGHT, VT_I4, "page_height", 0, NULL, get_possible_values_none,
703 },
704 {
705 WIA_IPS_PAGE_WIDTH, VT_I4, "page_width", 0, NULL, get_possible_values_none,
706 },
707 {
708 WIA_IPS_PAGES, VT_I4, "pages", 1, NULL, get_possible_values_none,
709 },
710 {
711 WIA_IPS_PHOTOMETRIC_INTERP, VT_I4, "photometric_interp", 1, g_possible_photometric_interp,
712 get_possible_values_int,
713 },
714 {
715 WIA_IPS_PREVIEW, VT_I4, "preview", 1, g_possible_preview, get_possible_values_int,
716 },
717 {
718 WIA_IPS_PREVIEW_TYPE, VT_I4, "preview_type", 0, g_possible_preview_type, get_possible_values_int,
719 },
720 {
721 WIA_IPS_ROTATION, VT_I4, "rotation", 1, g_possible_rotation, get_possible_values_int,
722 },
723 {
724 WIA_IPS_SEGMENTATION, VT_I4, "segmentation", 0, g_possible_segmentation, get_possible_values_int,
725 },
726 {
727 WIA_IPS_SHEET_FEEDER_REGISTRATION, VT_I4, "sheet_feeder_registration",
728 0, g_possible_sheet_feeder_registration, get_possible_values_int,
729 },
730 {
731 WIA_IPS_SHOW_PREVIEW_CONTROL, VT_I4, "show_preview_control",
732 0, g_possible_show_preview_control, get_possible_values_int,
733 },
734 {
735 WIA_IPS_SUPPORTS_CHILD_ITEM_CREATION, VT_I4, "supportes_child_item_creation", 0, NULL,
736 get_possible_values_none,
737 },
738 {
739 WIA_IPS_THRESHOLD, VT_I4, "threshold", 1, NULL, get_possible_values_none,
740 },
741 {
742 WIA_IPS_TRANSFER_CAPABILITIES, VT_I4, "transfer_capabilities", 0, NULL, get_possible_values_none,
743 },
744 {
745 WIA_IPA_UPLOAD_ITEM_SIZE, VT_I4, "upload_item_size", 1, NULL, get_possible_values_none,
746 },
747 {
748 WIA_IPS_WARM_UP_TIME, VT_I4, "warm_up_time", 0, NULL, get_possible_values_none,
749 },
750 {
751 WIA_IPS_XEXTENT, VT_I4, "xextent", 1, NULL, get_possible_values_none,
752 },
753 {
754 WIA_IPS_XPOS, VT_I4, "xpos", 1, NULL, get_possible_values_none,
755 },
756 {
757 WIA_IPS_XRES, VT_I4, "xres", 1, NULL, get_possible_values_none,
758 },
759 {
760 WIA_IPS_XSCALING, VT_I4, "xscaling", 1, NULL, get_possible_values_none,
761 },
762 {
763 WIA_IPS_YEXTENT, VT_I4, "yextent", 1, NULL, get_possible_values_none,
764 },
765 {
766 WIA_IPS_YPOS, VT_I4, "ypos", 1, NULL, get_possible_values_none,
767 },
768 {
769 WIA_IPS_YRES, VT_I4, "yres", 1, NULL, get_possible_values_none,
770 },
771 {
772 WIA_IPS_YSCALING, VT_I4, "yscaling", 1, NULL, get_possible_values_none,
773 },
774 { 0 },
775 };
776
777 const struct wia_property *g_wia_all_properties = _g_wia_all_properties;
778
get_possible_values_int(const struct wia_property * propspec)779 static PyObject *get_possible_values_int(const struct wia_property *propspec)
780 {
781 struct wia_prop_int *values = (struct wia_prop_int *)propspec->possible_values;
782 PyObject *list;
783 PyObject *value;
784
785 list = PyList_New(0);
786
787 while(values->name != NULL) {
788 value = PyUnicode_FromString(values->name);
789 PyList_Append(list, value);
790 values++;
791 }
792
793 return list;
794 }
795
get_possible_values_clsid(const struct wia_property * propspec)796 static PyObject *get_possible_values_clsid(const struct wia_property *propspec)
797 {
798 struct wia_prop_clsid *values = (struct wia_prop_clsid *)propspec->possible_values;
799 PyObject *list;
800 PyObject *value;
801
802 list = PyList_New(0);
803
804 while(values->name != NULL) {
805 value = PyUnicode_FromString(values->name);
806 PyList_Append(list, value);
807 values++;
808 }
809
810 return list;
811 }
812
get_possible_values_none(const struct wia_property *)813 static PyObject *get_possible_values_none(const struct wia_property*)
814 {
815 Py_RETURN_NONE;
816 }
817
int_to_pyobject(const struct wia_property * property,long value)818 PyObject *int_to_pyobject(const struct wia_property *property, long value)
819 {
820 const struct wia_prop_int *values;
821 int i;
822 PyObject *out;
823
824 if (property->possible_values == NULL)
825 return PyLong_FromLong(value);
826 values = (const struct wia_prop_int *)property->possible_values;
827 for (i = 0 ; values[i].name != NULL ; i++) {
828 if (values[i].value == value)
829 return PyUnicode_FromString(values[i].name);
830 }
831
832 char str[256];
833 str[0] = '\0';
834 str[sizeof(str)-1] = '\0';
835
836 for (i = 0 ; values[i].name != NULL ; i++) {
837 if (value & values[i].value) {
838 if (str[0] == '\0')
839 strncpy_s(str, values[i].name, sizeof(str) - 1);
840 else {
841 strncat_s(str, ",", sizeof(str) - 1);
842 strncat_s(str, values[i].name, sizeof(str) - 1);
843 }
844 }
845 }
846 if (str[0] != '\0') {
847 out = PyUnicode_FromString(str);
848 return out;
849 }
850
851 return PyLong_FromLong(value);
852 }
853
854
clsid_to_pyobject(const struct wia_property * property,CLSID value)855 PyObject *clsid_to_pyobject(const struct wia_property *property, CLSID value)
856 {
857 const struct wia_prop_clsid *values;
858 int i;
859
860 assert(property->possible_values != NULL);
861 values = (const struct wia_prop_clsid *)property->possible_values;
862 for (i = 0 ; NULL != values[i].name ; i++) {
863 if (values[i].value == value)
864 return PyUnicode_FromString(values[i].name);
865 }
866 wia_log(WIA_WARNING, "Got unknown clsid from driver (property=%s)", property->name);
867 return NULL;
868 }
869
int_vector_to_pyobject_list(const CAL * values)870 PyObject *int_vector_to_pyobject_list(const CAL *values)
871 {
872 PyObject *out = PyList_New(values->cElems);
873 PyObject *val;
874 ULONG i;
875
876 for (i = 0 ; i < values->cElems ; i++) {
877 val = PyLong_FromLong(values->pElems[i]);
878 PyList_SetItem(out, i, val);
879 }
880
881 return out;
882 }
883
int_vector_to_pyobject_tuple(const CAL * values)884 PyObject *int_vector_to_pyobject_tuple(const CAL *values)
885 {
886 PyObject *out;
887 PyObject *val;
888 int i;
889
890 if (values->cElems < 2) {
891 wia_log(WIA_WARNING, "Got a range with not enough elements ! (%d)", values->cElems);
892 return NULL;
893 }
894
895 out = PyTuple_New(values->cElems);
896 for (i = 0 ; i < values->cElems ; i++) {
897 val = PyLong_FromLong(values->pElems[i]);
898 PyTuple_SetItem(out, i, val);
899 }
900 return out;
901 }
902
str_vector_to_pyobject(const CABSTR * values)903 PyObject *str_vector_to_pyobject(const CABSTR *values)
904 {
905 PyObject *out = PyList_New(values->cElems);
906 PyObject *val;
907 ULONG i;
908
909 for (i = 0 ; i < values->cElems ; i++) {
910 //val = PyLong_FromLong(values->pElems[i]);
911 val = PyUnicode_FromWideChar(SysAllocString(values->pElems[i]), SysStringLen(values->pElems[i]));
912 PyList_SetItem(out, i, val);
913 }
914
915 return out;
916 }
917
pyobject_to_int(const struct wia_property * property_spec,PyObject * pyvalue,int fail_value)918 int pyobject_to_int(const struct wia_property *property_spec, PyObject *pyvalue, int fail_value)
919 {
920 char str[256];
921 char *pstr, *nstr;
922 int has_match;
923 int val;
924 int i;
925 const struct wia_prop_int *str2int;
926
927 if (PyLong_Check(pyvalue))
928 return PyLong_AsLong(pyvalue);
929
930 str2int = (const struct wia_prop_int *)property_spec->possible_values;
931 if (PyUnicode_Check(pyvalue) && str2int != NULL) {
932 // parse string
933 strncpy_s(str, PyUnicode_AsUTF8(pyvalue), sizeof(str));
934 val = 0;
935 has_match = 0;
936 pstr = str;
937 while(pstr) {
938 nstr = strchr(pstr, ',');
939 if (nstr) {
940 nstr[0] = '\0';
941 nstr++;
942 }
943 for (i = 0 ; str2int[i].name != NULL ; i++) {
944 if (strcmp(pstr, str2int[i].name) == 0) {
945 val |= str2int[i].value;
946 has_match = 1;
947 break;
948 }
949 }
950 pstr = nstr;
951 }
952
953 if (has_match) {
954 return val;
955 }
956 }
957
958 wia_log(WIA_WARNING, "set_property(%s): Failed to parse value", property_spec->name);
959 return fail_value;
960 }
961
pyobject_to_clsid(const struct wia_property * property_spec,PyObject * pyvalue,CLSID ** out)962 int pyobject_to_clsid(const struct wia_property *property_spec, PyObject *pyvalue, CLSID **out)
963 {
964 const struct wia_prop_clsid *str2clsid;
965 int i;
966 const char *value;
967
968 if (!PyUnicode_Check(pyvalue)) {
969 wia_log(WIA_WARNING, "set_property(%s): Invalid type for clsid property", property_spec->name);
970 return 0;
971 }
972
973 str2clsid = (const struct wia_prop_clsid *)property_spec->possible_values;
974 assert(str2clsid != NULL);
975
976 value = PyUnicode_AsUTF8(pyvalue);
977
978 for (i = 0 ; str2clsid[i].name != NULL ; i++) {
979 if (strcmp(value, str2clsid[i].name) == 0) {
980 *out = (CLSID *)&str2clsid[i].value;
981 return 1;
982 }
983 }
984
985 wia_log(WIA_WARNING, "set_property(%s): Invalid value for clsid property", property_spec->name);
986 return 0;
987 }
988