windowscodecs: Add metadata reader information to the registry.
[wine/multimedia.git] / dlls / windowscodecs / regsvr.c
blob9dfe37ba9dcb0b5c8f78c207989fca94ff476c05
1 /*
2 * Copyright 2009 Vincent Povirk for CodeWeavers
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.
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.
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
19 #define NONAMELESSUNION
20 #define NONAMELESSSTRUCT
21 #define COBJMACROS
22 #include <stdarg.h>
23 #include <string.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "winreg.h"
30 #include "winerror.h"
32 #include "objbase.h"
33 #include "ocidl.h"
34 #include "wincodec.h"
35 #include "wincodecsdk.h"
37 #include "wine/debug.h"
38 #include "wine/unicode.h"
40 #include "wincodecs_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
44 /***********************************************************************
45 * interface for self-registering
47 struct decoder_pattern
49 DWORD length; /* 0 for end of list */
50 DWORD position;
51 const BYTE *pattern;
52 const BYTE *mask;
53 DWORD endofstream;
56 struct regsvr_decoder
58 CLSID const *clsid; /* NULL for end of list */
59 LPCSTR author;
60 LPCSTR friendlyname;
61 LPCSTR version;
62 GUID const *vendor;
63 GUID const *container_format;
64 LPCSTR mimetypes;
65 LPCSTR extensions;
66 GUID const * const *formats;
67 const struct decoder_pattern *patterns;
70 static HRESULT register_decoders(struct regsvr_decoder const *list);
71 static HRESULT unregister_decoders(struct regsvr_decoder const *list);
73 struct regsvr_encoder
75 CLSID const *clsid; /* NULL for end of list */
76 LPCSTR author;
77 LPCSTR friendlyname;
78 LPCSTR version;
79 GUID const *vendor;
80 GUID const *container_format;
81 LPCSTR mimetypes;
82 LPCSTR extensions;
83 GUID const * const *formats;
86 static HRESULT register_encoders(struct regsvr_encoder const *list);
87 static HRESULT unregister_encoders(struct regsvr_encoder const *list);
89 struct regsvr_converter
91 CLSID const *clsid; /* NULL for end of list */
92 LPCSTR author;
93 LPCSTR friendlyname;
94 LPCSTR version;
95 GUID const *vendor;
96 GUID const * const *formats;
99 static HRESULT register_converters(struct regsvr_converter const *list);
100 static HRESULT unregister_converters(struct regsvr_converter const *list);
102 struct metadata_pattern
104 DWORD position;
105 DWORD length;
106 const BYTE *pattern;
107 const BYTE *mask;
108 DWORD data_offset;
111 struct reader_containers
113 GUID const *format;
114 const struct metadata_pattern *patterns;
117 struct regsvr_metadatareader
119 CLSID const *clsid; /* NULL for end of list */
120 LPCSTR author;
121 LPCSTR friendlyname;
122 LPCSTR version;
123 LPCSTR specversion;
124 GUID const *vendor;
125 GUID const *metadata_format;
126 DWORD requires_fullstream;
127 DWORD supports_padding;
128 DWORD requires_fixedsize;
129 const struct reader_containers *containers;
132 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list);
133 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list);
135 /***********************************************************************
136 * static string constants
138 static const WCHAR clsid_keyname[] = {
139 'C', 'L', 'S', 'I', 'D', 0 };
140 static const WCHAR curver_keyname[] = {
141 'C', 'u', 'r', 'V', 'e', 'r', 0 };
142 static const WCHAR ips_keyname[] = {
143 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
144 0 };
145 static const WCHAR ips32_keyname[] = {
146 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
147 '3', '2', 0 };
148 static const WCHAR progid_keyname[] = {
149 'P', 'r', 'o', 'g', 'I', 'D', 0 };
150 static const WCHAR viprogid_keyname[] = {
151 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
152 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
153 0 };
154 static const char tmodel_valuename[] = "ThreadingModel";
155 static const char author_valuename[] = "Author";
156 static const char friendlyname_valuename[] = "FriendlyName";
157 static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
158 static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
159 static const char version_valuename[] = "Version";
160 static const char mimetypes_valuename[] = "MimeTypes";
161 static const char extensions_valuename[] = "FileExtensions";
162 static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0};
163 static const WCHAR patterns_keyname[] = {'P','a','t','t','e','r','n','s',0};
164 static const WCHAR instance_keyname[] = {'I','n','s','t','a','n','c','e',0};
165 static const WCHAR clsid_valuename[] = {'C','L','S','I','D',0};
166 static const char length_valuename[] = "Length";
167 static const char position_valuename[] = "Position";
168 static const char pattern_valuename[] = "Pattern";
169 static const char mask_valuename[] = "Mask";
170 static const char endofstream_valuename[] = "EndOfStream";
171 static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
172 static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
173 static const char specversion_valuename[] = "SpecVersion";
174 static const char requiresfullstream_valuename[] = "RequiresFullStream";
175 static const char supportspadding_valuename[] = "SupportsPadding";
176 static const char requiresfixedsize_valuename[] = "FixedSize";
177 static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','s',0};
178 static const char dataoffset_valuename[] = "DataOffset";
180 /***********************************************************************
181 * register_decoders
183 static HRESULT register_decoders(struct regsvr_decoder const *list)
185 LONG res = ERROR_SUCCESS;
186 HKEY coclass_key;
187 WCHAR buf[39];
188 HKEY decoders_key;
189 HKEY instance_key;
191 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
192 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
193 if (res == ERROR_SUCCESS) {
194 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
195 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
196 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
197 if (res == ERROR_SUCCESS)
199 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
200 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
201 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
203 if (res != ERROR_SUCCESS)
204 RegCloseKey(coclass_key);
206 if (res != ERROR_SUCCESS) goto error_return;
208 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
209 HKEY clsid_key;
210 HKEY instance_clsid_key;
212 StringFromGUID2(list->clsid, buf, 39);
213 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
214 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
215 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
217 StringFromGUID2(list->clsid, buf, 39);
218 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
219 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
220 if (res == ERROR_SUCCESS) {
221 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
222 (CONST BYTE*)(buf), 78);
223 RegCloseKey(instance_clsid_key);
225 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
227 if (list->author) {
228 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
229 (CONST BYTE*)(list->author),
230 strlen(list->author) + 1);
231 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
234 if (list->friendlyname) {
235 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
236 (CONST BYTE*)(list->friendlyname),
237 strlen(list->friendlyname) + 1);
238 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
241 if (list->vendor) {
242 StringFromGUID2(list->vendor, buf, 39);
243 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
244 (CONST BYTE*)(buf), 78);
245 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
248 if (list->container_format) {
249 StringFromGUID2(list->container_format, buf, 39);
250 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
251 (CONST BYTE*)(buf), 78);
252 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
255 if (list->version) {
256 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
257 (CONST BYTE*)(list->version),
258 strlen(list->version) + 1);
259 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
262 if (list->mimetypes) {
263 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
264 (CONST BYTE*)(list->mimetypes),
265 strlen(list->mimetypes) + 1);
266 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
269 if (list->extensions) {
270 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
271 (CONST BYTE*)(list->extensions),
272 strlen(list->extensions) + 1);
273 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
276 if (list->formats) {
277 HKEY formats_key;
278 GUID const * const *format;
280 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
281 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
282 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
283 for (format=list->formats; *format; ++format)
285 HKEY format_key;
286 StringFromGUID2(*format, buf, 39);
287 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
288 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
289 if (res != ERROR_SUCCESS) break;
290 RegCloseKey(format_key);
292 RegCloseKey(formats_key);
293 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
296 if (list->patterns) {
297 HKEY patterns_key;
298 int i;
300 res = RegCreateKeyExW(clsid_key, patterns_keyname, 0, NULL, 0,
301 KEY_READ | KEY_WRITE, NULL, &patterns_key, NULL);
302 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
303 for (i=0; list->patterns[i].length; i++)
305 HKEY pattern_key;
306 static const WCHAR int_format[] = {'%','i',0};
307 snprintfW(buf, 39, int_format, i);
308 res = RegCreateKeyExW(patterns_key, buf, 0, NULL, 0,
309 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
310 if (res != ERROR_SUCCESS) break;
311 res = RegSetValueExA(pattern_key, length_valuename, 0, REG_DWORD,
312 (CONST BYTE*)(&list->patterns[i].length), 4);
313 if (res == ERROR_SUCCESS)
314 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
315 (CONST BYTE*)(&list->patterns[i].position), 4);
316 if (res == ERROR_SUCCESS)
317 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
318 list->patterns[i].pattern,
319 list->patterns[i].length);
320 if (res == ERROR_SUCCESS)
321 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
322 list->patterns[i].mask,
323 list->patterns[i].length);
324 if (res == ERROR_SUCCESS)
325 res = RegSetValueExA(pattern_key, endofstream_valuename, 0, REG_DWORD,
326 (CONST BYTE*)&(list->patterns[i].endofstream), 4);
327 RegCloseKey(pattern_key);
329 RegCloseKey(patterns_key);
330 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
333 error_close_clsid_key:
334 RegCloseKey(clsid_key);
337 error_close_coclass_key:
338 RegCloseKey(instance_key);
339 RegCloseKey(decoders_key);
340 RegCloseKey(coclass_key);
341 error_return:
342 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
345 /***********************************************************************
346 * unregister_decoders
348 static HRESULT unregister_decoders(struct regsvr_decoder const *list)
350 LONG res = ERROR_SUCCESS;
351 HKEY coclass_key;
352 WCHAR buf[39];
353 HKEY decoders_key;
354 HKEY instance_key;
356 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
357 KEY_READ | KEY_WRITE, &coclass_key);
358 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
360 if (res == ERROR_SUCCESS) {
361 StringFromGUID2(&CATID_WICBitmapDecoders, buf, 39);
362 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
363 KEY_READ | KEY_WRITE, NULL, &decoders_key, NULL);
364 if (res == ERROR_SUCCESS)
366 res = RegCreateKeyExW(decoders_key, instance_keyname, 0, NULL, 0,
367 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
368 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
370 if (res != ERROR_SUCCESS)
371 RegCloseKey(coclass_key);
373 if (res != ERROR_SUCCESS) goto error_return;
375 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
376 StringFromGUID2(list->clsid, buf, 39);
378 res = RegDeleteTreeW(coclass_key, buf);
379 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
380 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
382 res = RegDeleteTreeW(instance_key, buf);
383 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
384 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
387 error_close_coclass_key:
388 RegCloseKey(instance_key);
389 RegCloseKey(decoders_key);
390 RegCloseKey(coclass_key);
391 error_return:
392 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
395 /***********************************************************************
396 * register_encoders
398 static HRESULT register_encoders(struct regsvr_encoder const *list)
400 LONG res = ERROR_SUCCESS;
401 HKEY coclass_key;
402 WCHAR buf[39];
403 HKEY encoders_key;
404 HKEY instance_key;
406 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
407 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
408 if (res == ERROR_SUCCESS) {
409 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
410 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
411 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
412 if (res == ERROR_SUCCESS)
414 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
415 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
416 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
418 if (res != ERROR_SUCCESS)
419 RegCloseKey(coclass_key);
421 if (res != ERROR_SUCCESS) goto error_return;
423 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
424 HKEY clsid_key;
425 HKEY instance_clsid_key;
427 StringFromGUID2(list->clsid, buf, 39);
428 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
429 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
430 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
432 StringFromGUID2(list->clsid, buf, 39);
433 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
434 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
435 if (res == ERROR_SUCCESS) {
436 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
437 (CONST BYTE*)(buf), 78);
438 RegCloseKey(instance_clsid_key);
440 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
442 if (list->author) {
443 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
444 (CONST BYTE*)(list->author),
445 strlen(list->author) + 1);
446 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
449 if (list->friendlyname) {
450 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
451 (CONST BYTE*)(list->friendlyname),
452 strlen(list->friendlyname) + 1);
453 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
456 if (list->vendor) {
457 StringFromGUID2(list->vendor, buf, 39);
458 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
459 (CONST BYTE*)(buf), 78);
460 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
463 if (list->container_format) {
464 StringFromGUID2(list->container_format, buf, 39);
465 res = RegSetValueExW(clsid_key, containerformat_valuename, 0, REG_SZ,
466 (CONST BYTE*)(buf), 78);
467 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
470 if (list->version) {
471 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
472 (CONST BYTE*)(list->version),
473 strlen(list->version) + 1);
474 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
477 if (list->mimetypes) {
478 res = RegSetValueExA(clsid_key, mimetypes_valuename, 0, REG_SZ,
479 (CONST BYTE*)(list->mimetypes),
480 strlen(list->mimetypes) + 1);
481 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
484 if (list->extensions) {
485 res = RegSetValueExA(clsid_key, extensions_valuename, 0, REG_SZ,
486 (CONST BYTE*)(list->extensions),
487 strlen(list->extensions) + 1);
488 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
491 if (list->formats) {
492 HKEY formats_key;
493 GUID const * const *format;
495 res = RegCreateKeyExW(clsid_key, formats_keyname, 0, NULL, 0,
496 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
497 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
498 for (format=list->formats; *format; ++format)
500 HKEY format_key;
501 StringFromGUID2(*format, buf, 39);
502 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
503 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
504 if (res != ERROR_SUCCESS) break;
505 RegCloseKey(format_key);
507 RegCloseKey(formats_key);
508 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
511 error_close_clsid_key:
512 RegCloseKey(clsid_key);
515 error_close_coclass_key:
516 RegCloseKey(instance_key);
517 RegCloseKey(encoders_key);
518 RegCloseKey(coclass_key);
519 error_return:
520 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
523 /***********************************************************************
524 * unregister_encoders
526 static HRESULT unregister_encoders(struct regsvr_encoder const *list)
528 LONG res = ERROR_SUCCESS;
529 HKEY coclass_key;
530 WCHAR buf[39];
531 HKEY encoders_key;
532 HKEY instance_key;
534 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
535 KEY_READ | KEY_WRITE, &coclass_key);
536 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
538 if (res == ERROR_SUCCESS) {
539 StringFromGUID2(&CATID_WICBitmapEncoders, buf, 39);
540 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
541 KEY_READ | KEY_WRITE, NULL, &encoders_key, NULL);
542 if (res == ERROR_SUCCESS)
544 res = RegCreateKeyExW(encoders_key, instance_keyname, 0, NULL, 0,
545 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
546 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
548 if (res != ERROR_SUCCESS)
549 RegCloseKey(coclass_key);
551 if (res != ERROR_SUCCESS) goto error_return;
553 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
554 StringFromGUID2(list->clsid, buf, 39);
556 res = RegDeleteTreeW(coclass_key, buf);
557 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
558 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
560 res = RegDeleteTreeW(instance_key, buf);
561 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
562 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
565 error_close_coclass_key:
566 RegCloseKey(instance_key);
567 RegCloseKey(encoders_key);
568 RegCloseKey(coclass_key);
569 error_return:
570 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
573 /***********************************************************************
574 * register_converters
576 static HRESULT register_converters(struct regsvr_converter const *list)
578 LONG res = ERROR_SUCCESS;
579 HKEY coclass_key;
580 WCHAR buf[39];
581 HKEY converters_key;
582 HKEY instance_key;
584 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
585 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
586 if (res == ERROR_SUCCESS) {
587 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
588 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
589 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
590 if (res == ERROR_SUCCESS)
592 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
593 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
594 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
596 if (res != ERROR_SUCCESS)
597 RegCloseKey(coclass_key);
599 if (res != ERROR_SUCCESS) goto error_return;
601 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
602 HKEY clsid_key;
603 HKEY instance_clsid_key;
605 StringFromGUID2(list->clsid, buf, 39);
606 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
607 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
608 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
610 StringFromGUID2(list->clsid, buf, 39);
611 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
612 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
613 if (res == ERROR_SUCCESS) {
614 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
615 (CONST BYTE*)(buf), 78);
616 RegCloseKey(instance_clsid_key);
618 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
620 if (list->author) {
621 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
622 (CONST BYTE*)(list->author),
623 strlen(list->author) + 1);
624 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
627 if (list->friendlyname) {
628 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
629 (CONST BYTE*)(list->friendlyname),
630 strlen(list->friendlyname) + 1);
631 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
634 if (list->vendor) {
635 StringFromGUID2(list->vendor, buf, 39);
636 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
637 (CONST BYTE*)(buf), 78);
638 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
641 if (list->version) {
642 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
643 (CONST BYTE*)(list->version),
644 strlen(list->version) + 1);
645 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
648 if (list->formats) {
649 HKEY formats_key;
650 GUID const * const *format;
652 res = RegCreateKeyExW(clsid_key, pixelformats_keyname, 0, NULL, 0,
653 KEY_READ | KEY_WRITE, NULL, &formats_key, NULL);
654 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
655 for (format=list->formats; *format; ++format)
657 HKEY format_key;
658 StringFromGUID2(*format, buf, 39);
659 res = RegCreateKeyExW(formats_key, buf, 0, NULL, 0,
660 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
661 if (res != ERROR_SUCCESS) break;
662 RegCloseKey(format_key);
664 RegCloseKey(formats_key);
665 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
668 error_close_clsid_key:
669 RegCloseKey(clsid_key);
672 error_close_coclass_key:
673 RegCloseKey(instance_key);
674 RegCloseKey(converters_key);
675 RegCloseKey(coclass_key);
676 error_return:
677 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
680 /***********************************************************************
681 * unregister_converters
683 static HRESULT unregister_converters(struct regsvr_converter const *list)
685 LONG res = ERROR_SUCCESS;
686 HKEY coclass_key;
687 WCHAR buf[39];
688 HKEY converters_key;
689 HKEY instance_key;
691 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
692 KEY_READ | KEY_WRITE, &coclass_key);
693 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
695 if (res == ERROR_SUCCESS) {
696 StringFromGUID2(&CATID_WICFormatConverters, buf, 39);
697 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
698 KEY_READ | KEY_WRITE, NULL, &converters_key, NULL);
699 if (res == ERROR_SUCCESS)
701 res = RegCreateKeyExW(converters_key, instance_keyname, 0, NULL, 0,
702 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
703 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
705 if (res != ERROR_SUCCESS)
706 RegCloseKey(coclass_key);
708 if (res != ERROR_SUCCESS) goto error_return;
710 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
711 StringFromGUID2(list->clsid, buf, 39);
713 res = RegDeleteTreeW(coclass_key, buf);
714 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
715 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
717 res = RegDeleteTreeW(instance_key, buf);
718 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
719 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
722 error_close_coclass_key:
723 RegCloseKey(instance_key);
724 RegCloseKey(converters_key);
725 RegCloseKey(coclass_key);
726 error_return:
727 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
730 /***********************************************************************
731 * register_metadatareaders
733 static HRESULT register_metadatareaders(struct regsvr_metadatareader const *list)
735 LONG res = ERROR_SUCCESS;
736 HKEY coclass_key;
737 WCHAR buf[39];
738 HKEY readers_key;
739 HKEY instance_key;
741 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
742 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
743 if (res == ERROR_SUCCESS) {
744 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
745 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
746 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
747 if (res == ERROR_SUCCESS)
749 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
750 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
751 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
753 if (res != ERROR_SUCCESS)
754 RegCloseKey(coclass_key);
756 if (res != ERROR_SUCCESS) goto error_return;
758 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
759 HKEY clsid_key;
760 HKEY instance_clsid_key;
762 StringFromGUID2(list->clsid, buf, 39);
763 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
764 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
765 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
767 StringFromGUID2(list->clsid, buf, 39);
768 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0,
769 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL);
770 if (res == ERROR_SUCCESS) {
771 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ,
772 (CONST BYTE*)(buf), 78);
773 RegCloseKey(instance_clsid_key);
775 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
777 if (list->author) {
778 res = RegSetValueExA(clsid_key, author_valuename, 0, REG_SZ,
779 (CONST BYTE*)(list->author),
780 strlen(list->author) + 1);
781 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
784 if (list->friendlyname) {
785 res = RegSetValueExA(clsid_key, friendlyname_valuename, 0, REG_SZ,
786 (CONST BYTE*)(list->friendlyname),
787 strlen(list->friendlyname) + 1);
788 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
791 if (list->vendor) {
792 StringFromGUID2(list->vendor, buf, 39);
793 res = RegSetValueExW(clsid_key, vendor_valuename, 0, REG_SZ,
794 (CONST BYTE*)(buf), 78);
795 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
798 if (list->vendor) {
799 StringFromGUID2(list->metadata_format, buf, 39);
800 res = RegSetValueExW(clsid_key, metadataformat_valuename, 0, REG_SZ,
801 (CONST BYTE*)(buf), 78);
802 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
805 if (list->version) {
806 res = RegSetValueExA(clsid_key, version_valuename, 0, REG_SZ,
807 (CONST BYTE*)(list->version),
808 strlen(list->version) + 1);
809 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
812 if (list->specversion) {
813 res = RegSetValueExA(clsid_key, specversion_valuename, 0, REG_SZ,
814 (CONST BYTE*)(list->version),
815 strlen(list->version) + 1);
816 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
819 res = RegSetValueExA(clsid_key, requiresfullstream_valuename, 0, REG_DWORD,
820 (CONST BYTE*)(&list->requires_fullstream), 4);
821 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
823 res = RegSetValueExA(clsid_key, supportspadding_valuename, 0, REG_DWORD,
824 (CONST BYTE*)(&list->supports_padding), 4);
825 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
827 if (list->requires_fixedsize) {
828 res = RegSetValueExA(clsid_key, requiresfixedsize_valuename, 0, REG_DWORD,
829 (CONST BYTE*)(&list->requires_fixedsize), 4);
830 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
833 if (list->containers) {
834 HKEY containers_key;
835 const struct reader_containers *container;
837 res = RegCreateKeyExW(clsid_key, containers_keyname, 0, NULL, 0,
838 KEY_READ | KEY_WRITE, NULL, &containers_key, NULL);
839 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
840 for (container=list->containers; container->format; ++container)
842 HKEY format_key;
843 int i;
844 StringFromGUID2(container->format, buf, 39);
845 res = RegCreateKeyExW(containers_key, buf, 0, NULL, 0,
846 KEY_READ | KEY_WRITE, NULL, &format_key, NULL);
847 if (res != ERROR_SUCCESS) break;
849 for (i=0; container->patterns[i].length; i++)
851 HKEY pattern_key;
852 static const WCHAR int_format[] = {'%','i',0};
853 snprintfW(buf, 39, int_format, i);
854 res = RegCreateKeyExW(format_key, buf, 0, NULL, 0,
855 KEY_READ | KEY_WRITE, NULL, &pattern_key, NULL);
856 if (res != ERROR_SUCCESS) break;
857 res = RegSetValueExA(pattern_key, position_valuename, 0, REG_DWORD,
858 (CONST BYTE*)(&container->patterns[i].position), 4);
859 if (res == ERROR_SUCCESS)
860 res = RegSetValueExA(pattern_key, pattern_valuename, 0, REG_BINARY,
861 container->patterns[i].pattern,
862 container->patterns[i].length);
863 if (res == ERROR_SUCCESS)
864 res = RegSetValueExA(pattern_key, mask_valuename, 0, REG_BINARY,
865 container->patterns[i].mask,
866 container->patterns[i].length);
867 if (res == ERROR_SUCCESS && container->patterns[i].data_offset)
868 res = RegSetValueExA(pattern_key, dataoffset_valuename, 0, REG_DWORD,
869 (CONST BYTE*)&(container->patterns[i].data_offset), 4);
870 RegCloseKey(pattern_key);
873 RegCloseKey(format_key);
875 RegCloseKey(containers_key);
878 error_close_clsid_key:
879 RegCloseKey(clsid_key);
882 error_close_coclass_key:
883 RegCloseKey(instance_key);
884 RegCloseKey(readers_key);
885 RegCloseKey(coclass_key);
886 error_return:
887 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
890 /***********************************************************************
891 * unregister_metadatareaders
893 static HRESULT unregister_metadatareaders(struct regsvr_metadatareader const *list)
895 LONG res = ERROR_SUCCESS;
896 HKEY coclass_key;
897 WCHAR buf[39];
898 HKEY readers_key;
899 HKEY instance_key;
901 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
902 KEY_READ | KEY_WRITE, &coclass_key);
903 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
905 if (res == ERROR_SUCCESS) {
906 StringFromGUID2(&CATID_WICMetadataReader, buf, 39);
907 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
908 KEY_READ | KEY_WRITE, NULL, &readers_key, NULL);
909 if (res == ERROR_SUCCESS)
911 res = RegCreateKeyExW(readers_key, instance_keyname, 0, NULL, 0,
912 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL);
913 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
915 if (res != ERROR_SUCCESS)
916 RegCloseKey(coclass_key);
918 if (res != ERROR_SUCCESS) goto error_return;
920 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
921 StringFromGUID2(list->clsid, buf, 39);
923 res = RegDeleteTreeW(coclass_key, buf);
924 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
925 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
927 res = RegDeleteTreeW(instance_key, buf);
928 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
929 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
932 error_close_coclass_key:
933 RegCloseKey(instance_key);
934 RegCloseKey(readers_key);
935 RegCloseKey(coclass_key);
936 error_return:
937 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
940 /***********************************************************************
941 * decoder list
943 static const BYTE mask_all[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
945 static const BYTE bmp_magic[] = {0x42,0x4d};
947 static GUID const * const bmp_formats[] = {
948 &GUID_WICPixelFormat1bppIndexed,
949 &GUID_WICPixelFormat2bppIndexed,
950 &GUID_WICPixelFormat4bppIndexed,
951 &GUID_WICPixelFormat8bppIndexed,
952 &GUID_WICPixelFormat16bppBGR555,
953 &GUID_WICPixelFormat16bppBGR565,
954 &GUID_WICPixelFormat24bppBGR,
955 &GUID_WICPixelFormat32bppBGR,
956 &GUID_WICPixelFormat32bppBGRA,
957 NULL
960 static struct decoder_pattern const bmp_patterns[] = {
961 {2,0,bmp_magic,mask_all,0},
965 static const BYTE gif87a_magic[6] = "GIF87a";
966 static const BYTE gif89a_magic[6] = "GIF89a";
968 static GUID const * const gif_formats[] = {
969 &GUID_WICPixelFormat8bppIndexed,
970 NULL
973 static struct decoder_pattern const gif_patterns[] = {
974 {6,0,gif87a_magic,mask_all,0},
975 {6,0,gif89a_magic,mask_all,0},
979 static const BYTE ico_magic[] = {00,00,01,00};
981 static GUID const * const ico_formats[] = {
982 &GUID_WICPixelFormat32bppBGRA,
983 NULL
986 static struct decoder_pattern const ico_patterns[] = {
987 {4,0,ico_magic,mask_all,0},
991 static const BYTE jpeg_magic[] = {0xff, 0xd8};
993 static GUID const * const jpeg_formats[] = {
994 &GUID_WICPixelFormat24bppBGR,
995 &GUID_WICPixelFormat32bppCMYK,
996 &GUID_WICPixelFormat8bppGray,
997 NULL
1000 static struct decoder_pattern const jpeg_patterns[] = {
1001 {2,0,jpeg_magic,mask_all,0},
1005 static const BYTE png_magic[] = {137,80,78,71,13,10,26,10};
1007 static GUID const * const png_formats[] = {
1008 &GUID_WICPixelFormatBlackWhite,
1009 &GUID_WICPixelFormat2bppGray,
1010 &GUID_WICPixelFormat4bppGray,
1011 &GUID_WICPixelFormat8bppGray,
1012 &GUID_WICPixelFormat16bppGray,
1013 &GUID_WICPixelFormat32bppBGRA,
1014 &GUID_WICPixelFormat64bppRGBA,
1015 &GUID_WICPixelFormat1bppIndexed,
1016 &GUID_WICPixelFormat2bppIndexed,
1017 &GUID_WICPixelFormat4bppIndexed,
1018 &GUID_WICPixelFormat8bppIndexed,
1019 &GUID_WICPixelFormat24bppBGR,
1020 &GUID_WICPixelFormat48bppRGB,
1021 NULL
1024 static struct decoder_pattern const png_patterns[] = {
1025 {8,0,png_magic,mask_all,0},
1029 static const BYTE tiff_magic_le[] = {0x49,0x49,42,0};
1030 static const BYTE tiff_magic_be[] = {0x4d,0x4d,0,42};
1032 static GUID const * const tiff_decode_formats[] = {
1033 &GUID_WICPixelFormatBlackWhite,
1034 &GUID_WICPixelFormat4bppGray,
1035 &GUID_WICPixelFormat8bppGray,
1036 &GUID_WICPixelFormat4bppIndexed,
1037 &GUID_WICPixelFormat8bppIndexed,
1038 &GUID_WICPixelFormat24bppBGR,
1039 &GUID_WICPixelFormat32bppBGR,
1040 &GUID_WICPixelFormat32bppBGRA,
1041 &GUID_WICPixelFormat32bppPBGRA,
1042 &GUID_WICPixelFormat48bppRGB,
1043 &GUID_WICPixelFormat64bppRGBA,
1044 &GUID_WICPixelFormat64bppPRGBA,
1045 NULL
1048 static struct decoder_pattern const tiff_patterns[] = {
1049 {4,0,tiff_magic_le,mask_all,0},
1050 {4,0,tiff_magic_be,mask_all,0},
1054 static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE.";
1056 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};
1057 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};
1059 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};
1060 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};
1062 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};
1063 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};
1065 static GUID const * const tga_formats[] = {
1066 &GUID_WICPixelFormat8bppGray,
1067 &GUID_WICPixelFormat8bppIndexed,
1068 &GUID_WICPixelFormat16bppGray,
1069 &GUID_WICPixelFormat16bppBGR555,
1070 &GUID_WICPixelFormat24bppBGR,
1071 &GUID_WICPixelFormat32bppBGRA,
1072 &GUID_WICPixelFormat32bppPBGRA,
1073 NULL
1076 static struct decoder_pattern const tga_patterns[] = {
1077 {18,18,tga_footer_magic,mask_all,1},
1078 {18,0,tga_indexed_magic,tga_indexed_mask,0},
1079 {18,0,tga_truecolor_magic,tga_truecolor_mask,0},
1080 {18,0,tga_grayscale_magic,tga_grayscale_mask,0},
1084 static struct regsvr_decoder const decoder_list[] = {
1085 { &CLSID_WICBmpDecoder,
1086 "The Wine Project",
1087 "BMP Decoder",
1088 "1.0.0.0",
1089 &GUID_VendorMicrosoft,
1090 &GUID_ContainerFormatBmp,
1091 "image/bmp",
1092 ".bmp,.dib,.rle",
1093 bmp_formats,
1094 bmp_patterns
1096 { &CLSID_WICGifDecoder,
1097 "The Wine Project",
1098 "GIF Decoder",
1099 "1.0.0.0",
1100 &GUID_VendorMicrosoft,
1101 &GUID_ContainerFormatGif,
1102 "image/gif",
1103 ".gif",
1104 gif_formats,
1105 gif_patterns
1107 { &CLSID_WICIcoDecoder,
1108 "The Wine Project",
1109 "ICO Decoder",
1110 "1.0.0.0",
1111 &GUID_VendorMicrosoft,
1112 &GUID_ContainerFormatIco,
1113 "image/vnd.microsoft.icon",
1114 ".ico",
1115 ico_formats,
1116 ico_patterns
1118 { &CLSID_WICJpegDecoder,
1119 "The Wine Project",
1120 "JPEG Decoder",
1121 "1.0.0.0",
1122 &GUID_VendorMicrosoft,
1123 &GUID_ContainerFormatJpeg,
1124 "image/jpeg",
1125 ".jpg;.jpeg;.jfif",
1126 jpeg_formats,
1127 jpeg_patterns
1129 { &CLSID_WICPngDecoder,
1130 "The Wine Project",
1131 "PNG Decoder",
1132 "1.0.0.0",
1133 &GUID_VendorMicrosoft,
1134 &GUID_ContainerFormatPng,
1135 "image/png",
1136 ".png",
1137 png_formats,
1138 png_patterns
1140 { &CLSID_WICTiffDecoder,
1141 "The Wine Project",
1142 "TIFF Decoder",
1143 "1.0.0.0",
1144 &GUID_VendorMicrosoft,
1145 &GUID_ContainerFormatTiff,
1146 "image/tiff",
1147 ".tif;.tiff",
1148 tiff_decode_formats,
1149 tiff_patterns
1151 { &CLSID_WineTgaDecoder,
1152 "The Wine Project",
1153 "TGA Decoder",
1154 "1.0.0.0",
1155 &GUID_VendorWine,
1156 &GUID_WineContainerFormatTga,
1157 "image/x-targa",
1158 ".tga;.tpic",
1159 tga_formats,
1160 tga_patterns
1162 { NULL } /* list terminator */
1165 static GUID const * const bmp_encode_formats[] = {
1166 &GUID_WICPixelFormat16bppBGR555,
1167 &GUID_WICPixelFormat16bppBGR565,
1168 &GUID_WICPixelFormat24bppBGR,
1169 &GUID_WICPixelFormat32bppBGR,
1170 NULL
1173 static GUID const * const png_encode_formats[] = {
1174 &GUID_WICPixelFormat24bppBGR,
1175 &GUID_WICPixelFormatBlackWhite,
1176 &GUID_WICPixelFormat2bppGray,
1177 &GUID_WICPixelFormat4bppGray,
1178 &GUID_WICPixelFormat8bppGray,
1179 &GUID_WICPixelFormat16bppGray,
1180 &GUID_WICPixelFormat32bppBGR,
1181 &GUID_WICPixelFormat32bppBGRA,
1182 &GUID_WICPixelFormat48bppRGB,
1183 &GUID_WICPixelFormat64bppRGBA,
1184 NULL
1187 static GUID const * const tiff_encode_formats[] = {
1188 &GUID_WICPixelFormatBlackWhite,
1189 &GUID_WICPixelFormat4bppGray,
1190 &GUID_WICPixelFormat8bppGray,
1191 &GUID_WICPixelFormat24bppBGR,
1192 &GUID_WICPixelFormat32bppBGRA,
1193 &GUID_WICPixelFormat32bppPBGRA,
1194 &GUID_WICPixelFormat48bppRGB,
1195 &GUID_WICPixelFormat64bppRGBA,
1196 &GUID_WICPixelFormat64bppPRGBA,
1197 NULL
1200 static GUID const * const icns_encode_formats[] = {
1201 &GUID_WICPixelFormat32bppBGRA,
1202 NULL
1205 static struct regsvr_encoder const encoder_list[] = {
1206 { &CLSID_WICBmpEncoder,
1207 "The Wine Project",
1208 "BMP Encoder",
1209 "1.0.0.0",
1210 &GUID_VendorMicrosoft,
1211 &GUID_ContainerFormatBmp,
1212 "image/bmp",
1213 ".bmp,.dib,.rle",
1214 bmp_encode_formats
1216 { &CLSID_WICJpegEncoder,
1217 "The Wine Project",
1218 "JPEG Encoder",
1219 "1.0.0.0",
1220 &GUID_VendorMicrosoft,
1221 &GUID_ContainerFormatJpeg,
1222 "image/jpeg",
1223 ".jpg;.jpeg;.jfif",
1224 jpeg_formats
1226 { &CLSID_WICPngEncoder,
1227 "The Wine Project",
1228 "PNG Encoder",
1229 "1.0.0.0",
1230 &GUID_VendorMicrosoft,
1231 &GUID_ContainerFormatPng,
1232 "image/png",
1233 ".png",
1234 png_encode_formats
1236 { &CLSID_WICTiffEncoder,
1237 "The Wine Project",
1238 "TIFF Encoder",
1239 "1.0.0.0",
1240 &GUID_VendorMicrosoft,
1241 &GUID_ContainerFormatTiff,
1242 "image/tiff",
1243 ".tif;.tiff",
1244 tiff_encode_formats
1246 { &CLSID_WICIcnsEncoder,
1247 "The Wine Project",
1248 "ICNS Encoder",
1249 "1.0.0.0",
1250 &GUID_VendorWine,
1251 NULL, /* no container format guid */
1252 "image/icns",
1253 ".icns",
1254 icns_encode_formats
1256 { NULL } /* list terminator */
1259 static GUID const * const converter_formats[] = {
1260 &GUID_WICPixelFormat1bppIndexed,
1261 &GUID_WICPixelFormat2bppIndexed,
1262 &GUID_WICPixelFormat4bppIndexed,
1263 &GUID_WICPixelFormat8bppIndexed,
1264 &GUID_WICPixelFormatBlackWhite,
1265 &GUID_WICPixelFormat2bppGray,
1266 &GUID_WICPixelFormat4bppGray,
1267 &GUID_WICPixelFormat8bppGray,
1268 &GUID_WICPixelFormat16bppGray,
1269 &GUID_WICPixelFormat16bppBGR555,
1270 &GUID_WICPixelFormat16bppBGR565,
1271 &GUID_WICPixelFormat16bppBGRA5551,
1272 &GUID_WICPixelFormat24bppBGR,
1273 &GUID_WICPixelFormat32bppBGR,
1274 &GUID_WICPixelFormat32bppBGRA,
1275 &GUID_WICPixelFormat32bppPBGRA,
1276 &GUID_WICPixelFormat48bppRGB,
1277 &GUID_WICPixelFormat64bppRGBA,
1278 &GUID_WICPixelFormat32bppCMYK,
1279 NULL
1282 static struct regsvr_converter const converter_list[] = {
1283 { &CLSID_WICDefaultFormatConverter,
1284 "The Wine Project",
1285 "Default Pixel Format Converter",
1286 "1.0.0.0",
1287 &GUID_VendorMicrosoft,
1288 converter_formats
1290 { NULL } /* list terminator */
1293 static struct regsvr_metadatareader const metadatareader_list[] = {
1294 { &CLSID_WICUnknownMetadataReader,
1295 "The Wine Project",
1296 "Unknown Metadata Reader",
1297 "1.0.0.0",
1298 "1.0.0.0",
1299 &GUID_VendorMicrosoft,
1300 &GUID_MetadataFormatUnknown,
1304 NULL
1306 { NULL } /* list terminator */
1309 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN;
1310 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN;
1312 HRESULT WINAPI DllRegisterServer(void)
1314 HRESULT hr;
1316 TRACE("\n");
1318 hr = WIC_DllRegisterServer();
1319 if (SUCCEEDED(hr))
1320 hr = register_decoders(decoder_list);
1321 if (SUCCEEDED(hr))
1322 hr = register_encoders(encoder_list);
1323 if (SUCCEEDED(hr))
1324 hr = register_converters(converter_list);
1325 if (SUCCEEDED(hr))
1326 hr = register_metadatareaders(metadatareader_list);
1327 return hr;
1330 HRESULT WINAPI DllUnregisterServer(void)
1332 HRESULT hr;
1334 TRACE("\n");
1336 hr = WIC_DllUnregisterServer();
1337 if (SUCCEEDED(hr))
1338 hr = unregister_decoders(decoder_list);
1339 if (SUCCEEDED(hr))
1340 hr = unregister_encoders(encoder_list);
1341 if (SUCCEEDED(hr))
1342 hr = unregister_converters(converter_list);
1343 if (SUCCEEDED(hr))
1344 hr = unregister_metadatareaders(metadatareader_list);
1345 return hr;