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