[WINDOWSCODECS] Sync with Wine Staging 4.0. CORE-15682
[reactos.git] / dll / win32 / windowscodecs / regsvr.c
1 /*
2 * Copyright 2009 Vincent Povirk for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #define COBJMACROS
20 #include <stdarg.h>
21 #include <string.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winreg.h"
28 #include "winerror.h"
29
30 #include "objbase.h"
31 #include "ocidl.h"
32
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
35
36 #include "wincodecs_private.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
39
40 /***********************************************************************
41 * interface for self-registering
42 */
43 struct decoder_pattern
44 {
45 DWORD length; /* 0 for end of list */
46 DWORD position;
47 const BYTE *pattern;
48 const BYTE *mask;
49 DWORD endofstream;
50 };
51
52 struct regsvr_decoder
53 {
54 CLSID const *clsid; /* NULL for end of list */
55 LPCSTR author;
56 LPCSTR friendlyname;
57 LPCSTR version;
58 GUID const *vendor;
59 GUID const *container_format;
60 LPCSTR mimetypes;
61 LPCSTR extensions;
62 GUID const * const *formats;
63 const struct decoder_pattern *patterns;
64 };
65
66 static HRESULT register_decoders(struct regsvr_decoder const *list);
67 static HRESULT unregister_decoders(struct regsvr_decoder const *list);
68
69 struct regsvr_encoder
70 {
71 CLSID const *clsid; /* NULL for end of list */
72 LPCSTR author;
73 LPCSTR friendlyname;
74 LPCSTR version;
75 GUID const *vendor;
76 GUID const *container_format;
77 LPCSTR mimetypes;
78 LPCSTR extensions;
79 GUID const * const *formats;
80 };
81
82 static HRESULT register_encoders(struct regsvr_encoder const *list);
83 static HRESULT unregister_encoders(struct regsvr_encoder const *list);
84
85 struct regsvr_converter
86 {
87 CLSID const *clsid; /* NULL for end of list */
88 LPCSTR author;
89 LPCSTR friendlyname;
90 LPCSTR version;
91 GUID const *vendor;
92 GUID const * const *formats;
93 };
94
95 static HRESULT register_converters(struct regsvr_converter const *list);
96 static HRESULT unregister_converters(struct regsvr_converter const *list);
97
98 struct metadata_pattern
99 {
100 DWORD position;
101 DWORD length;
102 const BYTE *pattern;
103 const BYTE *mask;
104 DWORD data_offset;
105 };
106
107 struct reader_containers
108 {
109 GUID const *format;
110 const struct metadata_pattern *patterns;
111 };
112
113 struct regsvr_metadatareader
114 {
115 CLSID const *clsid; /* NULL for end of list */
116 LPCSTR author;
117 LPCSTR friendlyname;
118 LPCSTR version;
119 LPCSTR specversion;
120 GUID const *vendor;
121 GUID const *metadata_format;
122 DWORD requires_fullstream;
123 DWORD supports_padding;
124 DWORD requires_fixedsize;
125 const struct reader_containers *containers;
126 };
127
128 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list);
129 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list);
130
131 struct regsvr_pixelformat
132 {
133 CLSID const *clsid; /* NULL for end of list */
134 LPCSTR author;
135 LPCSTR friendlyname;
136 LPCSTR version;
137 GUID const *vendor;
138 UINT bitsperpixel;
139 UINT channelcount;
140 BYTE const * const *channelmasks;
141 WICPixelFormatNumericRepresentation numericrepresentation;
142 UINT supportsalpha;
143 };
144
145 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list);
146 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list);
147
148 /***********************************************************************
149 * static string constants
150 */
151 static const WCHAR clsid_keyname[] = {
152 'C', 'L', 'S', 'I', 'D', 0 };
153 static const char author_valuename[] = "Author";
154 static const char friendlyname_valuename[] = "FriendlyName";
155 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
156 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
157 static const char version_valuename[] = "Version";
158 static const char mimetypes_valuename[] = "MimeTypes";
159 static const char extensions_valuename[] = "FileExtensions";
160 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0};
161 static const WCHAR patterns_keyname[] = {'P','a','t','t','e','r','n','s',0};
162 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
163 static const WCHAR clsid_valuename[] = {'C','L','S','I','D',0};
164 static const char length_valuename[] = "Length";
165 static const char position_valuename[] = "Position";
166 static const char pattern_valuename[] = "Pattern";
167 static const char mask_valuename[] = "Mask";
168 static const char endofstream_valuename[] = "EndOfStream";
169 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
170 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
171 static const char specversion_valuename[] = "SpecVersion";
172 static const char requiresfullstream_valuename[] = "RequiresFullStream";
173 static const char supportspadding_valuename[] = "SupportsPadding";
174 static const char requiresfixedsize_valuename[] = "FixedSize";
175 static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0};
176 static const char dataoffset_valuename[] = "DataOffset";
177 static const char bitsperpixel_valuename[] = "BitLength";
178 static const char channelcount_valuename[] = "ChannelCount";
179 static const char numericrepresentation_valuename[] = "NumericRepresentation";
180 static const char supportstransparency_valuename[] = "SupportsTransparency";
181 static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
182
183 /***********************************************************************
184 * register_decoders
185 */
186 static HRESULT register_decoders(struct regsvr_decoder const *list)
187 {
188 LONG res = ERROR_SUCCESS;
189 HKEY coclass_key;
190 WCHAR buf[39];
191 HKEY decoders_key;
192 HKEY instance_key;
193
194 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
195 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
196 if (res == ERROR_SUCCESS) {
197 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
198 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
199 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
200 if (res == ERROR_SUCCESS)
201 {
202 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
203 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
204 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
205 }
206 if (res != ERROR_SUCCESS)
207 RegCloseKey(coclass_key);
208 }
209 if (res != ERROR_SUCCESS) goto error_return;
210
211 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
212 HKEY clsid_key;
213 HKEY instance_clsid_key;
214
215 StringFromGUID2(list->clsid, buf, 39);
216 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
217 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
218 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
219
220 StringFromGUID2(list->clsid, buf, 39);
221 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
222 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
223 if (res == ERROR_SUCCESS) {
224 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
225 (const BYTE*)buf, 78);
226 RegCloseKey(instance_clsid_key);
227 }
228 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
229
230 if (list->author) {
231 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
232 (const BYTE*)list->author,
233 strlen(list->author) + 1);
234 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
235 }
236
237 if (list->friendlyname) {
238 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
239 (const BYTE*)list->friendlyname,
240 strlen(list->friendlyname) + 1);
241 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
242 }
243
244 if (list->vendor) {
245 StringFromGUID2(list->vendor, buf, 39);
246 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
247 (const BYTE*)buf, 78);
248 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
249 }
250
251 if (list->container_format) {
252 StringFromGUID2(list->container_format, buf, 39);
253 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
254 (const BYTE*)buf, 78);
255 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
256 }
257
258 if (list->version) {
259 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
260 (const BYTE*)list->version,
261 strlen(list->version) + 1);
262 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
263 }
264
265 if (list->mimetypes) {
266 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
267 (const BYTE*)list->mimetypes,
268 strlen(list->mimetypes) + 1);
269 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
270 }
271
272 if (list->extensions) {
273 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
274 (const BYTE*)list->extensions,
275 strlen(list->extensions) + 1);
276 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
277 }
278
279 if (list->formats) {
280 HKEY formats_key;
281 GUID const * const *format;
282
283 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
284 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
285 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
286 for (format=list->formats; *format; ++format)
287 {
288 HKEY format_key;
289 StringFromGUID2(*format, buf, 39);
290 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
291 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
292 if (res != ERROR_SUCCESS) break;
293 RegCloseKey(format_key);
294 }
295 RegCloseKey(formats_key);
296 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
297 }
298
299 if (list->patterns) {
300 HKEY patterns_key;
301 int i;
302
303 res = RegCreateKeyExW(clsid_key, patterns_keyname, 0, NULL, 0,
304 KEY_READ | KEY_WRITE, NULL, &patterns_key, NULL);
305 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
306 for (i=0; list->patterns[i].length; i++)
307 {
308 HKEY pattern_key;
309 static const WCHAR int_format[] = {'%','i',0};
310 snprintfW(buf, 39, int_format, i);
311 res = RegCreateKeyExW(patterns_key, buf, 0, NULL, 0,
312 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
313 if (res != ERROR_SUCCESS) break;
314 res = RegSetValueExA(pattern_key, length_valuename, 0, REG_DWORD,
315 (const BYTE*)&list->patterns[i].length, 4);
316 if (res == ERROR_SUCCESS)
317 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
318 (const BYTE*)&list->patterns[i].position, 4);
319 if (res == ERROR_SUCCESS)
320 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
321 list->patterns[i].pattern,
322 list->patterns[i].length);
323 if (res == ERROR_SUCCESS)
324 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
325 list->patterns[i].mask,
326 list->patterns[i].length);
327 if (res == ERROR_SUCCESS)
328 res = RegSetValueExA(pattern_key, endofstream_valuename, 0, REG_DWORD,
329 (const BYTE*)&list->patterns[i].endofstream, 4);
330 RegCloseKey(pattern_key);
331 }
332 RegCloseKey(patterns_key);
333 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
334 }
335
336 error_close_clsid_key:
337 RegCloseKey(clsid_key);
338 }
339
340 error_close_coclass_key:
341 RegCloseKey(instance_key);
342 RegCloseKey(decoders_key);
343 RegCloseKey(coclass_key);
344 error_return:
345 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
346 }
347
348 /***********************************************************************
349 * unregister_decoders
350 */
351 static HRESULT unregister_decoders(struct regsvr_decoder const *list)
352 {
353 LONG res = ERROR_SUCCESS;
354 HKEY coclass_key;
355 WCHAR buf[39];
356 HKEY decoders_key;
357 HKEY instance_key;
358
359 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
360 KEY_READ | KEY_WRITE, &coclass_key);
361 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
362
363 if (res == ERROR_SUCCESS) {
364 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
365 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
366 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
367 if (res == ERROR_SUCCESS)
368 {
369 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
370 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
371 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
372 }
373 if (res != ERROR_SUCCESS)
374 RegCloseKey(coclass_key);
375 }
376 if (res != ERROR_SUCCESS) goto error_return;
377
378 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
379 StringFromGUID2(list->clsid, buf, 39);
380
381 res = RegDeleteTreeW(coclass_key, buf);
382 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
383 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
384
385 res = RegDeleteTreeW(instance_key, buf);
386 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
387 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
388 }
389
390 error_close_coclass_key:
391 RegCloseKey(instance_key);
392 RegCloseKey(decoders_key);
393 RegCloseKey(coclass_key);
394 error_return:
395 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
396 }
397
398 /***********************************************************************
399 * register_encoders
400 */
401 static HRESULT register_encoders(struct regsvr_encoder const *list)
402 {
403 LONG res = ERROR_SUCCESS;
404 HKEY coclass_key;
405 WCHAR buf[39];
406 HKEY encoders_key;
407 HKEY instance_key;
408
409 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
410 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
411 if (res == ERROR_SUCCESS) {
412 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
413 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
414 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
415 if (res == ERROR_SUCCESS)
416 {
417 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
418 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
419 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
420 }
421 if (res != ERROR_SUCCESS)
422 RegCloseKey(coclass_key);
423 }
424 if (res != ERROR_SUCCESS) goto error_return;
425
426 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
427 HKEY clsid_key;
428 HKEY instance_clsid_key;
429
430 StringFromGUID2(list->clsid, buf, 39);
431 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
432 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
433 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
434
435 StringFromGUID2(list->clsid, buf, 39);
436 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
437 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
438 if (res == ERROR_SUCCESS) {
439 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
440 (const BYTE*)buf, 78);
441 RegCloseKey(instance_clsid_key);
442 }
443 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
444
445 if (list->author) {
446 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
447 (const BYTE*)list->author,
448 strlen(list->author) + 1);
449 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
450 }
451
452 if (list->friendlyname) {
453 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
454 (const BYTE*)list->friendlyname,
455 strlen(list->friendlyname) + 1);
456 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
457 }
458
459 if (list->vendor) {
460 StringFromGUID2(list->vendor, buf, 39);
461 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
462 (const BYTE*)buf, 78);
463 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
464 }
465
466 if (list->container_format) {
467 StringFromGUID2(list->container_format, buf, 39);
468 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
469 (const BYTE*)buf, 78);
470 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
471 }
472
473 if (list->version) {
474 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
475 (const BYTE*)list->version,
476 strlen(list->version) + 1);
477 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
478 }
479
480 if (list->mimetypes) {
481 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
482 (const BYTE*)list->mimetypes,
483 strlen(list->mimetypes) + 1);
484 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
485 }
486
487 if (list->extensions) {
488 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
489 (const BYTE*)list->extensions,
490 strlen(list->extensions) + 1);
491 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
492 }
493
494 if (list->formats) {
495 HKEY formats_key;
496 GUID const * const *format;
497
498 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
499 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
500 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
501 for (format=list->formats; *format; ++format)
502 {
503 HKEY format_key;
504 StringFromGUID2(*format, buf, 39);
505 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
506 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
507 if (res != ERROR_SUCCESS) break;
508 RegCloseKey(format_key);
509 }
510 RegCloseKey(formats_key);
511 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
512 }
513
514 error_close_clsid_key:
515 RegCloseKey(clsid_key);
516 }
517
518 error_close_coclass_key:
519 RegCloseKey(instance_key);
520 RegCloseKey(encoders_key);
521 RegCloseKey(coclass_key);
522 error_return:
523 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
524 }
525
526 /***********************************************************************
527 * unregister_encoders
528 */
529 static HRESULT unregister_encoders(struct regsvr_encoder const *list)
530 {
531 LONG res = ERROR_SUCCESS;
532 HKEY coclass_key;
533 WCHAR buf[39];
534 HKEY encoders_key;
535 HKEY instance_key;
536
537 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
538 KEY_READ | KEY_WRITE, &coclass_key);
539 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
540
541 if (res == ERROR_SUCCESS) {
542 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
543 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
544 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
545 if (res == ERROR_SUCCESS)
546 {
547 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
548 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
549 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
550 }
551 if (res != ERROR_SUCCESS)
552 RegCloseKey(coclass_key);
553 }
554 if (res != ERROR_SUCCESS) goto error_return;
555
556 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
557 StringFromGUID2(list->clsid, buf, 39);
558
559 res = RegDeleteTreeW(coclass_key, buf);
560 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
561 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
562
563 res = RegDeleteTreeW(instance_key, buf);
564 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
565 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
566 }
567
568 error_close_coclass_key:
569 RegCloseKey(instance_key);
570 RegCloseKey(encoders_key);
571 RegCloseKey(coclass_key);
572 error_return:
573 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
574 }
575
576 /***********************************************************************
577 * register_converters
578 */
579 static HRESULT register_converters(struct regsvr_converter const *list)
580 {
581 LONG res = ERROR_SUCCESS;
582 HKEY coclass_key;
583 WCHAR buf[39];
584 HKEY converters_key;
585 HKEY instance_key;
586
587 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
588 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
589 if (res == ERROR_SUCCESS) {
590 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
591 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
592 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
593 if (res == ERROR_SUCCESS)
594 {
595 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
596 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
597 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
598 }
599 if (res != ERROR_SUCCESS)
600 RegCloseKey(coclass_key);
601 }
602 if (res != ERROR_SUCCESS) goto error_return;
603
604 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
605 HKEY clsid_key;
606 HKEY instance_clsid_key;
607
608 StringFromGUID2(list->clsid, buf, 39);
609 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
610 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
611 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
612
613 StringFromGUID2(list->clsid, buf, 39);
614 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
615 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
616 if (res == ERROR_SUCCESS) {
617 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
618 (const BYTE*)buf, 78);
619 RegCloseKey(instance_clsid_key);
620 }
621 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
622
623 if (list->author) {
624 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
625 (const BYTE*)list->author,
626 strlen(list->author) + 1);
627 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
628 }
629
630 if (list->friendlyname) {
631 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
632 (const BYTE*)list->friendlyname,
633 strlen(list->friendlyname) + 1);
634 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
635 }
636
637 if (list->vendor) {
638 StringFromGUID2(list->vendor, buf, 39);
639 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
640 (const BYTE*)buf, 78);
641 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
642 }
643
644 if (list->version) {
645 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
646 (const BYTE*)list->version,
647 strlen(list->version) + 1);
648 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
649 }
650
651 if (list->formats) {
652 HKEY formats_key;
653 GUID const * const *format;
654
655 res = RegCreateKeyExW(clsid_key, pixelformats_keyname, 0, NULL, 0,
656 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
657 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
658 for (format=list->formats; *format; ++format)
659 {
660 HKEY format_key;
661 StringFromGUID2(*format, buf, 39);
662 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
663 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
664 if (res != ERROR_SUCCESS) break;
665 RegCloseKey(format_key);
666 }
667 RegCloseKey(formats_key);
668 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
669 }
670
671 error_close_clsid_key:
672 RegCloseKey(clsid_key);
673 }
674
675 error_close_coclass_key:
676 RegCloseKey(instance_key);
677 RegCloseKey(converters_key);
678 RegCloseKey(coclass_key);
679 error_return:
680 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
681 }
682
683 /***********************************************************************
684 * unregister_converters
685 */
686 static HRESULT unregister_converters(struct regsvr_converter const *list)
687 {
688 LONG res = ERROR_SUCCESS;
689 HKEY coclass_key;
690 WCHAR buf[39];
691 HKEY converters_key;
692 HKEY instance_key;
693
694 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
695 KEY_READ | KEY_WRITE, &coclass_key);
696 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
697
698 if (res == ERROR_SUCCESS) {
699 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
700 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
701 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
702 if (res == ERROR_SUCCESS)
703 {
704 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
705 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
706 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
707 }
708 if (res != ERROR_SUCCESS)
709 RegCloseKey(coclass_key);
710 }
711 if (res != ERROR_SUCCESS) goto error_return;
712
713 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
714 StringFromGUID2(list->clsid, buf, 39);
715
716 res = RegDeleteTreeW(coclass_key, buf);
717 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
718 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
719
720 res = RegDeleteTreeW(instance_key, buf);
721 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
722 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
723 }
724
725 error_close_coclass_key:
726 RegCloseKey(instance_key);
727 RegCloseKey(converters_key);
728 RegCloseKey(coclass_key);
729 error_return:
730 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
731 }
732
733 /***********************************************************************
734 * register_metadatareaders
735 */
736 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list)
737 {
738 LONG res = ERROR_SUCCESS;
739 HKEY coclass_key;
740 WCHAR buf[39];
741 HKEY readers_key;
742 HKEY instance_key;
743
744 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
745 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
746 if (res == ERROR_SUCCESS) {
747 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
748 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
749 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
750 if (res == ERROR_SUCCESS)
751 {
752 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
753 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
754 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
755 }
756 if (res != ERROR_SUCCESS)
757 RegCloseKey(coclass_key);
758 }
759 if (res != ERROR_SUCCESS) goto error_return;
760
761 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
762 HKEY clsid_key;
763 HKEY instance_clsid_key;
764
765 StringFromGUID2(list->clsid, buf, 39);
766 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
767 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
768 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
769
770 StringFromGUID2(list->clsid, buf, 39);
771 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
772 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
773 if (res == ERROR_SUCCESS) {
774 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
775 (const BYTE*)buf, 78);
776 RegCloseKey(instance_clsid_key);
777 }
778 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
779
780 if (list->author) {
781 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
782 (const BYTE*)list->author,
783 strlen(list->author) + 1);
784 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
785 }
786
787 if (list->friendlyname) {
788 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
789 (const BYTE*)list->friendlyname,
790 strlen(list->friendlyname) + 1);
791 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
792 }
793
794 if (list->vendor) {
795 StringFromGUID2(list->vendor, buf, 39);
796 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
797 (const BYTE*)buf, 78);
798 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
799 }
800
801 if (list->metadata_format) {
802 StringFromGUID2(list->metadata_format, buf, 39);
803 res = RegSetValueExW(clsid_key, metadataformat_valuename, 0, REG_SZ,
804 (const BYTE*)buf, 78);
805 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
806 }
807
808 if (list->version) {
809 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
810 (const BYTE*)list->version,
811 strlen(list->version) + 1);
812 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
813 }
814
815 if (list->specversion) {
816 res = RegSetValueExA(clsid_key, specversion_valuename, 0, REG_SZ,
817 (const BYTE*)list->version,
818 strlen(list->version) + 1);
819 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
820 }
821
822 res = RegSetValueExA(clsid_key, requiresfullstream_valuename, 0, REG_DWORD,
823 (const BYTE*)&list->requires_fullstream, 4);
824 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
825
826 res = RegSetValueExA(clsid_key, supportspadding_valuename, 0, REG_DWORD,
827 (const BYTE*)&list->supports_padding, 4);
828 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
829
830 if (list->requires_fixedsize) {
831 res = RegSetValueExA(clsid_key, requiresfixedsize_valuename, 0, REG_DWORD,
832 (const BYTE*)&list->requires_fixedsize, 4);
833 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
834 }
835
836 if (list->containers) {
837 HKEY containers_key;
838 const struct reader_containers *container;
839
840 res = RegCreateKeyExW(clsid_key, containers_keyname, 0, NULL, 0,
841 KEY_READ | KEY_WRITE, NULL, &containers_key, NULL);
842 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
843 for (container=list->containers; container->format; ++container)
844 {
845 HKEY format_key;
846 int i;
847 StringFromGUID2(container->format, buf, 39);
848 res = RegCreateKeyExW(containers_key, buf, 0, NULL, 0,
849 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
850 if (res != ERROR_SUCCESS) break;
851
852 for (i=0; container->patterns[i].length; i++)
853 {
854 HKEY pattern_key;
855 static const WCHAR int_format[] = {'%','i',0};
856 snprintfW(buf, 39, int_format, i);
857 res = RegCreateKeyExW(format_key, buf, 0, NULL, 0,
858 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
859 if (res != ERROR_SUCCESS) break;
860 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
861 (const BYTE*)&container->patterns[i].position, 4);
862 if (res == ERROR_SUCCESS)
863 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
864 container->patterns[i].pattern,
865 container->patterns[i].length);
866 if (res == ERROR_SUCCESS)
867 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
868 container->patterns[i].mask,
869 container->patterns[i].length);
870 if (res == ERROR_SUCCESS && container->patterns[i].data_offset)
871 res = RegSetValueExA(pattern_key, dataoffset_valuename, 0, REG_DWORD,
872 (const BYTE*)&container->patterns[i].data_offset, 4);
873 RegCloseKey(pattern_key);
874 }
875
876 RegCloseKey(format_key);
877 }
878 RegCloseKey(containers_key);
879 }
880
881 error_close_clsid_key:
882 RegCloseKey(clsid_key);
883 }
884
885 error_close_coclass_key:
886 RegCloseKey(instance_key);
887 RegCloseKey(readers_key);
888 RegCloseKey(coclass_key);
889 error_return:
890 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
891 }
892
893 /***********************************************************************
894 * unregister_metadatareaders
895 */
896 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list)
897 {
898 LONG res = ERROR_SUCCESS;
899 HKEY coclass_key;
900 WCHAR buf[39];
901 HKEY readers_key;
902 HKEY instance_key;
903
904 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
905 KEY_READ | KEY_WRITE, &coclass_key);
906 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
907
908 if (res == ERROR_SUCCESS) {
909 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
910 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
911 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
912 if (res == ERROR_SUCCESS)
913 {
914 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
915 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
916 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
917 }
918 if (res != ERROR_SUCCESS)
919 RegCloseKey(coclass_key);
920 }
921 if (res != ERROR_SUCCESS) goto error_return;
922
923 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
924 StringFromGUID2(list->clsid, buf, 39);
925
926 res = RegDeleteTreeW(coclass_key, buf);
927 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
928 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
929
930 res = RegDeleteTreeW(instance_key, buf);
931 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
932 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
933 }
934
935 error_close_coclass_key:
936 RegCloseKey(instance_key);
937 RegCloseKey(readers_key);
938 RegCloseKey(coclass_key);
939 error_return:
940 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
941 }
942
943 /***********************************************************************
944 * register_pixelformats
945 */
946 static HRESULT register_pixelformats(struct regsvr_pixelformat const *list)
947 {
948 LONG res = ERROR_SUCCESS;
949 HKEY coclass_key;
950 WCHAR buf[39];
951 HKEY formats_key;
952 HKEY instance_key;
953
954 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
955 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
956 if (res == ERROR_SUCCESS) {
957 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
958 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
959 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
960 if (res == ERROR_SUCCESS)
961 {
962 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
963 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
964 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
965 }
966 if (res != ERROR_SUCCESS)
967 RegCloseKey(coclass_key);
968 }
969 if (res != ERROR_SUCCESS) goto error_return;
970
971 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
972 HKEY clsid_key;
973 HKEY instance_clsid_key;
974
975 StringFromGUID2(list->clsid, buf, 39);
976 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
977 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
978 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
979
980 StringFromGUID2(list->clsid, buf, 39);
981 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
982 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
983 if (res == ERROR_SUCCESS) {
984 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
985 (const BYTE*)buf, 78);
986 RegCloseKey(instance_clsid_key);
987 }
988 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
989
990 if (list->author) {
991 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
992 (const BYTE*)list->author,
993 strlen(list->author) + 1);
994 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
995 }
996
997 if (list->friendlyname) {
998 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
999 (const BYTE*)list->friendlyname,
1000 strlen(list->friendlyname) + 1);
1001 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1002 }
1003
1004 if (list->vendor) {
1005 StringFromGUID2(list->vendor, buf, 39);
1006 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
1007 (const BYTE*)buf, 78);
1008 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1009 }
1010
1011 if (list->version) {
1012 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
1013 (const BYTE*)list->version,
1014 strlen(list->version) + 1);
1015 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1016 }
1017
1018 res = RegSetValueExA(clsid_key, bitsperpixel_valuename, 0, REG_DWORD,
1019 (const BYTE*)&list->bitsperpixel, 4);
1020 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1021
1022 res = RegSetValueExA(clsid_key, channelcount_valuename, 0, REG_DWORD,
1023 (const BYTE*)&list->channelcount, 4);
1024 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1025
1026 res = RegSetValueExA(clsid_key, numericrepresentation_valuename, 0, REG_DWORD,
1027 (const BYTE*)&list->numericrepresentation, 4);
1028 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1029
1030 res = RegSetValueExA(clsid_key, supportstransparency_valuename, 0, REG_DWORD,
1031 (const BYTE*)&list->supportsalpha, 4);
1032 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1033
1034 if (list->channelmasks) {
1035 static const WCHAR valuename_format[] = {'%','d',0};
1036 HKEY masks_key;
1037 UINT i, mask_size;
1038 WCHAR mask_valuename[11];
1039
1040 mask_size = (list->bitsperpixel + 7)/8;
1041
1042 res = RegCreateKeyExW(clsid_key, channelmasks_keyname, 0, NULL, 0,
1043 KEY_READ | KEY_WRITE, NULL, &masks_key, NULL);
1044 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1045 for (i=0; i < list->channelcount; i++)
1046 {
1047 sprintfW(mask_valuename, valuename_format, i);
1048 res = RegSetValueExW(masks_key, mask_valuename, 0, REG_BINARY,
1049 list->channelmasks[i], mask_size);
1050 if (res != ERROR_SUCCESS) break;
1051 }
1052 RegCloseKey(masks_key);
1053 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
1054 }
1055
1056 error_close_clsid_key:
1057 RegCloseKey(clsid_key);
1058 }
1059
1060 error_close_coclass_key:
1061 RegCloseKey(instance_key);
1062 RegCloseKey(formats_key);
1063 RegCloseKey(coclass_key);
1064 error_return:
1065 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1066 }
1067
1068 /***********************************************************************
1069 * unregister_pixelformats
1070 */
1071 static HRESULT unregister_pixelformats(struct regsvr_pixelformat const *list)
1072 {
1073 LONG res = ERROR_SUCCESS;
1074 HKEY coclass_key;
1075 WCHAR buf[39];
1076 HKEY formats_key;
1077 HKEY instance_key;
1078
1079 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
1080 KEY_READ | KEY_WRITE, &coclass_key);
1081 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
1082
1083 if (res == ERROR_SUCCESS) {
1084 StringFromGUID2(&CATID_WICPixelFormats, buf, 39);
1085 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
1086 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
1087 if (res == ERROR_SUCCESS)
1088 {
1089 res = RegCreateKeyExW(formats_key, instance_keyname, 0, NULL, 0,
1090 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
1091 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1092 }
1093 if (res != ERROR_SUCCESS)
1094 RegCloseKey(coclass_key);
1095 }
1096 if (res != ERROR_SUCCESS) goto error_return;
1097
1098 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
1099 StringFromGUID2(list->clsid, buf, 39);
1100
1101 res = RegDeleteTreeW(coclass_key, buf);
1102 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1103 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1104
1105 res = RegDeleteTreeW(instance_key, buf);
1106 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
1107 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
1108 }
1109
1110 error_close_coclass_key:
1111 RegCloseKey(instance_key);
1112 RegCloseKey(formats_key);
1113 RegCloseKey(coclass_key);
1114 error_return:
1115 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
1116 }
1117
1118 /***********************************************************************
1119 * decoder list
1120 */
1121 static const BYTE mask_all[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
1122
1123 static const BYTE bmp_magic[] = {0x42,0x4d};
1124
1125 static GUID const * const bmp_formats[] = {
1126 &GUID_WICPixelFormat1bppIndexed,
1127 &GUID_WICPixelFormat2bppIndexed,
1128 &GUID_WICPixelFormat4bppIndexed,
1129 &GUID_WICPixelFormat8bppIndexed,
1130 &GUID_WICPixelFormat16bppBGR555,
1131 &GUID_WICPixelFormat16bppBGR565,
1132 &GUID_WICPixelFormat24bppBGR,
1133 &GUID_WICPixelFormat32bppBGR,
1134 &GUID_WICPixelFormat32bppBGRA,
1135 NULL
1136 };
1137
1138 static struct decoder_pattern const bmp_patterns[] = {
1139 {2,0,bmp_magic,mask_all,0},
1140 {0}
1141 };
1142
1143 static const BYTE gif87a_magic[6] = "GIF87a";
1144 static const BYTE gif89a_magic[6] = "GIF89a";
1145
1146 static GUID const * const gif_formats[] = {
1147 &GUID_WICPixelFormat8bppIndexed,
1148 NULL
1149 };
1150
1151 static struct decoder_pattern const gif_patterns[] = {
1152 {6,0,gif87a_magic,mask_all,0},
1153 {6,0,gif89a_magic,mask_all,0},
1154 {0}
1155 };
1156
1157 static const BYTE ico_magic[] = {00,00,01,00};
1158
1159 static GUID const * const ico_formats[] = {
1160 &GUID_WICPixelFormat32bppBGRA,
1161 NULL
1162 };
1163
1164 static struct decoder_pattern const ico_patterns[] = {
1165 {4,0,ico_magic,mask_all,0},
1166 {0}
1167 };
1168
1169 static const BYTE jpeg_magic[] = {0xff, 0xd8};
1170
1171 static GUID const * const jpeg_formats[] = {
1172 &GUID_WICPixelFormat24bppBGR,
1173 &GUID_WICPixelFormat32bppCMYK,
1174 &GUID_WICPixelFormat8bppGray,
1175 NULL
1176 };
1177
1178 static struct decoder_pattern const jpeg_patterns[] = {
1179 {2,0,jpeg_magic,mask_all,0},
1180 {0}
1181 };
1182
1183 static const BYTE png_magic[] = {137,80,78,71,13,10,26,10};
1184
1185 static GUID const * const png_formats[] = {
1186 &GUID_WICPixelFormatBlackWhite,
1187 &GUID_WICPixelFormat2bppGray,
1188 &GUID_WICPixelFormat4bppGray,
1189 &GUID_WICPixelFormat8bppGray,
1190 &GUID_WICPixelFormat16bppGray,
1191 &GUID_WICPixelFormat32bppBGRA,
1192 &GUID_WICPixelFormat64bppRGBA,
1193 &GUID_WICPixelFormat1bppIndexed,
1194 &GUID_WICPixelFormat2bppIndexed,
1195 &GUID_WICPixelFormat4bppIndexed,
1196 &GUID_WICPixelFormat8bppIndexed,
1197 &GUID_WICPixelFormat24bppBGR,
1198 &GUID_WICPixelFormat48bppRGB,
1199 NULL
1200 };
1201
1202 static struct decoder_pattern const png_patterns[] = {
1203 {8,0,png_magic,mask_all,0},
1204 {0}
1205 };
1206
1207 static const BYTE tiff_magic_le[] = {0x49,0x49,42,0};
1208 static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42};
1209
1210 static GUID const * const tiff_decode_formats[] = {
1211 &GUID_WICPixelFormatBlackWhite,
1212 &GUID_WICPixelFormat4bppGray,
1213 &GUID_WICPixelFormat8bppGray,
1214 &GUID_WICPixelFormat16bppGray,
1215 &GUID_WICPixelFormat32bppGrayFloat,
1216 &GUID_WICPixelFormat1bppIndexed,
1217 &GUID_WICPixelFormat2bppIndexed,
1218 &GUID_WICPixelFormat4bppIndexed,
1219 &GUID_WICPixelFormat8bppIndexed,
1220 &GUID_WICPixelFormat24bppBGR,
1221 &GUID_WICPixelFormat32bppBGR,
1222 &GUID_WICPixelFormat32bppBGRA,
1223 &GUID_WICPixelFormat32bppPBGRA,
1224 &GUID_WICPixelFormat48bppRGB,
1225 &GUID_WICPixelFormat64bppRGBA,
1226 &GUID_WICPixelFormat64bppPRGBA,
1227 &GUID_WICPixelFormat32bppCMYK,
1228 &GUID_WICPixelFormat64bppCMYK,
1229 &GUID_WICPixelFormat128bppRGBAFloat,
1230 NULL
1231 };
1232
1233 static struct decoder_pattern const tiff_patterns[] = {
1234 {4,0,tiff_magic_le,mask_all,0},
1235 {4,0,tiff_magic_be,mask_all,0},
1236 {0}
1237 };
1238
1239 static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE.";
1240
1241 static const BYTE tga_indexed_magic[18] = {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0};
1242 static const BYTE tga_indexed_mask[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff,0xcf};
1243
1244 static const BYTE tga_truecolor_magic[18] = {0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1245 static const BYTE tga_truecolor_mask[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0x87,0xc0};
1246
1247 static const BYTE tga_grayscale_magic[18] = {0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0};
1248 static const BYTE tga_grayscale_mask[18] = {0,0xff,0xf7,0,0,0,0,0,0,0,0,0,0,0,0,0,0xff,0xcf};
1249
1250 static GUID const * const tga_formats[] = {
1251 &GUID_WICPixelFormat8bppGray,
1252 &GUID_WICPixelFormat8bppIndexed,
1253 &GUID_WICPixelFormat16bppGray,
1254 &GUID_WICPixelFormat16bppBGR555,
1255 &GUID_WICPixelFormat24bppBGR,
1256 &GUID_WICPixelFormat32bppBGRA,
1257 &GUID_WICPixelFormat32bppPBGRA,
1258 NULL
1259 };
1260
1261 static struct decoder_pattern const tga_patterns[] = {
1262 {18,18,tga_footer_magic,mask_all,1},
1263 {18,0,tga_indexed_magic,tga_indexed_mask,0},
1264 {18,0,tga_truecolor_magic,tga_truecolor_mask,0},
1265 {18,0,tga_grayscale_magic,tga_grayscale_mask,0},
1266 {0}
1267 };
1268
1269 static struct regsvr_decoder const decoder_list[] = {
1270 { &CLSID_WICBmpDecoder,
1271 "The Wine Project",
1272 "BMP Decoder",
1273 "1.0.0.0",
1274 &GUID_VendorMicrosoft,
1275 &GUID_ContainerFormatBmp,
1276 "image/bmp",
1277 ".bmp,.dib,.rle",
1278 bmp_formats,
1279 bmp_patterns
1280 },
1281 { &CLSID_WICGifDecoder,
1282 "The Wine Project",
1283 "GIF Decoder",
1284 "1.0.0.0",
1285 &GUID_VendorMicrosoft,
1286 &GUID_ContainerFormatGif,
1287 "image/gif",
1288 ".gif",
1289 gif_formats,
1290 gif_patterns
1291 },
1292 { &CLSID_WICIcoDecoder,
1293 "The Wine Project",
1294 "ICO Decoder",
1295 "1.0.0.0",
1296 &GUID_VendorMicrosoft,
1297 &GUID_ContainerFormatIco,
1298 "image/vnd.microsoft.icon",
1299 ".ico",
1300 ico_formats,
1301 ico_patterns
1302 },
1303 { &CLSID_WICJpegDecoder,
1304 "The Wine Project",
1305 "JPEG Decoder",
1306 "1.0.0.0",
1307 &GUID_VendorMicrosoft,
1308 &GUID_ContainerFormatJpeg,
1309 "image/jpeg",
1310 ".jpg;.jpeg;.jfif",
1311 jpeg_formats,
1312 jpeg_patterns
1313 },
1314 { &CLSID_WICPngDecoder,
1315 "The Wine Project",
1316 "PNG Decoder",
1317 "1.0.0.0",
1318 &GUID_VendorMicrosoft,
1319 &GUID_ContainerFormatPng,
1320 "image/png",
1321 ".png",
1322 png_formats,
1323 png_patterns
1324 },
1325 { &CLSID_WICTiffDecoder,
1326 "The Wine Project",
1327 "TIFF Decoder",
1328 "1.0.0.0",
1329 &GUID_VendorMicrosoft,
1330 &GUID_ContainerFormatTiff,
1331 "image/tiff",
1332 ".tif;.tiff",
1333 tiff_decode_formats,
1334 tiff_patterns
1335 },
1336 { &CLSID_WineTgaDecoder,
1337 "The Wine Project",
1338 "TGA Decoder",
1339 "1.0.0.0",
1340 &GUID_VendorWine,
1341 &GUID_WineContainerFormatTga,
1342 "image/x-targa",
1343 ".tga;.tpic",
1344 tga_formats,
1345 tga_patterns
1346 },
1347 { NULL } /* list terminator */
1348 };
1349
1350 static GUID const * const bmp_encode_formats[] = {
1351 &GUID_WICPixelFormat16bppBGR555,
1352 &GUID_WICPixelFormat16bppBGR565,
1353 &GUID_WICPixelFormat24bppBGR,
1354 &GUID_WICPixelFormat32bppBGR,
1355 &GUID_WICPixelFormatBlackWhite,
1356 &GUID_WICPixelFormat1bppIndexed,
1357 &GUID_WICPixelFormat4bppIndexed,
1358 &GUID_WICPixelFormat8bppIndexed,
1359 NULL
1360 };
1361
1362 static GUID const * const png_encode_formats[] = {
1363 &GUID_WICPixelFormat24bppBGR,
1364 &GUID_WICPixelFormatBlackWhite,
1365 &GUID_WICPixelFormat2bppGray,
1366 &GUID_WICPixelFormat4bppGray,
1367 &GUID_WICPixelFormat8bppGray,
1368 &GUID_WICPixelFormat16bppGray,
1369 &GUID_WICPixelFormat32bppBGR,
1370 &GUID_WICPixelFormat32bppBGRA,
1371 &GUID_WICPixelFormat48bppRGB,
1372 &GUID_WICPixelFormat64bppRGBA,
1373 &GUID_WICPixelFormat1bppIndexed,
1374 &GUID_WICPixelFormat2bppIndexed,
1375 &GUID_WICPixelFormat4bppIndexed,
1376 &GUID_WICPixelFormat8bppIndexed,
1377 NULL
1378 };
1379
1380 static GUID const * const tiff_encode_formats[] = {
1381 &GUID_WICPixelFormatBlackWhite,
1382 &GUID_WICPixelFormat4bppGray,
1383 &GUID_WICPixelFormat8bppGray,
1384 &GUID_WICPixelFormat1bppIndexed,
1385 &GUID_WICPixelFormat4bppIndexed,
1386 &GUID_WICPixelFormat8bppIndexed,
1387 &GUID_WICPixelFormat24bppBGR,
1388 &GUID_WICPixelFormat32bppBGRA,
1389 &GUID_WICPixelFormat32bppPBGRA,
1390 &GUID_WICPixelFormat48bppRGB,
1391 &GUID_WICPixelFormat64bppRGBA,
1392 &GUID_WICPixelFormat64bppPRGBA,
1393 NULL
1394 };
1395
1396 static GUID const * const icns_encode_formats[] = {
1397 &GUID_WICPixelFormat32bppBGRA,
1398 NULL
1399 };
1400
1401 static struct regsvr_encoder const encoder_list[] = {
1402 { &CLSID_WICBmpEncoder,
1403 "The Wine Project",
1404 "BMP Encoder",
1405 "1.0.0.0",
1406 &GUID_VendorMicrosoft,
1407 &GUID_ContainerFormatBmp,
1408 "image/bmp",
1409 ".bmp,.dib,.rle",
1410 bmp_encode_formats
1411 },
1412 { &CLSID_WICGifEncoder,
1413 "The Wine Project",
1414 "GIF Encoder",
1415 "1.0.0.0",
1416 &GUID_VendorMicrosoft,
1417 &GUID_ContainerFormatGif,
1418 "image/gif",
1419 ".gif",
1420 gif_formats
1421 },
1422 { &CLSID_WICJpegEncoder,
1423 "The Wine Project",
1424 "JPEG Encoder",
1425 "1.0.0.0",
1426 &GUID_VendorMicrosoft,
1427 &GUID_ContainerFormatJpeg,
1428 "image/jpeg",
1429 ".jpg;.jpeg;.jfif",
1430 jpeg_formats
1431 },
1432 { &CLSID_WICPngEncoder,
1433 "The Wine Project",
1434 "PNG Encoder",
1435 "1.0.0.0",
1436 &GUID_VendorMicrosoft,
1437 &GUID_ContainerFormatPng,
1438 "image/png",
1439 ".png",
1440 png_encode_formats
1441 },
1442 { &CLSID_WICTiffEncoder,
1443 "The Wine Project",
1444 "TIFF Encoder",
1445 "1.0.0.0",
1446 &GUID_VendorMicrosoft,
1447 &GUID_ContainerFormatTiff,
1448 "image/tiff",
1449 ".tif;.tiff",
1450 tiff_encode_formats
1451 },
1452 { &CLSID_WICIcnsEncoder,
1453 "The Wine Project",
1454 "ICNS Encoder",
1455 "1.0.0.0",
1456 &GUID_VendorWine,
1457 NULL, /* no container format guid */
1458 "image/icns",
1459 ".icns",
1460 icns_encode_formats
1461 },
1462 { NULL } /* list terminator */
1463 };
1464
1465 static GUID const * const converter_formats[] = {
1466 &GUID_WICPixelFormat1bppIndexed,
1467 &GUID_WICPixelFormat2bppIndexed,
1468 &GUID_WICPixelFormat4bppIndexed,
1469 &GUID_WICPixelFormat8bppIndexed,
1470 &GUID_WICPixelFormatBlackWhite,
1471 &GUID_WICPixelFormat2bppGray,
1472 &GUID_WICPixelFormat4bppGray,
1473 &GUID_WICPixelFormat8bppGray,
1474 &GUID_WICPixelFormat16bppGray,
1475 &GUID_WICPixelFormat16bppBGR555,
1476 &GUID_WICPixelFormat16bppBGR565,
1477 &GUID_WICPixelFormat16bppBGRA5551,
1478 &GUID_WICPixelFormat24bppBGR,
1479 &GUID_WICPixelFormat24bppRGB,
1480 &GUID_WICPixelFormat32bppBGR,
1481 &GUID_WICPixelFormat32bppRGB,
1482 &GUID_WICPixelFormat32bppBGRA,
1483 &GUID_WICPixelFormat32bppRGBA,
1484 &GUID_WICPixelFormat32bppPBGRA,
1485 &GUID_WICPixelFormat32bppPRGBA,
1486 &GUID_WICPixelFormat32bppGrayFloat,
1487 &GUID_WICPixelFormat48bppRGB,
1488 &GUID_WICPixelFormat64bppRGBA,
1489 &GUID_WICPixelFormat32bppCMYK,
1490 NULL
1491 };
1492
1493 static struct regsvr_converter const converter_list[] = {
1494 { &CLSID_WICDefaultFormatConverter,
1495 "The Wine Project",
1496 "Default Pixel Format Converter",
1497 "1.0.0.0",
1498 &GUID_VendorMicrosoft,
1499 converter_formats
1500 },
1501 { NULL } /* list terminator */
1502 };
1503
1504 static const BYTE no_magic[1] = { 0 };
1505 static const BYTE no_mask[1] = { 0 };
1506
1507 static const struct metadata_pattern ifd_metadata_pattern[] = {
1508 { 0, 1, no_magic, no_mask, 0 },
1509 { 0 }
1510 };
1511
1512 static const struct reader_containers ifd_containers[] = {
1513 {
1514 &GUID_ContainerFormatTiff,
1515 ifd_metadata_pattern
1516 },
1517 { NULL } /* list terminator */
1518 };
1519
1520 static const BYTE tEXt[] = "tEXt";
1521
1522 static const struct metadata_pattern pngtext_metadata_pattern[] = {
1523 { 4, 4, tEXt, mask_all, 4 },
1524 { 0 }
1525 };
1526
1527 static const struct reader_containers pngtext_containers[] = {
1528 {
1529 &GUID_ContainerFormatPng,
1530 pngtext_metadata_pattern
1531 },
1532 { NULL } /* list terminator */
1533 };
1534
1535 static const BYTE gAMA[] = "gAMA";
1536
1537 static const struct metadata_pattern pnggama_metadata_pattern[] = {
1538 { 4, 4, gAMA, mask_all, 4 },
1539 { 0 }
1540 };
1541
1542 static const struct reader_containers pnggama_containers[] = {
1543 {
1544 &GUID_ContainerFormatPng,
1545 pnggama_metadata_pattern
1546 },
1547 { NULL } /* list terminator */
1548 };
1549
1550 static const BYTE cHRM[] = "cHRM";
1551
1552 static const struct metadata_pattern pngchrm_metadata_pattern[] = {
1553 { 4, 4, cHRM, mask_all, 4 },
1554 { 0 }
1555 };
1556
1557 static const struct reader_containers pngchrm_containers[] = {
1558 {
1559 &GUID_ContainerFormatPng,
1560 pngchrm_metadata_pattern
1561 },
1562 { NULL } /* list terminator */
1563 };
1564
1565 static const struct metadata_pattern lsd_metadata_patterns[] = {
1566 { 0, 6, gif87a_magic, mask_all, 0 },
1567 { 0, 6, gif89a_magic, mask_all, 0 },
1568 { 0 }
1569 };
1570
1571 static const struct reader_containers lsd_containers[] = {
1572 {
1573 &GUID_ContainerFormatGif,
1574 lsd_metadata_patterns
1575 },
1576 { NULL } /* list terminator */
1577 };
1578
1579 static const BYTE imd_magic[] = { 0x2c };
1580
1581 static const struct metadata_pattern imd_metadata_pattern[] = {
1582 { 0, 1, imd_magic, mask_all, 1 },
1583 { 0 }
1584 };
1585
1586 static const struct reader_containers imd_containers[] = {
1587 {
1588 &GUID_ContainerFormatGif,
1589 imd_metadata_pattern
1590 },
1591 { NULL } /* list terminator */
1592 };
1593
1594 static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 };
1595
1596 static const struct metadata_pattern gce_metadata_pattern[] = {
1597 { 0, 3, gce_magic, mask_all, 3 },
1598 { 0 }
1599 };
1600
1601 static const struct reader_containers gce_containers[] = {
1602 {
1603 &GUID_ContainerFormatGif,
1604 gce_metadata_pattern
1605 },
1606 { NULL } /* list terminator */
1607 };
1608
1609 static const BYTE ape_magic[] = { 0x21, 0xff, 0x0b };
1610
1611 static const struct metadata_pattern ape_metadata_pattern[] = {
1612 { 0, 3, ape_magic, mask_all, 0 },
1613 { 0 }
1614 };
1615
1616 static const struct reader_containers ape_containers[] = {
1617 {
1618 &GUID_ContainerFormatGif,
1619 ape_metadata_pattern
1620 },
1621 { NULL } /* list terminator */
1622 };
1623
1624 static const BYTE gif_comment_magic[] = { 0x21, 0xfe };
1625
1626 static const struct metadata_pattern gif_comment_metadata_pattern[] = {
1627 { 0, 2, gif_comment_magic, mask_all, 0 },
1628 { 0 }
1629 };
1630
1631 static const struct reader_containers gif_comment_containers[] = {
1632 {
1633 &GUID_ContainerFormatGif,
1634 gif_comment_metadata_pattern
1635 },
1636 { NULL } /* list terminator */
1637 };
1638
1639 static struct regsvr_metadatareader const metadatareader_list[] = {
1640 { &CLSID_WICUnknownMetadataReader,
1641 "The Wine Project",
1642 "Unknown Metadata Reader",
1643 "1.0.0.0",
1644 "1.0.0.0",
1645 &GUID_VendorMicrosoft,
1646 &GUID_MetadataFormatUnknown,
1647 0, 0, 0,
1648 NULL
1649 },
1650 { &CLSID_WICIfdMetadataReader,
1651 "The Wine Project",
1652 "Ifd Reader",
1653 "1.0.0.0",
1654 "1.0.0.0",
1655 &GUID_VendorMicrosoft,
1656 &GUID_MetadataFormatIfd,
1657 1, 1, 0,
1658 ifd_containers
1659 },
1660 { &CLSID_WICPngChrmMetadataReader,
1661 "The Wine Project",
1662 "Chunk cHRM Reader",
1663 "1.0.0.0",
1664 "1.0.0.0",
1665 &GUID_VendorMicrosoft,
1666 &GUID_MetadataFormatChunkcHRM,
1667 0, 0, 0,
1668 pngchrm_containers
1669 },
1670 { &CLSID_WICPngGamaMetadataReader,
1671 "The Wine Project",
1672 "Chunk gAMA Reader",
1673 "1.0.0.0",
1674 "1.0.0.0",
1675 &GUID_VendorMicrosoft,
1676 &GUID_MetadataFormatChunkgAMA,
1677 0, 0, 0,
1678 pnggama_containers
1679 },
1680 { &CLSID_WICPngTextMetadataReader,
1681 "The Wine Project",
1682 "Chunk tEXt Reader",
1683 "1.0.0.0",
1684 "1.0.0.0",
1685 &GUID_VendorMicrosoft,
1686 &GUID_MetadataFormatChunktEXt,
1687 0, 0, 0,
1688 pngtext_containers
1689 },
1690 { &CLSID_WICLSDMetadataReader,
1691 "The Wine Project",
1692 "Logical Screen Descriptor Reader",
1693 "1.0.0.0",
1694 "1.0.0.0",
1695 &GUID_VendorMicrosoft,
1696 &GUID_MetadataFormatLSD,
1697 0, 0, 0,
1698 lsd_containers
1699 },
1700 { &CLSID_WICIMDMetadataReader,
1701 "The Wine Project",
1702 "Image Descriptor Reader",
1703 "1.0.0.0",
1704 "1.0.0.0",
1705 &GUID_VendorMicrosoft,
1706 &GUID_MetadataFormatIMD,
1707 0, 0, 0,
1708 imd_containers
1709 },
1710 { &CLSID_WICGCEMetadataReader,
1711 "The Wine Project",
1712 "Graphic Control Extension Reader",
1713 "1.0.0.0",
1714 "1.0.0.0",
1715 &GUID_VendorMicrosoft,
1716 &GUID_MetadataFormatGCE,
1717 0, 0, 0,
1718 gce_containers
1719 },
1720 { &CLSID_WICAPEMetadataReader,
1721 "The Wine Project",
1722 "Application Extension Reader",
1723 "1.0.0.0",
1724 "1.0.0.0",
1725 &GUID_VendorMicrosoft,
1726 &GUID_MetadataFormatAPE,
1727 0, 0, 0,
1728 ape_containers
1729 },
1730 { &CLSID_WICGifCommentMetadataReader,
1731 "The Wine Project",
1732 "Comment Extension Reader",
1733 "1.0.0.0",
1734 "1.0.0.0",
1735 &GUID_VendorMicrosoft,
1736 &GUID_MetadataFormatGifComment,
1737 0, 0, 0,
1738 gif_comment_containers
1739 },
1740 { NULL } /* list terminator */
1741 };
1742
1743 static BYTE const channel_mask_1bit[] = { 0x01 };
1744 static BYTE const channel_mask_2bit[] = { 0x03 };
1745 static BYTE const channel_mask_4bit[] = { 0x0f };
1746
1747 static BYTE const channel_mask_8bit[] = { 0xff, 0x00, 0x00, 0x00 };
1748 static BYTE const channel_mask_8bit2[] = { 0x00, 0xff, 0x00, 0x00 };
1749 static BYTE const channel_mask_8bit3[] = { 0x00, 0x00, 0xff, 0x00 };
1750 static BYTE const channel_mask_8bit4[] = { 0x00, 0x00, 0x00, 0xff };
1751
1752 static BYTE const channel_mask_16bit[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1753 static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1754 static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
1755 static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
1756
1757 static BYTE const channel_mask_32bit[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
1758
1759 static BYTE const channel_mask_128bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1760 static BYTE const channel_mask_128bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
1761 static BYTE const channel_mask_128bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 };
1762 static BYTE const channel_mask_128bit4[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff };
1763
1764 static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 };
1765 static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 };
1766 static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c };
1767 static BYTE const channel_mask_5bit4[] = { 0x00, 0x80 };
1768
1769 static BYTE const channel_mask_BGR565_2[] = { 0xe0, 0x07 };
1770 static BYTE const channel_mask_BGR565_3[] = { 0x00, 0xf8 };
1771
1772 static BYTE const * const channel_masks_1bit[] = { channel_mask_1bit };
1773 static BYTE const * const channel_masks_2bit[] = { channel_mask_2bit };
1774 static BYTE const * const channel_masks_4bit[] = { channel_mask_4bit };
1775 static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit,
1776 channel_mask_8bit2, channel_mask_8bit3, channel_mask_8bit4 };
1777 static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit,
1778 channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4};
1779
1780 static BYTE const * const channel_masks_32bit[] = { channel_mask_32bit };
1781 static BYTE const * const channel_masks_128bit[] = { channel_mask_128bit1, channel_mask_128bit2, channel_mask_128bit3, channel_mask_128bit4 };
1782
1783 static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit,
1784 channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 };
1785
1786 static BYTE const * const channel_masks_BGR565[] = { channel_mask_5bit,
1787 channel_mask_BGR565_2, channel_mask_BGR565_3 };
1788
1789 static struct regsvr_pixelformat const pixelformat_list[] = {
1790 { &GUID_WICPixelFormat1bppIndexed,
1791 "The Wine Project",
1792 "1bpp Indexed",
1793 NULL, /* no version */
1794 &GUID_VendorMicrosoft,
1795 1, /* bitsperpixel */
1796 1, /* channel count */
1797 channel_masks_1bit,
1798 WICPixelFormatNumericRepresentationIndexed,
1799 0
1800 },
1801 { &GUID_WICPixelFormat2bppIndexed,
1802 "The Wine Project",
1803 "2bpp Indexed",
1804 NULL, /* no version */
1805 &GUID_VendorMicrosoft,
1806 2, /* bitsperpixel */
1807 1, /* channel count */
1808 channel_masks_2bit,
1809 WICPixelFormatNumericRepresentationIndexed,
1810 0
1811 },
1812 { &GUID_WICPixelFormat4bppIndexed,
1813 "The Wine Project",
1814 "4bpp Indexed",
1815 NULL, /* no version */
1816 &GUID_VendorMicrosoft,
1817 4, /* bitsperpixel */
1818 1, /* channel count */
1819 channel_masks_4bit,
1820 WICPixelFormatNumericRepresentationIndexed,
1821 0
1822 },
1823 { &GUID_WICPixelFormat8bppIndexed,
1824 "The Wine Project",
1825 "8bpp Indexed",
1826 NULL, /* no version */
1827 &GUID_VendorMicrosoft,
1828 8, /* bitsperpixel */
1829 1, /* channel count */
1830 channel_masks_8bit,
1831 WICPixelFormatNumericRepresentationIndexed,
1832 0
1833 },
1834 { &GUID_WICPixelFormatBlackWhite,
1835 "The Wine Project",
1836 "Black and White",
1837 NULL, /* no version */
1838 &GUID_VendorMicrosoft,
1839 1, /* bitsperpixel */
1840 1, /* channel count */
1841 channel_masks_1bit,
1842 WICPixelFormatNumericRepresentationUnsignedInteger,
1843 0
1844 },
1845 { &GUID_WICPixelFormat2bppGray,
1846 "The Wine Project",
1847 "2bpp Grayscale",
1848 NULL, /* no version */
1849 &GUID_VendorMicrosoft,
1850 2, /* bitsperpixel */
1851 1, /* channel count */
1852 channel_masks_2bit,
1853 WICPixelFormatNumericRepresentationUnsignedInteger,
1854 0
1855 },
1856 { &GUID_WICPixelFormat4bppGray,
1857 "The Wine Project",
1858 "4bpp Grayscale",
1859 NULL, /* no version */
1860 &GUID_VendorMicrosoft,
1861 4, /* bitsperpixel */
1862 1, /* channel count */
1863 channel_masks_4bit,
1864 WICPixelFormatNumericRepresentationUnsignedInteger,
1865 0
1866 },
1867 { &GUID_WICPixelFormat8bppGray,
1868 "The Wine Project",
1869 "8bpp Grayscale",
1870 NULL, /* no version */
1871 &GUID_VendorMicrosoft,
1872 8, /* bitsperpixel */
1873 1, /* channel count */
1874 channel_masks_8bit,
1875 WICPixelFormatNumericRepresentationUnsignedInteger,
1876 0
1877 },
1878 { &GUID_WICPixelFormat16bppGray,
1879 "The Wine Project",
1880 "16bpp Grayscale",
1881 NULL, /* no version */
1882 &GUID_VendorMicrosoft,
1883 16, /* bitsperpixel */
1884 1, /* channel count */
1885 channel_masks_16bit,
1886 WICPixelFormatNumericRepresentationUnsignedInteger,
1887 0
1888 },
1889 { &GUID_WICPixelFormat16bppBGR555,
1890 "The Wine Project",
1891 "16bpp BGR555",
1892 NULL, /* no version */
1893 &GUID_VendorMicrosoft,
1894 16, /* bitsperpixel */
1895 3, /* channel count */
1896 channel_masks_BGRA5551,
1897 WICPixelFormatNumericRepresentationUnsignedInteger,
1898 0
1899 },
1900 { &GUID_WICPixelFormat16bppBGR565,
1901 "The Wine Project",
1902 "16bpp BGR565",
1903 NULL, /* no version */
1904 &GUID_VendorMicrosoft,
1905 16, /* bitsperpixel */
1906 3, /* channel count */
1907 channel_masks_BGR565,
1908 WICPixelFormatNumericRepresentationUnsignedInteger,
1909 0
1910 },
1911 { &GUID_WICPixelFormat16bppBGRA5551,
1912 "The Wine Project",
1913 "16bpp BGRA5551",
1914 NULL, /* no version */
1915 &GUID_VendorMicrosoft,
1916 16, /* bitsperpixel */
1917 4, /* channel count */
1918 channel_masks_BGRA5551,
1919 WICPixelFormatNumericRepresentationUnsignedInteger,
1920 1
1921 },
1922 { &GUID_WICPixelFormat24bppBGR,
1923 "The Wine Project",
1924 "24bpp BGR",
1925 NULL, /* no version */
1926 &GUID_VendorMicrosoft,
1927 24, /* bitsperpixel */
1928 3, /* channel count */
1929 channel_masks_8bit,
1930 WICPixelFormatNumericRepresentationUnsignedInteger,
1931 0
1932 },
1933 { &GUID_WICPixelFormat24bppRGB,
1934 "The Wine Project",
1935 "24bpp RGB",
1936 NULL, /* no version */
1937 &GUID_VendorMicrosoft,
1938 24, /* bitsperpixel */
1939 3, /* channel count */
1940 channel_masks_8bit,
1941 WICPixelFormatNumericRepresentationUnsignedInteger,
1942 0
1943 },
1944 { &GUID_WICPixelFormat32bppBGR,
1945 "The Wine Project",
1946 "32bpp BGR",
1947 NULL, /* no version */
1948 &GUID_VendorMicrosoft,
1949 32, /* bitsperpixel */
1950 3, /* channel count */
1951 channel_masks_8bit,
1952 WICPixelFormatNumericRepresentationUnsignedInteger,
1953 0
1954 },
1955 { &GUID_WICPixelFormat32bppRGB,
1956 "The Wine Project",
1957 "32bpp RGB",
1958 NULL, /* no version */
1959 &GUID_VendorMicrosoft,
1960 32, /* bitsperpixel */
1961 3, /* channel count */
1962 channel_masks_8bit,
1963 WICPixelFormatNumericRepresentationUnsignedInteger,
1964 0
1965 },
1966 { &GUID_WICPixelFormat32bppBGRA,
1967 "The Wine Project",
1968 "32bpp BGRA",
1969 NULL, /* no version */
1970 &GUID_VendorMicrosoft,
1971 32, /* bitsperpixel */
1972 4, /* channel count */
1973 channel_masks_8bit,
1974 WICPixelFormatNumericRepresentationUnsignedInteger,
1975 1
1976 },
1977 { &GUID_WICPixelFormat32bppRGBA,
1978 "The Wine Project",
1979 "32bpp RGBA",
1980 NULL, /* no version */
1981 &GUID_VendorMicrosoft,
1982 32, /* bitsperpixel */
1983 4, /* channel count */
1984 channel_masks_8bit,
1985 WICPixelFormatNumericRepresentationUnsignedInteger,
1986 1
1987 },
1988 { &GUID_WICPixelFormat32bppPBGRA,
1989 "The Wine Project",
1990 "32bpp PBGRA",
1991 NULL, /* no version */
1992 &GUID_VendorMicrosoft,
1993 32, /* bitsperpixel */
1994 4, /* channel count */
1995 channel_masks_8bit,
1996 WICPixelFormatNumericRepresentationUnsignedInteger,
1997 1
1998 },
1999 { &GUID_WICPixelFormat32bppPRGBA,
2000 "The Wine Project",
2001 "32bpp PRGBA",
2002 NULL, /* no version */
2003 &GUID_VendorMicrosoft,
2004 32, /* bitsperpixel */
2005 4, /* channel count */
2006 channel_masks_8bit,
2007 WICPixelFormatNumericRepresentationUnsignedInteger,
2008 1
2009 },
2010 { &GUID_WICPixelFormat32bppGrayFloat,
2011 "The Wine Project",
2012 "32bpp GrayFloat",
2013 NULL, /* no version */
2014 &GUID_VendorMicrosoft,
2015 32, /* bitsperpixel */
2016 1, /* channel count */
2017 channel_masks_32bit,
2018 WICPixelFormatNumericRepresentationFloat,
2019 0
2020 },
2021 { &GUID_WICPixelFormat48bppRGB,
2022 "The Wine Project",
2023 "48bpp RGB",
2024 NULL, /* no version */
2025 &GUID_VendorMicrosoft,
2026 48, /* bitsperpixel */
2027 3, /* channel count */
2028 channel_masks_16bit,
2029 WICPixelFormatNumericRepresentationUnsignedInteger,
2030 0
2031 },
2032 { &GUID_WICPixelFormat64bppRGBA,
2033 "The Wine Project",
2034 "64bpp RGBA",
2035 NULL, /* no version */
2036 &GUID_VendorMicrosoft,
2037 64, /* bitsperpixel */
2038 4, /* channel count */
2039 channel_masks_16bit,
2040 WICPixelFormatNumericRepresentationUnsignedInteger,
2041 1
2042 },
2043 { &GUID_WICPixelFormat64bppPRGBA,
2044 "The Wine Project",
2045 "64bpp PRGBA",
2046 NULL, /* no version */
2047 &GUID_VendorMicrosoft,
2048 64, /* bitsperpixel */
2049 4, /* channel count */
2050 channel_masks_16bit,
2051 WICPixelFormatNumericRepresentationUnsignedInteger,
2052 1
2053 },
2054 { &GUID_WICPixelFormat32bppCMYK,
2055 "The Wine Project",
2056 "32bpp CMYK",
2057 NULL, /* no version */
2058 &GUID_VendorMicrosoft,
2059 32, /* bitsperpixel */
2060 4, /* channel count */
2061 channel_masks_8bit,
2062 WICPixelFormatNumericRepresentationUnsignedInteger,
2063 0
2064 },
2065 { &GUID_WICPixelFormat64bppCMYK,
2066 "The Wine Project",
2067 "64bpp CMYK",
2068 NULL, /* no version */
2069 &GUID_VendorMicrosoft,
2070 64, /* bitsperpixel */
2071 4, /* channel count */
2072 channel_masks_16bit,
2073 WICPixelFormatNumericRepresentationUnsignedInteger,
2074 0
2075 },
2076 { &GUID_WICPixelFormat128bppRGBAFloat,
2077 "The Wine Project",
2078 "128bpp RGBAFloat",
2079 NULL, /* no version */
2080 &GUID_VendorMicrosoft,
2081 128, /* bitsperpixel */
2082 4, /* channel count */
2083 channel_masks_128bit,
2084 WICPixelFormatNumericRepresentationFloat,
2085 1
2086 },
2087 { NULL } /* list terminator */
2088 };
2089
2090 struct regsvr_category
2091 {
2092 const CLSID *clsid; /* NULL for end of list */
2093 };
2094
2095 static const struct regsvr_category category_list[] = {
2096 { &CATID_WICBitmapDecoders },
2097 { &CATID_WICBitmapEncoders },
2098 { &CATID_WICFormatConverters },
2099 { &CATID_WICMetadataReader },
2100 { &CATID_WICPixelFormats },
2101 { NULL }
2102 };
2103
2104 static HRESULT register_categories(const struct regsvr_category *list)
2105 {
2106 LONG res;
2107 WCHAR buf[39];
2108 HKEY coclass_key, categories_key, instance_key;
2109
2110 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
2111 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
2112 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
2113
2114 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2115 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
2116 KEY_READ | KEY_WRITE, NULL, &categories_key, NULL);
2117 if (res != ERROR_SUCCESS)
2118 {
2119 RegCloseKey(coclass_key);
2120 return HRESULT_FROM_WIN32(res);
2121 }
2122
2123 res = RegCreateKeyExW(categories_key, instance_keyname, 0, NULL, 0,
2124 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
2125
2126 for (; res == ERROR_SUCCESS && list->clsid; list++)
2127 {
2128 HKEY instance_clsid_key;
2129
2130 StringFromGUID2(list->clsid, buf, 39);
2131 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
2132 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
2133 if (res == ERROR_SUCCESS)
2134 {
2135 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
2136 (const BYTE *)buf, 78);
2137 RegCloseKey(instance_clsid_key);
2138 }
2139 }
2140
2141 RegCloseKey(instance_key);
2142 RegCloseKey(categories_key);
2143 RegCloseKey(coclass_key);
2144
2145 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
2146 }
2147
2148 static HRESULT unregister_categories(const struct regsvr_category *list)
2149 {
2150 LONG res;
2151 WCHAR buf[39];
2152 HKEY coclass_key, categories_key, instance_key;
2153
2154 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
2155 KEY_READ | KEY_WRITE, &coclass_key);
2156 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);
2157
2158 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2159 res = RegOpenKeyExW(coclass_key, buf, 0,
2160 KEY_READ | KEY_WRITE, &categories_key);
2161 if (res != ERROR_SUCCESS)
2162 {
2163 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
2164 RegCloseKey(coclass_key);
2165 return HRESULT_FROM_WIN32(res);
2166 }
2167
2168 res = RegOpenKeyExW(categories_key, instance_keyname, 0,
2169 KEY_READ | KEY_WRITE, &instance_key);
2170
2171 for (; res == ERROR_SUCCESS && list->clsid; list++)
2172 {
2173 StringFromGUID2(list->clsid, buf, 39);
2174 res = RegDeleteTreeW(instance_key, buf);
2175 }
2176
2177 RegCloseKey(instance_key);
2178 RegCloseKey(categories_key);
2179
2180 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39);
2181 res = RegDeleteTreeW(coclass_key, buf);
2182
2183 RegCloseKey(coclass_key);
2184
2185 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
2186 }
2187
2188 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN;
2189 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN;
2190
2191 HRESULT WINAPI DllRegisterServer(void)
2192 {
2193 HRESULT hr;
2194
2195 TRACE("\n");
2196
2197 hr = WIC_DllRegisterServer();
2198 if (SUCCEEDED(hr))
2199 hr = register_categories(category_list);
2200 if (SUCCEEDED(hr))
2201 hr = register_decoders(decoder_list);
2202 if (SUCCEEDED(hr))
2203 hr = register_encoders(encoder_list);
2204 if (SUCCEEDED(hr))
2205 hr = register_converters(converter_list);
2206 if (SUCCEEDED(hr))
2207 hr = register_metadatareaders(metadatareader_list);
2208 if (SUCCEEDED(hr))
2209 hr = register_pixelformats(pixelformat_list);
2210 return hr;
2211 }
2212
2213 HRESULT WINAPI DllUnregisterServer(void)
2214 {
2215 HRESULT hr;
2216
2217 TRACE("\n");
2218
2219 hr = WIC_DllUnregisterServer();
2220 if (SUCCEEDED(hr))
2221 hr = unregister_categories(category_list);
2222 if (SUCCEEDED(hr))
2223 hr = unregister_decoders(decoder_list);
2224 if (SUCCEEDED(hr))
2225 hr = unregister_encoders(encoder_list);
2226 if (SUCCEEDED(hr))
2227 hr = unregister_converters(converter_list);
2228 if (SUCCEEDED(hr))
2229 hr = unregister_metadatareaders(metadatareader_list);
2230 if (SUCCEEDED(hr))
2231 hr = unregister_pixelformats(pixelformat_list);
2232 return hr;
2233 }