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 &GUID_WICPixelFormat1bppIndexed, 1346 &GUID_WICPixelFormat2bppIndexed, 1347 &GUID_WICPixelFormat4bppIndexed, 1348 &GUID_WICPixelFormat8bppIndexed, 1349 NULL 1350 }; 1351 1352 static GUID const * const tiff_encode_formats[] = { 1353 &GUID_WICPixelFormatBlackWhite, 1354 &GUID_WICPixelFormat4bppGray, 1355 &GUID_WICPixelFormat8bppGray, 1356 &GUID_WICPixelFormat24bppBGR, 1357 &GUID_WICPixelFormat32bppBGRA, 1358 &GUID_WICPixelFormat32bppPBGRA, 1359 &GUID_WICPixelFormat48bppRGB, 1360 &GUID_WICPixelFormat64bppRGBA, 1361 &GUID_WICPixelFormat64bppPRGBA, 1362 NULL 1363 }; 1364 1365 static GUID const * const icns_encode_formats[] = { 1366 &GUID_WICPixelFormat32bppBGRA, 1367 NULL 1368 }; 1369 1370 static struct regsvr_encoder const encoder_list[] = { 1371 { &CLSID_WICBmpEncoder, 1372 "The Wine Project", 1373 "BMP Encoder", 1374 "1.0.0.0", 1375 &GUID_VendorMicrosoft, 1376 &GUID_ContainerFormatBmp, 1377 "image/bmp", 1378 ".bmp,.dib,.rle", 1379 bmp_encode_formats 1380 }, 1381 { &CLSID_WICJpegEncoder, 1382 "The Wine Project", 1383 "JPEG Encoder", 1384 "1.0.0.0", 1385 &GUID_VendorMicrosoft, 1386 &GUID_ContainerFormatJpeg, 1387 "image/jpeg", 1388 ".jpg;.jpeg;.jfif", 1389 jpeg_formats 1390 }, 1391 { &CLSID_WICPngEncoder, 1392 "The Wine Project", 1393 "PNG Encoder", 1394 "1.0.0.0", 1395 &GUID_VendorMicrosoft, 1396 &GUID_ContainerFormatPng, 1397 "image/png", 1398 ".png", 1399 png_encode_formats 1400 }, 1401 { &CLSID_WICTiffEncoder, 1402 "The Wine Project", 1403 "TIFF Encoder", 1404 "1.0.0.0", 1405 &GUID_VendorMicrosoft, 1406 &GUID_ContainerFormatTiff, 1407 "image/tiff", 1408 ".tif;.tiff", 1409 tiff_encode_formats 1410 }, 1411 { &CLSID_WICIcnsEncoder, 1412 "The Wine Project", 1413 "ICNS Encoder", 1414 "1.0.0.0", 1415 &GUID_VendorWine, 1416 NULL, /* no container format guid */ 1417 "image/icns", 1418 ".icns", 1419 icns_encode_formats 1420 }, 1421 { NULL } /* list terminator */ 1422 }; 1423 1424 static GUID const * const converter_formats[] = { 1425 &GUID_WICPixelFormat1bppIndexed, 1426 &GUID_WICPixelFormat2bppIndexed, 1427 &GUID_WICPixelFormat4bppIndexed, 1428 &GUID_WICPixelFormat8bppIndexed, 1429 &GUID_WICPixelFormatBlackWhite, 1430 &GUID_WICPixelFormat2bppGray, 1431 &GUID_WICPixelFormat4bppGray, 1432 &GUID_WICPixelFormat8bppGray, 1433 &GUID_WICPixelFormat16bppGray, 1434 &GUID_WICPixelFormat16bppBGR555, 1435 &GUID_WICPixelFormat16bppBGR565, 1436 &GUID_WICPixelFormat16bppBGRA5551, 1437 &GUID_WICPixelFormat24bppBGR, 1438 &GUID_WICPixelFormat24bppRGB, 1439 &GUID_WICPixelFormat32bppBGR, 1440 &GUID_WICPixelFormat32bppBGRA, 1441 &GUID_WICPixelFormat32bppPBGRA, 1442 &GUID_WICPixelFormat32bppGrayFloat, 1443 &GUID_WICPixelFormat48bppRGB, 1444 &GUID_WICPixelFormat64bppRGBA, 1445 &GUID_WICPixelFormat32bppCMYK, 1446 NULL 1447 }; 1448 1449 static struct regsvr_converter const converter_list[] = { 1450 { &CLSID_WICDefaultFormatConverter, 1451 "The Wine Project", 1452 "Default Pixel Format Converter", 1453 "1.0.0.0", 1454 &GUID_VendorMicrosoft, 1455 converter_formats 1456 }, 1457 { NULL } /* list terminator */ 1458 }; 1459 1460 static const BYTE no_magic[1] = { 0 }; 1461 static const BYTE no_mask[1] = { 0 }; 1462 1463 static const struct metadata_pattern ifd_metadata_pattern[] = { 1464 { 0, 1, no_magic, no_mask, 0 }, 1465 { 0 } 1466 }; 1467 1468 static const struct reader_containers ifd_containers[] = { 1469 { 1470 &GUID_ContainerFormatTiff, 1471 ifd_metadata_pattern 1472 }, 1473 { NULL } /* list terminator */ 1474 }; 1475 1476 static const BYTE tEXt[] = "tEXt"; 1477 1478 static const struct metadata_pattern pngtext_metadata_pattern[] = { 1479 { 4, 4, tEXt, mask_all, 4 }, 1480 { 0 } 1481 }; 1482 1483 static const struct reader_containers pngtext_containers[] = { 1484 { 1485 &GUID_ContainerFormatPng, 1486 pngtext_metadata_pattern 1487 }, 1488 { NULL } /* list terminator */ 1489 }; 1490 1491 static const BYTE gAMA[] = "gAMA"; 1492 1493 static const struct metadata_pattern pnggama_metadata_pattern[] = { 1494 { 4, 4, gAMA, mask_all, 4 }, 1495 { 0 } 1496 }; 1497 1498 static const struct reader_containers pnggama_containers[] = { 1499 { 1500 &GUID_ContainerFormatPng, 1501 pnggama_metadata_pattern 1502 }, 1503 { NULL } /* list terminator */ 1504 }; 1505 1506 static const BYTE cHRM[] = "cHRM"; 1507 1508 static const struct metadata_pattern pngchrm_metadata_pattern[] = { 1509 { 4, 4, cHRM, mask_all, 4 }, 1510 { 0 } 1511 }; 1512 1513 static const struct reader_containers pngchrm_containers[] = { 1514 { 1515 &GUID_ContainerFormatPng, 1516 pngchrm_metadata_pattern 1517 }, 1518 { NULL } /* list terminator */ 1519 }; 1520 1521 static const struct metadata_pattern lsd_metadata_patterns[] = { 1522 { 0, 6, gif87a_magic, mask_all, 0 }, 1523 { 0, 6, gif89a_magic, mask_all, 0 }, 1524 { 0 } 1525 }; 1526 1527 static const struct reader_containers lsd_containers[] = { 1528 { 1529 &GUID_ContainerFormatGif, 1530 lsd_metadata_patterns 1531 }, 1532 { NULL } /* list terminator */ 1533 }; 1534 1535 static const BYTE imd_magic[] = { 0x2c }; 1536 1537 static const struct metadata_pattern imd_metadata_pattern[] = { 1538 { 0, 1, imd_magic, mask_all, 1 }, 1539 { 0 } 1540 }; 1541 1542 static const struct reader_containers imd_containers[] = { 1543 { 1544 &GUID_ContainerFormatGif, 1545 imd_metadata_pattern 1546 }, 1547 { NULL } /* list terminator */ 1548 }; 1549 1550 static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 }; 1551 1552 static const struct metadata_pattern gce_metadata_pattern[] = { 1553 { 0, 3, gce_magic, mask_all, 3 }, 1554 { 0 } 1555 }; 1556 1557 static const struct reader_containers gce_containers[] = { 1558 { 1559 &GUID_ContainerFormatGif, 1560 gce_metadata_pattern 1561 }, 1562 { NULL } /* list terminator */ 1563 }; 1564 1565 static const BYTE ape_magic[] = { 0x21, 0xff, 0x0b }; 1566 1567 static const struct metadata_pattern ape_metadata_pattern[] = { 1568 { 0, 3, ape_magic, mask_all, 0 }, 1569 { 0 } 1570 }; 1571 1572 static const struct reader_containers ape_containers[] = { 1573 { 1574 &GUID_ContainerFormatGif, 1575 ape_metadata_pattern 1576 }, 1577 { NULL } /* list terminator */ 1578 }; 1579 1580 static const BYTE gif_comment_magic[] = { 0x21, 0xfe }; 1581 1582 static const struct metadata_pattern gif_comment_metadata_pattern[] = { 1583 { 0, 2, gif_comment_magic, mask_all, 0 }, 1584 { 0 } 1585 }; 1586 1587 static const struct reader_containers gif_comment_containers[] = { 1588 { 1589 &GUID_ContainerFormatGif, 1590 gif_comment_metadata_pattern 1591 }, 1592 { NULL } /* list terminator */ 1593 }; 1594 1595 static struct regsvr_metadatareader const metadatareader_list[] = { 1596 { &CLSID_WICUnknownMetadataReader, 1597 "The Wine Project", 1598 "Unknown Metadata Reader", 1599 "1.0.0.0", 1600 "1.0.0.0", 1601 &GUID_VendorMicrosoft, 1602 &GUID_MetadataFormatUnknown, 1603 0, 0, 0, 1604 NULL 1605 }, 1606 { &CLSID_WICIfdMetadataReader, 1607 "The Wine Project", 1608 "Ifd Reader", 1609 "1.0.0.0", 1610 "1.0.0.0", 1611 &GUID_VendorMicrosoft, 1612 &GUID_MetadataFormatIfd, 1613 1, 1, 0, 1614 ifd_containers 1615 }, 1616 { &CLSID_WICPngChrmMetadataReader, 1617 "The Wine Project", 1618 "Chunk cHRM Reader", 1619 "1.0.0.0", 1620 "1.0.0.0", 1621 &GUID_VendorMicrosoft, 1622 &GUID_MetadataFormatChunkcHRM, 1623 0, 0, 0, 1624 pngchrm_containers 1625 }, 1626 { &CLSID_WICPngGamaMetadataReader, 1627 "The Wine Project", 1628 "Chunk gAMA Reader", 1629 "1.0.0.0", 1630 "1.0.0.0", 1631 &GUID_VendorMicrosoft, 1632 &GUID_MetadataFormatChunkgAMA, 1633 0, 0, 0, 1634 pnggama_containers 1635 }, 1636 { &CLSID_WICPngTextMetadataReader, 1637 "The Wine Project", 1638 "Chunk tEXt Reader", 1639 "1.0.0.0", 1640 "1.0.0.0", 1641 &GUID_VendorMicrosoft, 1642 &GUID_MetadataFormatChunktEXt, 1643 0, 0, 0, 1644 pngtext_containers 1645 }, 1646 { &CLSID_WICLSDMetadataReader, 1647 "The Wine Project", 1648 "Logical Screen Descriptor Reader", 1649 "1.0.0.0", 1650 "1.0.0.0", 1651 &GUID_VendorMicrosoft, 1652 &GUID_MetadataFormatLSD, 1653 0, 0, 0, 1654 lsd_containers 1655 }, 1656 { &CLSID_WICIMDMetadataReader, 1657 "The Wine Project", 1658 "Image Descriptor Reader", 1659 "1.0.0.0", 1660 "1.0.0.0", 1661 &GUID_VendorMicrosoft, 1662 &GUID_MetadataFormatIMD, 1663 0, 0, 0, 1664 imd_containers 1665 }, 1666 { &CLSID_WICGCEMetadataReader, 1667 "The Wine Project", 1668 "Graphic Control Extension Reader", 1669 "1.0.0.0", 1670 "1.0.0.0", 1671 &GUID_VendorMicrosoft, 1672 &GUID_MetadataFormatGCE, 1673 0, 0, 0, 1674 gce_containers 1675 }, 1676 { &CLSID_WICAPEMetadataReader, 1677 "The Wine Project", 1678 "Application Extension Reader", 1679 "1.0.0.0", 1680 "1.0.0.0", 1681 &GUID_VendorMicrosoft, 1682 &GUID_MetadataFormatAPE, 1683 0, 0, 0, 1684 ape_containers 1685 }, 1686 { &CLSID_WICGifCommentMetadataReader, 1687 "The Wine Project", 1688 "Comment Extension Reader", 1689 "1.0.0.0", 1690 "1.0.0.0", 1691 &GUID_VendorMicrosoft, 1692 &GUID_MetadataFormatGifComment, 1693 0, 0, 0, 1694 gif_comment_containers 1695 }, 1696 { NULL } /* list terminator */ 1697 }; 1698 1699 static BYTE const channel_mask_1bit[] = { 0x01 }; 1700 static BYTE const channel_mask_2bit[] = { 0x03 }; 1701 static BYTE const channel_mask_4bit[] = { 0x0f }; 1702 1703 static BYTE const channel_mask_8bit[] = { 0xff, 0x00, 0x00, 0x00 }; 1704 static BYTE const channel_mask_8bit2[] = { 0x00, 0xff, 0x00, 0x00 }; 1705 static BYTE const channel_mask_8bit3[] = { 0x00, 0x00, 0xff, 0x00 }; 1706 static BYTE const channel_mask_8bit4[] = { 0x00, 0x00, 0x00, 0xff }; 1707 1708 static BYTE const channel_mask_16bit[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1709 static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; 1710 static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 }; 1711 static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }; 1712 1713 static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 }; 1714 static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 }; 1715 static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c }; 1716 static BYTE const channel_mask_5bit4[] = { 0x00, 0x80 }; 1717 1718 static BYTE const channel_mask_BGR565_2[] = { 0xe0, 0x07 }; 1719 static BYTE const channel_mask_BGR565_3[] = { 0x00, 0xf8 }; 1720 1721 static BYTE const * const channel_masks_1bit[] = { channel_mask_1bit }; 1722 static BYTE const * const channel_masks_2bit[] = { channel_mask_2bit }; 1723 static BYTE const * const channel_masks_4bit[] = { channel_mask_4bit }; 1724 static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit, 1725 channel_mask_8bit2, channel_mask_8bit3, channel_mask_8bit4 }; 1726 static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit, 1727 channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4}; 1728 1729 static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit, 1730 channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 }; 1731 1732 static BYTE const * const channel_masks_BGR565[] = { channel_mask_5bit, 1733 channel_mask_BGR565_2, channel_mask_BGR565_3 }; 1734 1735 static struct regsvr_pixelformat const pixelformat_list[] = { 1736 { &GUID_WICPixelFormat1bppIndexed, 1737 "The Wine Project", 1738 "1bpp Indexed", 1739 NULL, /* no version */ 1740 &GUID_VendorMicrosoft, 1741 1, /* bitsperpixel */ 1742 1, /* channel count */ 1743 channel_masks_1bit, 1744 WICPixelFormatNumericRepresentationIndexed, 1745 1 1746 }, 1747 { &GUID_WICPixelFormat2bppIndexed, 1748 "The Wine Project", 1749 "2bpp Indexed", 1750 NULL, /* no version */ 1751 &GUID_VendorMicrosoft, 1752 2, /* bitsperpixel */ 1753 1, /* channel count */ 1754 channel_masks_2bit, 1755 WICPixelFormatNumericRepresentationIndexed, 1756 1 1757 }, 1758 { &GUID_WICPixelFormat4bppIndexed, 1759 "The Wine Project", 1760 "4bpp Indexed", 1761 NULL, /* no version */ 1762 &GUID_VendorMicrosoft, 1763 4, /* bitsperpixel */ 1764 1, /* channel count */ 1765 channel_masks_4bit, 1766 WICPixelFormatNumericRepresentationIndexed, 1767 1 1768 }, 1769 { &GUID_WICPixelFormat8bppIndexed, 1770 "The Wine Project", 1771 "8bpp Indexed", 1772 NULL, /* no version */ 1773 &GUID_VendorMicrosoft, 1774 8, /* bitsperpixel */ 1775 1, /* channel count */ 1776 channel_masks_8bit, 1777 WICPixelFormatNumericRepresentationIndexed, 1778 1 1779 }, 1780 { &GUID_WICPixelFormatBlackWhite, 1781 "The Wine Project", 1782 "Black and White", 1783 NULL, /* no version */ 1784 &GUID_VendorMicrosoft, 1785 1, /* bitsperpixel */ 1786 1, /* channel count */ 1787 channel_masks_1bit, 1788 WICPixelFormatNumericRepresentationUnsignedInteger, 1789 0 1790 }, 1791 { &GUID_WICPixelFormat2bppGray, 1792 "The Wine Project", 1793 "2bpp Grayscale", 1794 NULL, /* no version */ 1795 &GUID_VendorMicrosoft, 1796 2, /* bitsperpixel */ 1797 1, /* channel count */ 1798 channel_masks_2bit, 1799 WICPixelFormatNumericRepresentationUnsignedInteger, 1800 0 1801 }, 1802 { &GUID_WICPixelFormat4bppGray, 1803 "The Wine Project", 1804 "4bpp Grayscale", 1805 NULL, /* no version */ 1806 &GUID_VendorMicrosoft, 1807 4, /* bitsperpixel */ 1808 1, /* channel count */ 1809 channel_masks_4bit, 1810 WICPixelFormatNumericRepresentationUnsignedInteger, 1811 0 1812 }, 1813 { &GUID_WICPixelFormat8bppGray, 1814 "The Wine Project", 1815 "8bpp Grayscale", 1816 NULL, /* no version */ 1817 &GUID_VendorMicrosoft, 1818 8, /* bitsperpixel */ 1819 1, /* channel count */ 1820 channel_masks_8bit, 1821 WICPixelFormatNumericRepresentationUnsignedInteger, 1822 0 1823 }, 1824 { &GUID_WICPixelFormat16bppGray, 1825 "The Wine Project", 1826 "16bpp Grayscale", 1827 NULL, /* no version */ 1828 &GUID_VendorMicrosoft, 1829 16, /* bitsperpixel */ 1830 1, /* channel count */ 1831 channel_masks_16bit, 1832 WICPixelFormatNumericRepresentationUnsignedInteger, 1833 0 1834 }, 1835 { &GUID_WICPixelFormat16bppBGR555, 1836 "The Wine Project", 1837 "16bpp BGR555", 1838 NULL, /* no version */ 1839 &GUID_VendorMicrosoft, 1840 16, /* bitsperpixel */ 1841 3, /* channel count */ 1842 channel_masks_BGRA5551, 1843 WICPixelFormatNumericRepresentationUnsignedInteger, 1844 0 1845 }, 1846 { &GUID_WICPixelFormat16bppBGR565, 1847 "The Wine Project", 1848 "16bpp BGR565", 1849 NULL, /* no version */ 1850 &GUID_VendorMicrosoft, 1851 16, /* bitsperpixel */ 1852 3, /* channel count */ 1853 channel_masks_BGR565, 1854 WICPixelFormatNumericRepresentationUnsignedInteger, 1855 0 1856 }, 1857 { &GUID_WICPixelFormat16bppBGRA5551, 1858 "The Wine Project", 1859 "16bpp BGRA5551", 1860 NULL, /* no version */ 1861 &GUID_VendorMicrosoft, 1862 16, /* bitsperpixel */ 1863 4, /* channel count */ 1864 channel_masks_BGRA5551, 1865 WICPixelFormatNumericRepresentationUnsignedInteger, 1866 1 1867 }, 1868 { &GUID_WICPixelFormat24bppBGR, 1869 "The Wine Project", 1870 "24bpp BGR", 1871 NULL, /* no version */ 1872 &GUID_VendorMicrosoft, 1873 24, /* bitsperpixel */ 1874 3, /* channel count */ 1875 channel_masks_8bit, 1876 WICPixelFormatNumericRepresentationUnsignedInteger, 1877 0 1878 }, 1879 { &GUID_WICPixelFormat24bppRGB, 1880 "The Wine Project", 1881 "24bpp RGB", 1882 NULL, /* no version */ 1883 &GUID_VendorMicrosoft, 1884 24, /* bitsperpixel */ 1885 3, /* channel count */ 1886 channel_masks_8bit, 1887 WICPixelFormatNumericRepresentationUnsignedInteger, 1888 0 1889 }, 1890 { &GUID_WICPixelFormat32bppBGR, 1891 "The Wine Project", 1892 "32bpp BGR", 1893 NULL, /* no version */ 1894 &GUID_VendorMicrosoft, 1895 32, /* bitsperpixel */ 1896 3, /* channel count */ 1897 channel_masks_8bit, 1898 WICPixelFormatNumericRepresentationUnsignedInteger, 1899 0 1900 }, 1901 { &GUID_WICPixelFormat32bppBGRA, 1902 "The Wine Project", 1903 "32bpp BGRA", 1904 NULL, /* no version */ 1905 &GUID_VendorMicrosoft, 1906 32, /* bitsperpixel */ 1907 4, /* channel count */ 1908 channel_masks_8bit, 1909 WICPixelFormatNumericRepresentationUnsignedInteger, 1910 1 1911 }, 1912 { &GUID_WICPixelFormat32bppPBGRA, 1913 "The Wine Project", 1914 "32bpp PBGRA", 1915 NULL, /* no version */ 1916 &GUID_VendorMicrosoft, 1917 32, /* bitsperpixel */ 1918 4, /* channel count */ 1919 channel_masks_8bit, 1920 WICPixelFormatNumericRepresentationUnsignedInteger, 1921 1 1922 }, 1923 { &GUID_WICPixelFormat48bppRGB, 1924 "The Wine Project", 1925 "48bpp RGB", 1926 NULL, /* no version */ 1927 &GUID_VendorMicrosoft, 1928 48, /* bitsperpixel */ 1929 3, /* channel count */ 1930 channel_masks_16bit, 1931 WICPixelFormatNumericRepresentationUnsignedInteger, 1932 0 1933 }, 1934 { &GUID_WICPixelFormat64bppRGBA, 1935 "The Wine Project", 1936 "64bpp RGBA", 1937 NULL, /* no version */ 1938 &GUID_VendorMicrosoft, 1939 64, /* bitsperpixel */ 1940 4, /* channel count */ 1941 channel_masks_16bit, 1942 WICPixelFormatNumericRepresentationUnsignedInteger, 1943 1 1944 }, 1945 { &GUID_WICPixelFormat64bppPRGBA, 1946 "The Wine Project", 1947 "64bpp PRGBA", 1948 NULL, /* no version */ 1949 &GUID_VendorMicrosoft, 1950 64, /* bitsperpixel */ 1951 4, /* channel count */ 1952 channel_masks_16bit, 1953 WICPixelFormatNumericRepresentationUnsignedInteger, 1954 1 1955 }, 1956 { &GUID_WICPixelFormat32bppCMYK, 1957 "The Wine Project", 1958 "32bpp CMYK", 1959 NULL, /* no version */ 1960 &GUID_VendorMicrosoft, 1961 32, /* bitsperpixel */ 1962 4, /* channel count */ 1963 channel_masks_8bit, 1964 WICPixelFormatNumericRepresentationUnsignedInteger, 1965 0 1966 }, 1967 { NULL } /* list terminator */ 1968 }; 1969 1970 struct regsvr_category 1971 { 1972 const CLSID *clsid; /* NULL for end of list */ 1973 }; 1974 1975 static const struct regsvr_category category_list[] = { 1976 { &CATID_WICBitmapDecoders }, 1977 { &CATID_WICBitmapEncoders }, 1978 { &CATID_WICFormatConverters }, 1979 { &CATID_WICMetadataReader }, 1980 { &CATID_WICPixelFormats }, 1981 { NULL } 1982 }; 1983 1984 static HRESULT register_categories(const struct regsvr_category *list) 1985 { 1986 LONG res; 1987 WCHAR buf[39]; 1988 HKEY coclass_key, categories_key, instance_key; 1989 1990 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, 1991 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); 1992 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); 1993 1994 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 1995 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 1996 KEY_READ | KEY_WRITE, NULL, &categories_key, NULL); 1997 if (res != ERROR_SUCCESS) 1998 { 1999 RegCloseKey(coclass_key); 2000 return HRESULT_FROM_WIN32(res); 2001 } 2002 2003 res = RegCreateKeyExW(categories_key, instance_keyname, 0, NULL, 0, 2004 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 2005 2006 for (; res == ERROR_SUCCESS && list->clsid; list++) 2007 { 2008 HKEY instance_clsid_key; 2009 2010 StringFromGUID2(list->clsid, buf, 39); 2011 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0, 2012 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL); 2013 if (res == ERROR_SUCCESS) 2014 { 2015 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ, 2016 (const BYTE *)buf, 78); 2017 RegCloseKey(instance_clsid_key); 2018 } 2019 } 2020 2021 RegCloseKey(instance_key); 2022 RegCloseKey(categories_key); 2023 RegCloseKey(coclass_key); 2024 2025 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 2026 } 2027 2028 static HRESULT unregister_categories(const struct regsvr_category *list) 2029 { 2030 LONG res; 2031 WCHAR buf[39]; 2032 HKEY coclass_key, categories_key, instance_key; 2033 2034 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, 2035 KEY_READ | KEY_WRITE, &coclass_key); 2036 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); 2037 2038 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 2039 res = RegOpenKeyExW(coclass_key, buf, 0, 2040 KEY_READ | KEY_WRITE, &categories_key); 2041 if (res != ERROR_SUCCESS) 2042 { 2043 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 2044 RegCloseKey(coclass_key); 2045 return HRESULT_FROM_WIN32(res); 2046 } 2047 2048 res = RegOpenKeyExW(categories_key, instance_keyname, 0, 2049 KEY_READ | KEY_WRITE, &instance_key); 2050 2051 for (; res == ERROR_SUCCESS && list->clsid; list++) 2052 { 2053 StringFromGUID2(list->clsid, buf, 39); 2054 res = RegDeleteTreeW(instance_key, buf); 2055 } 2056 2057 RegCloseKey(instance_key); 2058 RegCloseKey(categories_key); 2059 2060 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 2061 res = RegDeleteTreeW(coclass_key, buf); 2062 2063 RegCloseKey(coclass_key); 2064 2065 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 2066 } 2067 2068 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN; 2069 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN; 2070 2071 HRESULT WINAPI DllRegisterServer(void) 2072 { 2073 HRESULT hr; 2074 2075 TRACE("\n"); 2076 2077 hr = WIC_DllRegisterServer(); 2078 if (SUCCEEDED(hr)) 2079 hr = register_categories(category_list); 2080 if (SUCCEEDED(hr)) 2081 hr = register_decoders(decoder_list); 2082 if (SUCCEEDED(hr)) 2083 hr = register_encoders(encoder_list); 2084 if (SUCCEEDED(hr)) 2085 hr = register_converters(converter_list); 2086 if (SUCCEEDED(hr)) 2087 hr = register_metadatareaders(metadatareader_list); 2088 if (SUCCEEDED(hr)) 2089 hr = register_pixelformats(pixelformat_list); 2090 return hr; 2091 } 2092 2093 HRESULT WINAPI DllUnregisterServer(void) 2094 { 2095 HRESULT hr; 2096 2097 TRACE("\n"); 2098 2099 hr = WIC_DllUnregisterServer(); 2100 if (SUCCEEDED(hr)) 2101 hr = unregister_categories(category_list); 2102 if (SUCCEEDED(hr)) 2103 hr = unregister_decoders(decoder_list); 2104 if (SUCCEEDED(hr)) 2105 hr = unregister_encoders(encoder_list); 2106 if (SUCCEEDED(hr)) 2107 hr = unregister_converters(converter_list); 2108 if (SUCCEEDED(hr)) 2109 hr = unregister_metadatareaders(metadatareader_list); 2110 if (SUCCEEDED(hr)) 2111 hr = unregister_pixelformats(pixelformat_list); 2112 return hr; 2113 } 2114