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_WICPixelFormat16bppGray, 1198 &GUID_WICPixelFormat32bppGrayFloat, 1199 &GUID_WICPixelFormat1bppIndexed, 1200 &GUID_WICPixelFormat2bppIndexed, 1201 &GUID_WICPixelFormat4bppIndexed, 1202 &GUID_WICPixelFormat8bppIndexed, 1203 &GUID_WICPixelFormat24bppBGR, 1204 &GUID_WICPixelFormat32bppBGR, 1205 &GUID_WICPixelFormat32bppBGRA, 1206 &GUID_WICPixelFormat32bppPBGRA, 1207 &GUID_WICPixelFormat48bppRGB, 1208 &GUID_WICPixelFormat64bppRGBA, 1209 &GUID_WICPixelFormat64bppPRGBA, 1210 &GUID_WICPixelFormat32bppCMYK, 1211 &GUID_WICPixelFormat64bppCMYK, 1212 &GUID_WICPixelFormat128bppRGBAFloat, 1213 NULL 1214 }; 1215 1216 static struct decoder_pattern const tiff_patterns[] = { 1217 {4,0,tiff_magic_le,mask_all,0}, 1218 {4,0,tiff_magic_be,mask_all,0}, 1219 {0} 1220 }; 1221 1222 static const BYTE tga_footer_magic[18] = "TRUEVISION-XFILE."; 1223 1224 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}; 1225 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}; 1226 1227 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}; 1228 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}; 1229 1230 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}; 1231 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}; 1232 1233 static GUID const * const tga_formats[] = { 1234 &GUID_WICPixelFormat8bppGray, 1235 &GUID_WICPixelFormat8bppIndexed, 1236 &GUID_WICPixelFormat16bppGray, 1237 &GUID_WICPixelFormat16bppBGR555, 1238 &GUID_WICPixelFormat24bppBGR, 1239 &GUID_WICPixelFormat32bppBGRA, 1240 &GUID_WICPixelFormat32bppPBGRA, 1241 NULL 1242 }; 1243 1244 static struct decoder_pattern const tga_patterns[] = { 1245 {18,18,tga_footer_magic,mask_all,1}, 1246 {18,0,tga_indexed_magic,tga_indexed_mask,0}, 1247 {18,0,tga_truecolor_magic,tga_truecolor_mask,0}, 1248 {18,0,tga_grayscale_magic,tga_grayscale_mask,0}, 1249 {0} 1250 }; 1251 1252 static struct regsvr_decoder const decoder_list[] = { 1253 { &CLSID_WICBmpDecoder, 1254 "The Wine Project", 1255 "BMP Decoder", 1256 "1.0.0.0", 1257 &GUID_VendorMicrosoft, 1258 &GUID_ContainerFormatBmp, 1259 "image/bmp", 1260 ".bmp,.dib,.rle", 1261 bmp_formats, 1262 bmp_patterns 1263 }, 1264 { &CLSID_WICGifDecoder, 1265 "The Wine Project", 1266 "GIF Decoder", 1267 "1.0.0.0", 1268 &GUID_VendorMicrosoft, 1269 &GUID_ContainerFormatGif, 1270 "image/gif", 1271 ".gif", 1272 gif_formats, 1273 gif_patterns 1274 }, 1275 { &CLSID_WICIcoDecoder, 1276 "The Wine Project", 1277 "ICO Decoder", 1278 "1.0.0.0", 1279 &GUID_VendorMicrosoft, 1280 &GUID_ContainerFormatIco, 1281 "image/vnd.microsoft.icon", 1282 ".ico", 1283 ico_formats, 1284 ico_patterns 1285 }, 1286 { &CLSID_WICJpegDecoder, 1287 "The Wine Project", 1288 "JPEG Decoder", 1289 "1.0.0.0", 1290 &GUID_VendorMicrosoft, 1291 &GUID_ContainerFormatJpeg, 1292 "image/jpeg", 1293 ".jpg;.jpeg;.jfif", 1294 jpeg_formats, 1295 jpeg_patterns 1296 }, 1297 { &CLSID_WICPngDecoder, 1298 "The Wine Project", 1299 "PNG Decoder", 1300 "1.0.0.0", 1301 &GUID_VendorMicrosoft, 1302 &GUID_ContainerFormatPng, 1303 "image/png", 1304 ".png", 1305 png_formats, 1306 png_patterns 1307 }, 1308 { &CLSID_WICTiffDecoder, 1309 "The Wine Project", 1310 "TIFF Decoder", 1311 "1.0.0.0", 1312 &GUID_VendorMicrosoft, 1313 &GUID_ContainerFormatTiff, 1314 "image/tiff", 1315 ".tif;.tiff", 1316 tiff_decode_formats, 1317 tiff_patterns 1318 }, 1319 { &CLSID_WineTgaDecoder, 1320 "The Wine Project", 1321 "TGA Decoder", 1322 "1.0.0.0", 1323 &GUID_VendorWine, 1324 &GUID_WineContainerFormatTga, 1325 "image/x-targa", 1326 ".tga;.tpic", 1327 tga_formats, 1328 tga_patterns 1329 }, 1330 { NULL } /* list terminator */ 1331 }; 1332 1333 static GUID const * const bmp_encode_formats[] = { 1334 &GUID_WICPixelFormat16bppBGR555, 1335 &GUID_WICPixelFormat16bppBGR565, 1336 &GUID_WICPixelFormat24bppBGR, 1337 &GUID_WICPixelFormat32bppBGR, 1338 &GUID_WICPixelFormatBlackWhite, 1339 &GUID_WICPixelFormat1bppIndexed, 1340 &GUID_WICPixelFormat2bppIndexed, 1341 &GUID_WICPixelFormat4bppIndexed, 1342 &GUID_WICPixelFormat8bppIndexed, 1343 NULL 1344 }; 1345 1346 static GUID const * const png_encode_formats[] = { 1347 &GUID_WICPixelFormat24bppBGR, 1348 &GUID_WICPixelFormatBlackWhite, 1349 &GUID_WICPixelFormat2bppGray, 1350 &GUID_WICPixelFormat4bppGray, 1351 &GUID_WICPixelFormat8bppGray, 1352 &GUID_WICPixelFormat16bppGray, 1353 &GUID_WICPixelFormat32bppBGR, 1354 &GUID_WICPixelFormat32bppBGRA, 1355 &GUID_WICPixelFormat48bppRGB, 1356 &GUID_WICPixelFormat64bppRGBA, 1357 &GUID_WICPixelFormat1bppIndexed, 1358 &GUID_WICPixelFormat2bppIndexed, 1359 &GUID_WICPixelFormat4bppIndexed, 1360 &GUID_WICPixelFormat8bppIndexed, 1361 NULL 1362 }; 1363 1364 static GUID const * const tiff_encode_formats[] = { 1365 &GUID_WICPixelFormatBlackWhite, 1366 &GUID_WICPixelFormat4bppGray, 1367 &GUID_WICPixelFormat8bppGray, 1368 &GUID_WICPixelFormat1bppIndexed, 1369 &GUID_WICPixelFormat2bppIndexed, 1370 &GUID_WICPixelFormat4bppIndexed, 1371 &GUID_WICPixelFormat8bppIndexed, 1372 &GUID_WICPixelFormat24bppBGR, 1373 &GUID_WICPixelFormat32bppBGRA, 1374 &GUID_WICPixelFormat32bppPBGRA, 1375 &GUID_WICPixelFormat48bppRGB, 1376 &GUID_WICPixelFormat64bppRGBA, 1377 &GUID_WICPixelFormat64bppPRGBA, 1378 NULL 1379 }; 1380 1381 static GUID const * const icns_encode_formats[] = { 1382 &GUID_WICPixelFormat32bppBGRA, 1383 NULL 1384 }; 1385 1386 static struct regsvr_encoder const encoder_list[] = { 1387 { &CLSID_WICBmpEncoder, 1388 "The Wine Project", 1389 "BMP Encoder", 1390 "1.0.0.0", 1391 &GUID_VendorMicrosoft, 1392 &GUID_ContainerFormatBmp, 1393 "image/bmp", 1394 ".bmp,.dib,.rle", 1395 bmp_encode_formats 1396 }, 1397 { &CLSID_WICGifEncoder, 1398 "The Wine Project", 1399 "GIF Encoder", 1400 "1.0.0.0", 1401 &GUID_VendorMicrosoft, 1402 &GUID_ContainerFormatGif, 1403 "image/gif", 1404 ".gif", 1405 gif_formats 1406 }, 1407 { &CLSID_WICJpegEncoder, 1408 "The Wine Project", 1409 "JPEG Encoder", 1410 "1.0.0.0", 1411 &GUID_VendorMicrosoft, 1412 &GUID_ContainerFormatJpeg, 1413 "image/jpeg", 1414 ".jpg;.jpeg;.jfif", 1415 jpeg_formats 1416 }, 1417 { &CLSID_WICPngEncoder, 1418 "The Wine Project", 1419 "PNG Encoder", 1420 "1.0.0.0", 1421 &GUID_VendorMicrosoft, 1422 &GUID_ContainerFormatPng, 1423 "image/png", 1424 ".png", 1425 png_encode_formats 1426 }, 1427 { &CLSID_WICTiffEncoder, 1428 "The Wine Project", 1429 "TIFF Encoder", 1430 "1.0.0.0", 1431 &GUID_VendorMicrosoft, 1432 &GUID_ContainerFormatTiff, 1433 "image/tiff", 1434 ".tif;.tiff", 1435 tiff_encode_formats 1436 }, 1437 { &CLSID_WICIcnsEncoder, 1438 "The Wine Project", 1439 "ICNS Encoder", 1440 "1.0.0.0", 1441 &GUID_VendorWine, 1442 NULL, /* no container format guid */ 1443 "image/icns", 1444 ".icns", 1445 icns_encode_formats 1446 }, 1447 { NULL } /* list terminator */ 1448 }; 1449 1450 static GUID const * const converter_formats[] = { 1451 &GUID_WICPixelFormat1bppIndexed, 1452 &GUID_WICPixelFormat2bppIndexed, 1453 &GUID_WICPixelFormat4bppIndexed, 1454 &GUID_WICPixelFormat8bppIndexed, 1455 &GUID_WICPixelFormatBlackWhite, 1456 &GUID_WICPixelFormat2bppGray, 1457 &GUID_WICPixelFormat4bppGray, 1458 &GUID_WICPixelFormat8bppGray, 1459 &GUID_WICPixelFormat16bppGray, 1460 &GUID_WICPixelFormat16bppBGR555, 1461 &GUID_WICPixelFormat16bppBGR565, 1462 &GUID_WICPixelFormat16bppBGRA5551, 1463 &GUID_WICPixelFormat24bppBGR, 1464 &GUID_WICPixelFormat24bppRGB, 1465 &GUID_WICPixelFormat32bppBGR, 1466 &GUID_WICPixelFormat32bppRGB, 1467 &GUID_WICPixelFormat32bppBGRA, 1468 &GUID_WICPixelFormat32bppRGBA, 1469 &GUID_WICPixelFormat32bppPBGRA, 1470 &GUID_WICPixelFormat32bppPRGBA, 1471 &GUID_WICPixelFormat32bppGrayFloat, 1472 &GUID_WICPixelFormat48bppRGB, 1473 &GUID_WICPixelFormat64bppRGBA, 1474 &GUID_WICPixelFormat32bppCMYK, 1475 NULL 1476 }; 1477 1478 static struct regsvr_converter const converter_list[] = { 1479 { &CLSID_WICDefaultFormatConverter, 1480 "The Wine Project", 1481 "Default Pixel Format Converter", 1482 "1.0.0.0", 1483 &GUID_VendorMicrosoft, 1484 converter_formats 1485 }, 1486 { NULL } /* list terminator */ 1487 }; 1488 1489 static const BYTE no_magic[1] = { 0 }; 1490 static const BYTE no_mask[1] = { 0 }; 1491 1492 static const struct metadata_pattern ifd_metadata_pattern[] = { 1493 { 0, 1, no_magic, no_mask, 0 }, 1494 { 0 } 1495 }; 1496 1497 static const struct reader_containers ifd_containers[] = { 1498 { 1499 &GUID_ContainerFormatTiff, 1500 ifd_metadata_pattern 1501 }, 1502 { NULL } /* list terminator */ 1503 }; 1504 1505 static const BYTE tEXt[] = "tEXt"; 1506 1507 static const struct metadata_pattern pngtext_metadata_pattern[] = { 1508 { 4, 4, tEXt, mask_all, 4 }, 1509 { 0 } 1510 }; 1511 1512 static const struct reader_containers pngtext_containers[] = { 1513 { 1514 &GUID_ContainerFormatPng, 1515 pngtext_metadata_pattern 1516 }, 1517 { NULL } /* list terminator */ 1518 }; 1519 1520 static const BYTE gAMA[] = "gAMA"; 1521 1522 static const struct metadata_pattern pnggama_metadata_pattern[] = { 1523 { 4, 4, gAMA, mask_all, 4 }, 1524 { 0 } 1525 }; 1526 1527 static const struct reader_containers pnggama_containers[] = { 1528 { 1529 &GUID_ContainerFormatPng, 1530 pnggama_metadata_pattern 1531 }, 1532 { NULL } /* list terminator */ 1533 }; 1534 1535 static const BYTE cHRM[] = "cHRM"; 1536 1537 static const struct metadata_pattern pngchrm_metadata_pattern[] = { 1538 { 4, 4, cHRM, mask_all, 4 }, 1539 { 0 } 1540 }; 1541 1542 static const struct reader_containers pngchrm_containers[] = { 1543 { 1544 &GUID_ContainerFormatPng, 1545 pngchrm_metadata_pattern 1546 }, 1547 { NULL } /* list terminator */ 1548 }; 1549 1550 static const struct metadata_pattern lsd_metadata_patterns[] = { 1551 { 0, 6, gif87a_magic, mask_all, 0 }, 1552 { 0, 6, gif89a_magic, mask_all, 0 }, 1553 { 0 } 1554 }; 1555 1556 static const struct reader_containers lsd_containers[] = { 1557 { 1558 &GUID_ContainerFormatGif, 1559 lsd_metadata_patterns 1560 }, 1561 { NULL } /* list terminator */ 1562 }; 1563 1564 static const BYTE imd_magic[] = { 0x2c }; 1565 1566 static const struct metadata_pattern imd_metadata_pattern[] = { 1567 { 0, 1, imd_magic, mask_all, 1 }, 1568 { 0 } 1569 }; 1570 1571 static const struct reader_containers imd_containers[] = { 1572 { 1573 &GUID_ContainerFormatGif, 1574 imd_metadata_pattern 1575 }, 1576 { NULL } /* list terminator */ 1577 }; 1578 1579 static const BYTE gce_magic[] = { 0x21, 0xf9, 0x04 }; 1580 1581 static const struct metadata_pattern gce_metadata_pattern[] = { 1582 { 0, 3, gce_magic, mask_all, 3 }, 1583 { 0 } 1584 }; 1585 1586 static const struct reader_containers gce_containers[] = { 1587 { 1588 &GUID_ContainerFormatGif, 1589 gce_metadata_pattern 1590 }, 1591 { NULL } /* list terminator */ 1592 }; 1593 1594 static const BYTE ape_magic[] = { 0x21, 0xff, 0x0b }; 1595 1596 static const struct metadata_pattern ape_metadata_pattern[] = { 1597 { 0, 3, ape_magic, mask_all, 0 }, 1598 { 0 } 1599 }; 1600 1601 static const struct reader_containers ape_containers[] = { 1602 { 1603 &GUID_ContainerFormatGif, 1604 ape_metadata_pattern 1605 }, 1606 { NULL } /* list terminator */ 1607 }; 1608 1609 static const BYTE gif_comment_magic[] = { 0x21, 0xfe }; 1610 1611 static const struct metadata_pattern gif_comment_metadata_pattern[] = { 1612 { 0, 2, gif_comment_magic, mask_all, 0 }, 1613 { 0 } 1614 }; 1615 1616 static const struct reader_containers gif_comment_containers[] = { 1617 { 1618 &GUID_ContainerFormatGif, 1619 gif_comment_metadata_pattern 1620 }, 1621 { NULL } /* list terminator */ 1622 }; 1623 1624 static struct regsvr_metadatareader const metadatareader_list[] = { 1625 { &CLSID_WICUnknownMetadataReader, 1626 "The Wine Project", 1627 "Unknown Metadata Reader", 1628 "1.0.0.0", 1629 "1.0.0.0", 1630 &GUID_VendorMicrosoft, 1631 &GUID_MetadataFormatUnknown, 1632 0, 0, 0, 1633 NULL 1634 }, 1635 { &CLSID_WICIfdMetadataReader, 1636 "The Wine Project", 1637 "Ifd Reader", 1638 "1.0.0.0", 1639 "1.0.0.0", 1640 &GUID_VendorMicrosoft, 1641 &GUID_MetadataFormatIfd, 1642 1, 1, 0, 1643 ifd_containers 1644 }, 1645 { &CLSID_WICPngChrmMetadataReader, 1646 "The Wine Project", 1647 "Chunk cHRM Reader", 1648 "1.0.0.0", 1649 "1.0.0.0", 1650 &GUID_VendorMicrosoft, 1651 &GUID_MetadataFormatChunkcHRM, 1652 0, 0, 0, 1653 pngchrm_containers 1654 }, 1655 { &CLSID_WICPngGamaMetadataReader, 1656 "The Wine Project", 1657 "Chunk gAMA Reader", 1658 "1.0.0.0", 1659 "1.0.0.0", 1660 &GUID_VendorMicrosoft, 1661 &GUID_MetadataFormatChunkgAMA, 1662 0, 0, 0, 1663 pnggama_containers 1664 }, 1665 { &CLSID_WICPngTextMetadataReader, 1666 "The Wine Project", 1667 "Chunk tEXt Reader", 1668 "1.0.0.0", 1669 "1.0.0.0", 1670 &GUID_VendorMicrosoft, 1671 &GUID_MetadataFormatChunktEXt, 1672 0, 0, 0, 1673 pngtext_containers 1674 }, 1675 { &CLSID_WICLSDMetadataReader, 1676 "The Wine Project", 1677 "Logical Screen Descriptor Reader", 1678 "1.0.0.0", 1679 "1.0.0.0", 1680 &GUID_VendorMicrosoft, 1681 &GUID_MetadataFormatLSD, 1682 0, 0, 0, 1683 lsd_containers 1684 }, 1685 { &CLSID_WICIMDMetadataReader, 1686 "The Wine Project", 1687 "Image Descriptor Reader", 1688 "1.0.0.0", 1689 "1.0.0.0", 1690 &GUID_VendorMicrosoft, 1691 &GUID_MetadataFormatIMD, 1692 0, 0, 0, 1693 imd_containers 1694 }, 1695 { &CLSID_WICGCEMetadataReader, 1696 "The Wine Project", 1697 "Graphic Control Extension Reader", 1698 "1.0.0.0", 1699 "1.0.0.0", 1700 &GUID_VendorMicrosoft, 1701 &GUID_MetadataFormatGCE, 1702 0, 0, 0, 1703 gce_containers 1704 }, 1705 { &CLSID_WICAPEMetadataReader, 1706 "The Wine Project", 1707 "Application Extension Reader", 1708 "1.0.0.0", 1709 "1.0.0.0", 1710 &GUID_VendorMicrosoft, 1711 &GUID_MetadataFormatAPE, 1712 0, 0, 0, 1713 ape_containers 1714 }, 1715 { &CLSID_WICGifCommentMetadataReader, 1716 "The Wine Project", 1717 "Comment Extension Reader", 1718 "1.0.0.0", 1719 "1.0.0.0", 1720 &GUID_VendorMicrosoft, 1721 &GUID_MetadataFormatGifComment, 1722 0, 0, 0, 1723 gif_comment_containers 1724 }, 1725 { NULL } /* list terminator */ 1726 }; 1727 1728 static BYTE const channel_mask_1bit[] = { 0x01 }; 1729 static BYTE const channel_mask_2bit[] = { 0x03 }; 1730 static BYTE const channel_mask_4bit[] = { 0x0f }; 1731 1732 static BYTE const channel_mask_8bit[] = { 0xff, 0x00, 0x00, 0x00 }; 1733 static BYTE const channel_mask_8bit2[] = { 0x00, 0xff, 0x00, 0x00 }; 1734 static BYTE const channel_mask_8bit3[] = { 0x00, 0x00, 0xff, 0x00 }; 1735 static BYTE const channel_mask_8bit4[] = { 0x00, 0x00, 0x00, 0xff }; 1736 1737 static BYTE const channel_mask_16bit[] = { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1738 static BYTE const channel_mask_16bit2[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; 1739 static BYTE const channel_mask_16bit3[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 }; 1740 static BYTE const channel_mask_16bit4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }; 1741 1742 static BYTE const channel_mask_32bit[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; 1743 1744 static BYTE const channel_mask_128bit1[] = { 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; 1745 static BYTE const channel_mask_128bit2[] = { 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; 1746 static BYTE const channel_mask_128bit3[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00 }; 1747 static BYTE const channel_mask_128bit4[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff }; 1748 1749 static BYTE const channel_mask_5bit[] = { 0x1f, 0x00 }; 1750 static BYTE const channel_mask_5bit2[] = { 0xe0, 0x03 }; 1751 static BYTE const channel_mask_5bit3[] = { 0x00, 0x7c }; 1752 static BYTE const channel_mask_5bit4[] = { 0x00, 0x80 }; 1753 1754 static BYTE const channel_mask_BGR565_2[] = { 0xe0, 0x07 }; 1755 static BYTE const channel_mask_BGR565_3[] = { 0x00, 0xf8 }; 1756 1757 static BYTE const * const channel_masks_1bit[] = { channel_mask_1bit }; 1758 static BYTE const * const channel_masks_2bit[] = { channel_mask_2bit }; 1759 static BYTE const * const channel_masks_4bit[] = { channel_mask_4bit }; 1760 static BYTE const * const channel_masks_8bit[] = { channel_mask_8bit, 1761 channel_mask_8bit2, channel_mask_8bit3, channel_mask_8bit4 }; 1762 static BYTE const * const channel_masks_16bit[] = { channel_mask_16bit, 1763 channel_mask_16bit2, channel_mask_16bit3, channel_mask_16bit4}; 1764 1765 static BYTE const * const channel_masks_32bit[] = { channel_mask_32bit }; 1766 static BYTE const * const channel_masks_128bit[] = { channel_mask_128bit1, channel_mask_128bit2, channel_mask_128bit3, channel_mask_128bit4 }; 1767 1768 static BYTE const * const channel_masks_BGRA5551[] = { channel_mask_5bit, 1769 channel_mask_5bit2, channel_mask_5bit3, channel_mask_5bit4 }; 1770 1771 static BYTE const * const channel_masks_BGR565[] = { channel_mask_5bit, 1772 channel_mask_BGR565_2, channel_mask_BGR565_3 }; 1773 1774 static struct regsvr_pixelformat const pixelformat_list[] = { 1775 { &GUID_WICPixelFormat1bppIndexed, 1776 "The Wine Project", 1777 "1bpp Indexed", 1778 NULL, /* no version */ 1779 &GUID_VendorMicrosoft, 1780 1, /* bitsperpixel */ 1781 1, /* channel count */ 1782 channel_masks_1bit, 1783 WICPixelFormatNumericRepresentationIndexed, 1784 0 1785 }, 1786 { &GUID_WICPixelFormat2bppIndexed, 1787 "The Wine Project", 1788 "2bpp Indexed", 1789 NULL, /* no version */ 1790 &GUID_VendorMicrosoft, 1791 2, /* bitsperpixel */ 1792 1, /* channel count */ 1793 channel_masks_2bit, 1794 WICPixelFormatNumericRepresentationIndexed, 1795 0 1796 }, 1797 { &GUID_WICPixelFormat4bppIndexed, 1798 "The Wine Project", 1799 "4bpp Indexed", 1800 NULL, /* no version */ 1801 &GUID_VendorMicrosoft, 1802 4, /* bitsperpixel */ 1803 1, /* channel count */ 1804 channel_masks_4bit, 1805 WICPixelFormatNumericRepresentationIndexed, 1806 0 1807 }, 1808 { &GUID_WICPixelFormat8bppIndexed, 1809 "The Wine Project", 1810 "8bpp Indexed", 1811 NULL, /* no version */ 1812 &GUID_VendorMicrosoft, 1813 8, /* bitsperpixel */ 1814 1, /* channel count */ 1815 channel_masks_8bit, 1816 WICPixelFormatNumericRepresentationIndexed, 1817 0 1818 }, 1819 { &GUID_WICPixelFormatBlackWhite, 1820 "The Wine Project", 1821 "Black and White", 1822 NULL, /* no version */ 1823 &GUID_VendorMicrosoft, 1824 1, /* bitsperpixel */ 1825 1, /* channel count */ 1826 channel_masks_1bit, 1827 WICPixelFormatNumericRepresentationUnsignedInteger, 1828 0 1829 }, 1830 { &GUID_WICPixelFormat2bppGray, 1831 "The Wine Project", 1832 "2bpp Grayscale", 1833 NULL, /* no version */ 1834 &GUID_VendorMicrosoft, 1835 2, /* bitsperpixel */ 1836 1, /* channel count */ 1837 channel_masks_2bit, 1838 WICPixelFormatNumericRepresentationUnsignedInteger, 1839 0 1840 }, 1841 { &GUID_WICPixelFormat4bppGray, 1842 "The Wine Project", 1843 "4bpp Grayscale", 1844 NULL, /* no version */ 1845 &GUID_VendorMicrosoft, 1846 4, /* bitsperpixel */ 1847 1, /* channel count */ 1848 channel_masks_4bit, 1849 WICPixelFormatNumericRepresentationUnsignedInteger, 1850 0 1851 }, 1852 { &GUID_WICPixelFormat8bppGray, 1853 "The Wine Project", 1854 "8bpp Grayscale", 1855 NULL, /* no version */ 1856 &GUID_VendorMicrosoft, 1857 8, /* bitsperpixel */ 1858 1, /* channel count */ 1859 channel_masks_8bit, 1860 WICPixelFormatNumericRepresentationUnsignedInteger, 1861 0 1862 }, 1863 { &GUID_WICPixelFormat16bppGray, 1864 "The Wine Project", 1865 "16bpp Grayscale", 1866 NULL, /* no version */ 1867 &GUID_VendorMicrosoft, 1868 16, /* bitsperpixel */ 1869 1, /* channel count */ 1870 channel_masks_16bit, 1871 WICPixelFormatNumericRepresentationUnsignedInteger, 1872 0 1873 }, 1874 { &GUID_WICPixelFormat16bppBGR555, 1875 "The Wine Project", 1876 "16bpp BGR555", 1877 NULL, /* no version */ 1878 &GUID_VendorMicrosoft, 1879 16, /* bitsperpixel */ 1880 3, /* channel count */ 1881 channel_masks_BGRA5551, 1882 WICPixelFormatNumericRepresentationUnsignedInteger, 1883 0 1884 }, 1885 { &GUID_WICPixelFormat16bppBGR565, 1886 "The Wine Project", 1887 "16bpp BGR565", 1888 NULL, /* no version */ 1889 &GUID_VendorMicrosoft, 1890 16, /* bitsperpixel */ 1891 3, /* channel count */ 1892 channel_masks_BGR565, 1893 WICPixelFormatNumericRepresentationUnsignedInteger, 1894 0 1895 }, 1896 { &GUID_WICPixelFormat16bppBGRA5551, 1897 "The Wine Project", 1898 "16bpp BGRA5551", 1899 NULL, /* no version */ 1900 &GUID_VendorMicrosoft, 1901 16, /* bitsperpixel */ 1902 4, /* channel count */ 1903 channel_masks_BGRA5551, 1904 WICPixelFormatNumericRepresentationUnsignedInteger, 1905 1 1906 }, 1907 { &GUID_WICPixelFormat24bppBGR, 1908 "The Wine Project", 1909 "24bpp BGR", 1910 NULL, /* no version */ 1911 &GUID_VendorMicrosoft, 1912 24, /* bitsperpixel */ 1913 3, /* channel count */ 1914 channel_masks_8bit, 1915 WICPixelFormatNumericRepresentationUnsignedInteger, 1916 0 1917 }, 1918 { &GUID_WICPixelFormat24bppRGB, 1919 "The Wine Project", 1920 "24bpp RGB", 1921 NULL, /* no version */ 1922 &GUID_VendorMicrosoft, 1923 24, /* bitsperpixel */ 1924 3, /* channel count */ 1925 channel_masks_8bit, 1926 WICPixelFormatNumericRepresentationUnsignedInteger, 1927 0 1928 }, 1929 { &GUID_WICPixelFormat32bppBGR, 1930 "The Wine Project", 1931 "32bpp BGR", 1932 NULL, /* no version */ 1933 &GUID_VendorMicrosoft, 1934 32, /* bitsperpixel */ 1935 3, /* channel count */ 1936 channel_masks_8bit, 1937 WICPixelFormatNumericRepresentationUnsignedInteger, 1938 0 1939 }, 1940 { &GUID_WICPixelFormat32bppRGB, 1941 "The Wine Project", 1942 "32bpp RGB", 1943 NULL, /* no version */ 1944 &GUID_VendorMicrosoft, 1945 32, /* bitsperpixel */ 1946 3, /* channel count */ 1947 channel_masks_8bit, 1948 WICPixelFormatNumericRepresentationUnsignedInteger, 1949 0 1950 }, 1951 { &GUID_WICPixelFormat32bppBGRA, 1952 "The Wine Project", 1953 "32bpp BGRA", 1954 NULL, /* no version */ 1955 &GUID_VendorMicrosoft, 1956 32, /* bitsperpixel */ 1957 4, /* channel count */ 1958 channel_masks_8bit, 1959 WICPixelFormatNumericRepresentationUnsignedInteger, 1960 1 1961 }, 1962 { &GUID_WICPixelFormat32bppRGBA, 1963 "The Wine Project", 1964 "32bpp RGBA", 1965 NULL, /* no version */ 1966 &GUID_VendorMicrosoft, 1967 32, /* bitsperpixel */ 1968 4, /* channel count */ 1969 channel_masks_8bit, 1970 WICPixelFormatNumericRepresentationUnsignedInteger, 1971 1 1972 }, 1973 { &GUID_WICPixelFormat32bppPBGRA, 1974 "The Wine Project", 1975 "32bpp PBGRA", 1976 NULL, /* no version */ 1977 &GUID_VendorMicrosoft, 1978 32, /* bitsperpixel */ 1979 4, /* channel count */ 1980 channel_masks_8bit, 1981 WICPixelFormatNumericRepresentationUnsignedInteger, 1982 1 1983 }, 1984 { &GUID_WICPixelFormat32bppPRGBA, 1985 "The Wine Project", 1986 "32bpp PRGBA", 1987 NULL, /* no version */ 1988 &GUID_VendorMicrosoft, 1989 32, /* bitsperpixel */ 1990 4, /* channel count */ 1991 channel_masks_8bit, 1992 WICPixelFormatNumericRepresentationUnsignedInteger, 1993 1 1994 }, 1995 { &GUID_WICPixelFormat32bppGrayFloat, 1996 "The Wine Project", 1997 "32bpp GrayFloat", 1998 NULL, /* no version */ 1999 &GUID_VendorMicrosoft, 2000 32, /* bitsperpixel */ 2001 1, /* channel count */ 2002 channel_masks_32bit, 2003 WICPixelFormatNumericRepresentationFloat, 2004 0 2005 }, 2006 { &GUID_WICPixelFormat48bppRGB, 2007 "The Wine Project", 2008 "48bpp RGB", 2009 NULL, /* no version */ 2010 &GUID_VendorMicrosoft, 2011 48, /* bitsperpixel */ 2012 3, /* channel count */ 2013 channel_masks_16bit, 2014 WICPixelFormatNumericRepresentationUnsignedInteger, 2015 0 2016 }, 2017 { &GUID_WICPixelFormat64bppRGBA, 2018 "The Wine Project", 2019 "64bpp RGBA", 2020 NULL, /* no version */ 2021 &GUID_VendorMicrosoft, 2022 64, /* bitsperpixel */ 2023 4, /* channel count */ 2024 channel_masks_16bit, 2025 WICPixelFormatNumericRepresentationUnsignedInteger, 2026 1 2027 }, 2028 { &GUID_WICPixelFormat64bppPRGBA, 2029 "The Wine Project", 2030 "64bpp PRGBA", 2031 NULL, /* no version */ 2032 &GUID_VendorMicrosoft, 2033 64, /* bitsperpixel */ 2034 4, /* channel count */ 2035 channel_masks_16bit, 2036 WICPixelFormatNumericRepresentationUnsignedInteger, 2037 1 2038 }, 2039 { &GUID_WICPixelFormat32bppCMYK, 2040 "The Wine Project", 2041 "32bpp CMYK", 2042 NULL, /* no version */ 2043 &GUID_VendorMicrosoft, 2044 32, /* bitsperpixel */ 2045 4, /* channel count */ 2046 channel_masks_8bit, 2047 WICPixelFormatNumericRepresentationUnsignedInteger, 2048 0 2049 }, 2050 { &GUID_WICPixelFormat64bppCMYK, 2051 "The Wine Project", 2052 "64bpp CMYK", 2053 NULL, /* no version */ 2054 &GUID_VendorMicrosoft, 2055 64, /* bitsperpixel */ 2056 4, /* channel count */ 2057 channel_masks_16bit, 2058 WICPixelFormatNumericRepresentationUnsignedInteger, 2059 0 2060 }, 2061 { &GUID_WICPixelFormat128bppRGBAFloat, 2062 "The Wine Project", 2063 "128bpp RGBAFloat", 2064 NULL, /* no version */ 2065 &GUID_VendorMicrosoft, 2066 128, /* bitsperpixel */ 2067 4, /* channel count */ 2068 channel_masks_128bit, 2069 WICPixelFormatNumericRepresentationFloat, 2070 1 2071 }, 2072 { NULL } /* list terminator */ 2073 }; 2074 2075 struct regsvr_category 2076 { 2077 const CLSID *clsid; /* NULL for end of list */ 2078 }; 2079 2080 static const struct regsvr_category category_list[] = { 2081 { &CATID_WICBitmapDecoders }, 2082 { &CATID_WICBitmapEncoders }, 2083 { &CATID_WICFormatConverters }, 2084 { &CATID_WICMetadataReader }, 2085 { &CATID_WICPixelFormats }, 2086 { NULL } 2087 }; 2088 2089 static HRESULT register_categories(const struct regsvr_category *list) 2090 { 2091 LONG res; 2092 WCHAR buf[39]; 2093 HKEY coclass_key, categories_key, instance_key; 2094 2095 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, 2096 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); 2097 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); 2098 2099 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 2100 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, 2101 KEY_READ | KEY_WRITE, NULL, &categories_key, NULL); 2102 if (res != ERROR_SUCCESS) 2103 { 2104 RegCloseKey(coclass_key); 2105 return HRESULT_FROM_WIN32(res); 2106 } 2107 2108 res = RegCreateKeyExW(categories_key, instance_keyname, 0, NULL, 0, 2109 KEY_READ | KEY_WRITE, NULL, &instance_key, NULL); 2110 2111 for (; res == ERROR_SUCCESS && list->clsid; list++) 2112 { 2113 HKEY instance_clsid_key; 2114 2115 StringFromGUID2(list->clsid, buf, 39); 2116 res = RegCreateKeyExW(instance_key, buf, 0, NULL, 0, 2117 KEY_READ | KEY_WRITE, NULL, &instance_clsid_key, NULL); 2118 if (res == ERROR_SUCCESS) 2119 { 2120 res = RegSetValueExW(instance_clsid_key, clsid_valuename, 0, REG_SZ, 2121 (const BYTE *)buf, 78); 2122 RegCloseKey(instance_clsid_key); 2123 } 2124 } 2125 2126 RegCloseKey(instance_key); 2127 RegCloseKey(categories_key); 2128 RegCloseKey(coclass_key); 2129 2130 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 2131 } 2132 2133 static HRESULT unregister_categories(const struct regsvr_category *list) 2134 { 2135 LONG res; 2136 WCHAR buf[39]; 2137 HKEY coclass_key, categories_key, instance_key; 2138 2139 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, 2140 KEY_READ | KEY_WRITE, &coclass_key); 2141 if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res); 2142 2143 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 2144 res = RegOpenKeyExW(coclass_key, buf, 0, 2145 KEY_READ | KEY_WRITE, &categories_key); 2146 if (res != ERROR_SUCCESS) 2147 { 2148 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; 2149 RegCloseKey(coclass_key); 2150 return HRESULT_FROM_WIN32(res); 2151 } 2152 2153 res = RegOpenKeyExW(categories_key, instance_keyname, 0, 2154 KEY_READ | KEY_WRITE, &instance_key); 2155 2156 for (; res == ERROR_SUCCESS && list->clsid; list++) 2157 { 2158 StringFromGUID2(list->clsid, buf, 39); 2159 res = RegDeleteTreeW(instance_key, buf); 2160 } 2161 2162 RegCloseKey(instance_key); 2163 RegCloseKey(categories_key); 2164 2165 StringFromGUID2(&CLSID_WICImagingCategories, buf, 39); 2166 res = RegDeleteTreeW(coclass_key, buf); 2167 2168 RegCloseKey(coclass_key); 2169 2170 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; 2171 } 2172 2173 extern HRESULT WINAPI WIC_DllRegisterServer(void) DECLSPEC_HIDDEN; 2174 extern HRESULT WINAPI WIC_DllUnregisterServer(void) DECLSPEC_HIDDEN; 2175 2176 HRESULT WINAPI DllRegisterServer(void) 2177 { 2178 HRESULT hr; 2179 2180 TRACE("\n"); 2181 2182 hr = WIC_DllRegisterServer(); 2183 if (SUCCEEDED(hr)) 2184 hr = register_categories(category_list); 2185 if (SUCCEEDED(hr)) 2186 hr = register_decoders(decoder_list); 2187 if (SUCCEEDED(hr)) 2188 hr = register_encoders(encoder_list); 2189 if (SUCCEEDED(hr)) 2190 hr = register_converters(converter_list); 2191 if (SUCCEEDED(hr)) 2192 hr = register_metadatareaders(metadatareader_list); 2193 if (SUCCEEDED(hr)) 2194 hr = register_pixelformats(pixelformat_list); 2195 return hr; 2196 } 2197 2198 HRESULT WINAPI DllUnregisterServer(void) 2199 { 2200 HRESULT hr; 2201 2202 TRACE("\n"); 2203 2204 hr = WIC_DllUnregisterServer(); 2205 if (SUCCEEDED(hr)) 2206 hr = unregister_categories(category_list); 2207 if (SUCCEEDED(hr)) 2208 hr = unregister_decoders(decoder_list); 2209 if (SUCCEEDED(hr)) 2210 hr = unregister_encoders(encoder_list); 2211 if (SUCCEEDED(hr)) 2212 hr = unregister_converters(converter_list); 2213 if (SUCCEEDED(hr)) 2214 hr = unregister_metadatareaders(metadatareader_list); 2215 if (SUCCEEDED(hr)) 2216 hr = unregister_pixelformats(pixelformat_list); 2217 return hr; 2218 } 2219