1 /* 2 * Copyright 2009 Vincent Povirk for CodeWeavers 3 * Copyright 2012 Dmitry Timoshkov 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include "config.h" 21 22 #include <assert.h> 23 #include <stdarg.h> 24 25 #define COBJMACROS 26 27 #include "windef.h" 28 #include "winbase.h" 29 #include "winreg.h" 30 #include "objbase.h" 31 #include "shellapi.h" 32 33 #include "wincodecs_private.h" 34 35 #include "wine/debug.h" 36 37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); 38 39 typedef struct { 40 IWICImagingFactory2 IWICImagingFactory2_iface; 41 IWICComponentFactory IWICComponentFactory_iface; 42 LONG ref; 43 } ImagingFactory; 44 45 static inline ImagingFactory *impl_from_IWICComponentFactory(IWICComponentFactory *iface) 46 { 47 return CONTAINING_RECORD(iface, ImagingFactory, IWICComponentFactory_iface); 48 } 49 50 static inline ImagingFactory *impl_from_IWICImagingFactory2(IWICImagingFactory2 *iface) 51 { 52 return CONTAINING_RECORD(iface, ImagingFactory, IWICImagingFactory2_iface); 53 } 54 55 static HRESULT WINAPI ImagingFactory_QueryInterface(IWICImagingFactory2 *iface, REFIID iid, 56 void **ppv) 57 { 58 ImagingFactory *This = impl_from_IWICImagingFactory2(iface); 59 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); 60 61 if (!ppv) return E_INVALIDARG; 62 63 if (IsEqualIID(&IID_IUnknown, iid) || 64 IsEqualIID(&IID_IWICImagingFactory, iid) || 65 IsEqualIID(&IID_IWICComponentFactory, iid)) 66 { 67 *ppv = &This->IWICComponentFactory_iface; 68 } 69 else if (IsEqualIID(&IID_IWICImagingFactory2, iid)) 70 { 71 *ppv = &This->IWICImagingFactory2_iface; 72 } 73 else 74 { 75 *ppv = NULL; 76 return E_NOINTERFACE; 77 } 78 79 IUnknown_AddRef((IUnknown*)*ppv); 80 return S_OK; 81 } 82 83 static ULONG WINAPI ImagingFactory_AddRef(IWICImagingFactory2 *iface) 84 { 85 ImagingFactory *This = impl_from_IWICImagingFactory2(iface); 86 ULONG ref = InterlockedIncrement(&This->ref); 87 88 TRACE("(%p) refcount=%u\n", iface, ref); 89 90 return ref; 91 } 92 93 static ULONG WINAPI ImagingFactory_Release(IWICImagingFactory2 *iface) 94 { 95 ImagingFactory *This = impl_from_IWICImagingFactory2(iface); 96 ULONG ref = InterlockedDecrement(&This->ref); 97 98 TRACE("(%p) refcount=%u\n", iface, ref); 99 100 if (ref == 0) 101 HeapFree(GetProcessHeap(), 0, This); 102 103 return ref; 104 } 105 106 static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename( 107 IWICImagingFactory2 *iface, LPCWSTR wzFilename, const GUID *pguidVendor, 108 DWORD dwDesiredAccess, WICDecodeOptions metadataOptions, 109 IWICBitmapDecoder **ppIDecoder) 110 { 111 IWICStream *stream; 112 HRESULT hr; 113 114 TRACE("(%p,%s,%s,%u,%u,%p)\n", iface, debugstr_w(wzFilename), 115 debugstr_guid(pguidVendor), dwDesiredAccess, metadataOptions, ppIDecoder); 116 117 hr = StreamImpl_Create(&stream); 118 if (SUCCEEDED(hr)) 119 { 120 hr = IWICStream_InitializeFromFilename(stream, wzFilename, dwDesiredAccess); 121 122 if (SUCCEEDED(hr)) 123 { 124 hr = IWICImagingFactory2_CreateDecoderFromStream(iface, (IStream*)stream, 125 pguidVendor, metadataOptions, ppIDecoder); 126 } 127 128 IWICStream_Release(stream); 129 } 130 131 return hr; 132 } 133 134 static HRESULT find_decoder(IStream *pIStream, const GUID *pguidVendor, 135 WICDecodeOptions metadataOptions, IWICBitmapDecoder **decoder) 136 { 137 IEnumUnknown *enumdecoders; 138 IUnknown *unkdecoderinfo; 139 IWICBitmapDecoderInfo *decoderinfo; 140 GUID vendor; 141 HRESULT res; 142 ULONG num_fetched; 143 BOOL matches; 144 145 *decoder = NULL; 146 147 res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders); 148 if (FAILED(res)) return res; 149 150 while (!*decoder) 151 { 152 res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched); 153 154 if (res == S_OK) 155 { 156 res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo); 157 158 if (SUCCEEDED(res)) 159 { 160 if (pguidVendor) 161 { 162 res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor); 163 if (FAILED(res) || !IsEqualIID(&vendor, pguidVendor)) 164 { 165 IWICBitmapDecoderInfo_Release(decoderinfo); 166 IUnknown_Release(unkdecoderinfo); 167 continue; 168 } 169 } 170 171 res = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, pIStream, &matches); 172 173 if (SUCCEEDED(res) && matches) 174 { 175 res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, decoder); 176 177 /* FIXME: should use QueryCapability to choose a decoder */ 178 179 if (SUCCEEDED(res)) 180 { 181 res = IWICBitmapDecoder_Initialize(*decoder, pIStream, metadataOptions); 182 183 if (FAILED(res)) 184 { 185 IWICBitmapDecoder_Release(*decoder); 186 IWICBitmapDecoderInfo_Release(decoderinfo); 187 IUnknown_Release(unkdecoderinfo); 188 IEnumUnknown_Release(enumdecoders); 189 *decoder = NULL; 190 return res; 191 } 192 } 193 } 194 195 IWICBitmapDecoderInfo_Release(decoderinfo); 196 } 197 198 IUnknown_Release(unkdecoderinfo); 199 } 200 else 201 break; 202 } 203 204 IEnumUnknown_Release(enumdecoders); 205 206 return WINCODEC_ERR_COMPONENTNOTFOUND; 207 } 208 209 static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream( 210 IWICImagingFactory2 *iface, IStream *pIStream, const GUID *pguidVendor, 211 WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder) 212 { 213 HRESULT res; 214 IWICBitmapDecoder *decoder = NULL; 215 216 TRACE("(%p,%p,%s,%u,%p)\n", iface, pIStream, debugstr_guid(pguidVendor), 217 metadataOptions, ppIDecoder); 218 219 if (pguidVendor) 220 res = find_decoder(pIStream, pguidVendor, metadataOptions, &decoder); 221 if (!decoder) 222 res = find_decoder(pIStream, NULL, metadataOptions, &decoder); 223 224 if (decoder) 225 { 226 *ppIDecoder = decoder; 227 return S_OK; 228 } 229 else 230 { 231 if (WARN_ON(wincodecs)) 232 { 233 LARGE_INTEGER seek; 234 BYTE data[4]; 235 ULONG bytesread; 236 237 WARN("failed to load from a stream %#x\n", res); 238 239 seek.QuadPart = 0; 240 if (IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL) == S_OK) 241 { 242 if (IStream_Read(pIStream, data, 4, &bytesread) == S_OK) 243 WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]); 244 } 245 } 246 *ppIDecoder = NULL; 247 return res; 248 } 249 } 250 251 static HRESULT WINAPI ImagingFactory_CreateDecoderFromFileHandle( 252 IWICImagingFactory2 *iface, ULONG_PTR hFile, const GUID *pguidVendor, 253 WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder) 254 { 255 IWICStream *stream; 256 HRESULT hr; 257 258 TRACE("(%p,%lx,%s,%u,%p)\n", iface, hFile, debugstr_guid(pguidVendor), 259 metadataOptions, ppIDecoder); 260 261 hr = StreamImpl_Create(&stream); 262 if (SUCCEEDED(hr)) 263 { 264 hr = stream_initialize_from_filehandle(stream, (HANDLE)hFile); 265 if (SUCCEEDED(hr)) 266 { 267 hr = IWICImagingFactory2_CreateDecoderFromStream(iface, (IStream*)stream, 268 pguidVendor, metadataOptions, ppIDecoder); 269 } 270 IWICStream_Release(stream); 271 } 272 return hr; 273 } 274 275 static HRESULT WINAPI ImagingFactory_CreateComponentInfo(IWICImagingFactory2 *iface, 276 REFCLSID clsidComponent, IWICComponentInfo **ppIInfo) 277 { 278 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(clsidComponent), ppIInfo); 279 return CreateComponentInfo(clsidComponent, ppIInfo); 280 } 281 282 static HRESULT WINAPI ImagingFactory_CreateDecoder(IWICImagingFactory2 *iface, 283 REFGUID guidContainerFormat, const GUID *pguidVendor, 284 IWICBitmapDecoder **ppIDecoder) 285 { 286 IEnumUnknown *enumdecoders; 287 IUnknown *unkdecoderinfo; 288 IWICBitmapDecoderInfo *decoderinfo; 289 IWICBitmapDecoder *decoder = NULL, *preferred_decoder = NULL; 290 GUID vendor; 291 HRESULT res; 292 ULONG num_fetched; 293 294 TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat), 295 debugstr_guid(pguidVendor), ppIDecoder); 296 297 if (!guidContainerFormat || !ppIDecoder) return E_INVALIDARG; 298 299 res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders); 300 if (FAILED(res)) return res; 301 302 while (!preferred_decoder) 303 { 304 res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched); 305 if (res != S_OK) break; 306 307 res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void **)&decoderinfo); 308 if (SUCCEEDED(res)) 309 { 310 GUID container_guid; 311 312 res = IWICBitmapDecoderInfo_GetContainerFormat(decoderinfo, &container_guid); 313 if (SUCCEEDED(res) && IsEqualIID(&container_guid, guidContainerFormat)) 314 { 315 IWICBitmapDecoder *new_decoder; 316 317 res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &new_decoder); 318 if (SUCCEEDED(res)) 319 { 320 if (pguidVendor) 321 { 322 res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor); 323 if (SUCCEEDED(res) && IsEqualIID(&vendor, pguidVendor)) 324 { 325 preferred_decoder = new_decoder; 326 new_decoder = NULL; 327 } 328 } 329 330 if (new_decoder && !decoder) 331 { 332 decoder = new_decoder; 333 new_decoder = NULL; 334 } 335 336 if (new_decoder) IWICBitmapDecoder_Release(new_decoder); 337 } 338 } 339 340 IWICBitmapDecoderInfo_Release(decoderinfo); 341 } 342 343 IUnknown_Release(unkdecoderinfo); 344 } 345 346 IEnumUnknown_Release(enumdecoders); 347 348 if (preferred_decoder) 349 { 350 *ppIDecoder = preferred_decoder; 351 if (decoder) IWICBitmapDecoder_Release(decoder); 352 return S_OK; 353 } 354 355 if (decoder) 356 { 357 *ppIDecoder = decoder; 358 return S_OK; 359 } 360 361 *ppIDecoder = NULL; 362 return WINCODEC_ERR_COMPONENTNOTFOUND; 363 } 364 365 static HRESULT WINAPI ImagingFactory_CreateEncoder(IWICImagingFactory2 *iface, 366 REFGUID guidContainerFormat, const GUID *pguidVendor, 367 IWICBitmapEncoder **ppIEncoder) 368 { 369 static int fixme=0; 370 IEnumUnknown *enumencoders; 371 IUnknown *unkencoderinfo; 372 IWICBitmapEncoderInfo *encoderinfo; 373 IWICBitmapEncoder *encoder=NULL; 374 HRESULT res=S_OK; 375 ULONG num_fetched; 376 GUID actual_containerformat; 377 378 TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat), 379 debugstr_guid(pguidVendor), ppIEncoder); 380 381 if (pguidVendor && !fixme++) 382 FIXME("ignoring vendor GUID\n"); 383 384 res = CreateComponentEnumerator(WICEncoder, WICComponentEnumerateDefault, &enumencoders); 385 if (FAILED(res)) return res; 386 387 while (!encoder) 388 { 389 res = IEnumUnknown_Next(enumencoders, 1, &unkencoderinfo, &num_fetched); 390 391 if (res == S_OK) 392 { 393 res = IUnknown_QueryInterface(unkencoderinfo, &IID_IWICBitmapEncoderInfo, (void**)&encoderinfo); 394 395 if (SUCCEEDED(res)) 396 { 397 res = IWICBitmapEncoderInfo_GetContainerFormat(encoderinfo, &actual_containerformat); 398 399 if (SUCCEEDED(res) && IsEqualGUID(guidContainerFormat, &actual_containerformat)) 400 { 401 res = IWICBitmapEncoderInfo_CreateInstance(encoderinfo, &encoder); 402 if (FAILED(res)) 403 encoder = NULL; 404 } 405 406 IWICBitmapEncoderInfo_Release(encoderinfo); 407 } 408 409 IUnknown_Release(unkencoderinfo); 410 } 411 else 412 break; 413 } 414 415 IEnumUnknown_Release(enumencoders); 416 417 if (encoder) 418 { 419 *ppIEncoder = encoder; 420 return S_OK; 421 } 422 else 423 { 424 WARN("failed to create encoder\n"); 425 *ppIEncoder = NULL; 426 return WINCODEC_ERR_COMPONENTNOTFOUND; 427 } 428 } 429 430 static HRESULT WINAPI ImagingFactory_CreatePalette(IWICImagingFactory2 *iface, 431 IWICPalette **ppIPalette) 432 { 433 TRACE("(%p,%p)\n", iface, ppIPalette); 434 return PaletteImpl_Create(ppIPalette); 435 } 436 437 static HRESULT WINAPI ImagingFactory_CreateFormatConverter(IWICImagingFactory2 *iface, 438 IWICFormatConverter **ppIFormatConverter) 439 { 440 return FormatConverter_CreateInstance(&IID_IWICFormatConverter, (void**)ppIFormatConverter); 441 } 442 443 static HRESULT WINAPI ImagingFactory_CreateBitmapScaler(IWICImagingFactory2 *iface, 444 IWICBitmapScaler **ppIBitmapScaler) 445 { 446 TRACE("(%p,%p)\n", iface, ppIBitmapScaler); 447 448 return BitmapScaler_Create(ppIBitmapScaler); 449 } 450 451 static HRESULT WINAPI ImagingFactory_CreateBitmapClipper(IWICImagingFactory2 *iface, 452 IWICBitmapClipper **ppIBitmapClipper) 453 { 454 TRACE("(%p,%p)\n", iface, ppIBitmapClipper); 455 return BitmapClipper_Create(ppIBitmapClipper); 456 } 457 458 static HRESULT WINAPI ImagingFactory_CreateBitmapFlipRotator(IWICImagingFactory2 *iface, 459 IWICBitmapFlipRotator **ppIBitmapFlipRotator) 460 { 461 TRACE("(%p,%p)\n", iface, ppIBitmapFlipRotator); 462 return FlipRotator_Create(ppIBitmapFlipRotator); 463 } 464 465 static HRESULT WINAPI ImagingFactory_CreateStream(IWICImagingFactory2 *iface, 466 IWICStream **ppIWICStream) 467 { 468 TRACE("(%p,%p)\n", iface, ppIWICStream); 469 return StreamImpl_Create(ppIWICStream); 470 } 471 472 static HRESULT WINAPI ImagingFactory_CreateColorContext(IWICImagingFactory2 *iface, 473 IWICColorContext **ppIColorContext) 474 { 475 TRACE("(%p,%p)\n", iface, ppIColorContext); 476 return ColorContext_Create(ppIColorContext); 477 } 478 479 static HRESULT WINAPI ImagingFactory_CreateColorTransformer(IWICImagingFactory2 *iface, 480 IWICColorTransform **ppIColorTransform) 481 { 482 TRACE("(%p,%p)\n", iface, ppIColorTransform); 483 return ColorTransform_Create(ppIColorTransform); 484 } 485 486 static HRESULT WINAPI ImagingFactory_CreateBitmap(IWICImagingFactory2 *iface, 487 UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat, 488 WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap) 489 { 490 TRACE("(%p,%u,%u,%s,%u,%p)\n", iface, uiWidth, uiHeight, 491 debugstr_guid(pixelFormat), option, ppIBitmap); 492 return BitmapImpl_Create(uiWidth, uiHeight, 0, 0, NULL, 0, pixelFormat, option, ppIBitmap); 493 } 494 495 static HRESULT create_bitmap_from_source_rect(IWICBitmapSource *piBitmapSource, const WICRect *rect, 496 WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap) 497 { 498 IWICBitmap *result; 499 IWICBitmapLock *lock; 500 IWICPalette *palette; 501 UINT width, height; 502 WICPixelFormatGUID pixelformat = {0}; 503 HRESULT hr; 504 WICRect rc; 505 double dpix, dpiy; 506 IWICComponentInfo *info; 507 IWICPixelFormatInfo2 *formatinfo; 508 WICPixelFormatNumericRepresentation format_type; 509 510 assert(!rect || option == WICBitmapCacheOnLoad); 511 512 if (!piBitmapSource || !ppIBitmap) 513 return E_INVALIDARG; 514 515 if (option == WICBitmapNoCache && SUCCEEDED(IWICBitmapSource_QueryInterface(piBitmapSource, 516 &IID_IWICBitmap, (void **)&result))) 517 { 518 *ppIBitmap = result; 519 return S_OK; 520 } 521 522 hr = IWICBitmapSource_GetSize(piBitmapSource, &width, &height); 523 524 if (SUCCEEDED(hr) && rect) 525 { 526 if (rect->X >= width || rect->Y >= height || rect->Width == 0 || rect->Height == 0) 527 return E_INVALIDARG; 528 529 width = min(width - rect->X, rect->Width); 530 height = min(height - rect->Y, rect->Height); 531 } 532 533 if (SUCCEEDED(hr)) 534 hr = IWICBitmapSource_GetPixelFormat(piBitmapSource, &pixelformat); 535 536 if (SUCCEEDED(hr)) 537 hr = CreateComponentInfo(&pixelformat, &info); 538 539 if (SUCCEEDED(hr)) 540 { 541 hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void**)&formatinfo); 542 543 if (SUCCEEDED(hr)) 544 { 545 hr = IWICPixelFormatInfo2_GetNumericRepresentation(formatinfo, &format_type); 546 547 IWICPixelFormatInfo2_Release(formatinfo); 548 } 549 550 IWICComponentInfo_Release(info); 551 } 552 553 if (SUCCEEDED(hr)) 554 hr = BitmapImpl_Create(width, height, 0, 0, NULL, 0, &pixelformat, option, &result); 555 556 if (SUCCEEDED(hr)) 557 { 558 hr = IWICBitmap_Lock(result, NULL, WICBitmapLockWrite, &lock); 559 if (SUCCEEDED(hr)) 560 { 561 UINT stride, buffersize; 562 BYTE *buffer; 563 564 if (rect) 565 { 566 rc.X = rect->X; 567 rc.Y = rect->Y; 568 } 569 else 570 rc.X = rc.Y = 0; 571 rc.Width = width; 572 rc.Height = height; 573 574 hr = IWICBitmapLock_GetStride(lock, &stride); 575 576 if (SUCCEEDED(hr)) 577 hr = IWICBitmapLock_GetDataPointer(lock, &buffersize, &buffer); 578 579 if (SUCCEEDED(hr)) 580 hr = IWICBitmapSource_CopyPixels(piBitmapSource, &rc, stride, 581 buffersize, buffer); 582 583 IWICBitmapLock_Release(lock); 584 } 585 586 if (SUCCEEDED(hr) && (format_type == WICPixelFormatNumericRepresentationUnspecified || 587 format_type == WICPixelFormatNumericRepresentationIndexed)) 588 { 589 hr = PaletteImpl_Create(&palette); 590 591 if (SUCCEEDED(hr)) 592 { 593 hr = IWICBitmapSource_CopyPalette(piBitmapSource, palette); 594 595 if (SUCCEEDED(hr)) 596 hr = IWICBitmap_SetPalette(result, palette); 597 else 598 hr = S_OK; 599 600 IWICPalette_Release(palette); 601 } 602 } 603 604 if (SUCCEEDED(hr)) 605 { 606 hr = IWICBitmapSource_GetResolution(piBitmapSource, &dpix, &dpiy); 607 608 if (SUCCEEDED(hr)) 609 hr = IWICBitmap_SetResolution(result, dpix, dpiy); 610 else 611 hr = S_OK; 612 } 613 614 if (SUCCEEDED(hr)) 615 *ppIBitmap = result; 616 else 617 IWICBitmap_Release(result); 618 } 619 620 return hr; 621 } 622 623 static HRESULT WINAPI ImagingFactory_CreateBitmapFromSource(IWICImagingFactory2 *iface, 624 IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option, 625 IWICBitmap **ppIBitmap) 626 { 627 TRACE("(%p,%p,%u,%p)\n", iface, piBitmapSource, option, ppIBitmap); 628 629 return create_bitmap_from_source_rect(piBitmapSource, NULL, option, ppIBitmap); 630 } 631 632 static HRESULT WINAPI ImagingFactory_CreateBitmapFromSourceRect(IWICImagingFactory2 *iface, 633 IWICBitmapSource *piBitmapSource, UINT x, UINT y, UINT width, UINT height, 634 IWICBitmap **ppIBitmap) 635 { 636 WICRect rect; 637 638 TRACE("(%p,%p,%u,%u,%u,%u,%p)\n", iface, piBitmapSource, x, y, width, 639 height, ppIBitmap); 640 641 rect.X = x; 642 rect.Y = y; 643 rect.Width = width; 644 rect.Height = height; 645 646 return create_bitmap_from_source_rect(piBitmapSource, &rect, WICBitmapCacheOnLoad, ppIBitmap); 647 } 648 649 static HRESULT WINAPI ImagingFactory_CreateBitmapFromMemory(IWICImagingFactory2 *iface, 650 UINT width, UINT height, REFWICPixelFormatGUID format, UINT stride, 651 UINT size, BYTE *buffer, IWICBitmap **bitmap) 652 { 653 HRESULT hr; 654 655 TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface, width, height, 656 debugstr_guid(format), stride, size, buffer, bitmap); 657 658 if (!stride || !size || !buffer || !bitmap) return E_INVALIDARG; 659 660 hr = BitmapImpl_Create(width, height, stride, size, NULL, 0, format, WICBitmapCacheOnLoad, bitmap); 661 if (SUCCEEDED(hr)) 662 { 663 IWICBitmapLock *lock; 664 665 hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock); 666 if (SUCCEEDED(hr)) 667 { 668 UINT buffersize; 669 BYTE *data; 670 671 IWICBitmapLock_GetDataPointer(lock, &buffersize, &data); 672 memcpy(data, buffer, buffersize); 673 674 IWICBitmapLock_Release(lock); 675 } 676 else 677 { 678 IWICBitmap_Release(*bitmap); 679 *bitmap = NULL; 680 } 681 } 682 return hr; 683 } 684 685 static BOOL get_16bpp_format(HBITMAP hbm, WICPixelFormatGUID *format) 686 { 687 BOOL ret = TRUE; 688 BITMAPV4HEADER bmh; 689 HDC hdc; 690 691 hdc = CreateCompatibleDC(0); 692 693 memset(&bmh, 0, sizeof(bmh)); 694 bmh.bV4Size = sizeof(bmh); 695 bmh.bV4Width = 1; 696 bmh.bV4Height = 1; 697 bmh.bV4V4Compression = BI_BITFIELDS; 698 bmh.bV4BitCount = 16; 699 700 GetDIBits(hdc, hbm, 0, 0, NULL, (BITMAPINFO *)&bmh, DIB_RGB_COLORS); 701 702 if (bmh.bV4RedMask == 0x7c00 && 703 bmh.bV4GreenMask == 0x3e0 && 704 bmh.bV4BlueMask == 0x1f) 705 { 706 *format = GUID_WICPixelFormat16bppBGR555; 707 } 708 else if (bmh.bV4RedMask == 0xf800 && 709 bmh.bV4GreenMask == 0x7e0 && 710 bmh.bV4BlueMask == 0x1f) 711 { 712 *format = GUID_WICPixelFormat16bppBGR565; 713 } 714 else 715 { 716 FIXME("unrecognized bitfields %x,%x,%x\n", bmh.bV4RedMask, 717 bmh.bV4GreenMask, bmh.bV4BlueMask); 718 ret = FALSE; 719 } 720 721 DeleteDC(hdc); 722 return ret; 723 } 724 725 static HRESULT WINAPI ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory2 *iface, 726 HBITMAP hbm, HPALETTE hpal, WICBitmapAlphaChannelOption option, IWICBitmap **bitmap) 727 { 728 BITMAP bm; 729 HRESULT hr; 730 WICPixelFormatGUID format; 731 IWICBitmapLock *lock; 732 UINT size, num_palette_entries = 0; 733 PALETTEENTRY entry[256]; 734 735 TRACE("(%p,%p,%p,%u,%p)\n", iface, hbm, hpal, option, bitmap); 736 737 if (!bitmap) return E_INVALIDARG; 738 739 if (GetObjectW(hbm, sizeof(bm), &bm) != sizeof(bm)) 740 return WINCODEC_ERR_WIN32ERROR; 741 742 if (hpal) 743 { 744 num_palette_entries = GetPaletteEntries(hpal, 0, 256, entry); 745 if (!num_palette_entries) 746 return WINCODEC_ERR_WIN32ERROR; 747 } 748 749 /* TODO: Figure out the correct format for 16, 32, 64 bpp */ 750 switch(bm.bmBitsPixel) 751 { 752 case 1: 753 format = GUID_WICPixelFormat1bppIndexed; 754 break; 755 case 4: 756 format = GUID_WICPixelFormat4bppIndexed; 757 break; 758 case 8: 759 format = GUID_WICPixelFormat8bppIndexed; 760 break; 761 case 16: 762 if (!get_16bpp_format(hbm, &format)) 763 return E_INVALIDARG; 764 break; 765 case 24: 766 format = GUID_WICPixelFormat24bppBGR; 767 break; 768 case 32: 769 switch (option) 770 { 771 case WICBitmapUseAlpha: 772 format = GUID_WICPixelFormat32bppBGRA; 773 break; 774 case WICBitmapUsePremultipliedAlpha: 775 format = GUID_WICPixelFormat32bppPBGRA; 776 break; 777 case WICBitmapIgnoreAlpha: 778 format = GUID_WICPixelFormat32bppBGR; 779 break; 780 default: 781 return E_INVALIDARG; 782 } 783 break; 784 case 48: 785 format = GUID_WICPixelFormat48bppRGB; 786 break; 787 default: 788 FIXME("unsupported %d bpp\n", bm.bmBitsPixel); 789 return E_INVALIDARG; 790 } 791 792 hr = BitmapImpl_Create(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, 0, NULL, 0, &format, 793 WICBitmapCacheOnLoad, bitmap); 794 if (hr != S_OK) return hr; 795 796 hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock); 797 if (hr == S_OK) 798 { 799 BYTE *buffer; 800 HDC hdc; 801 char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD)]; 802 BITMAPINFO *bmi = (BITMAPINFO *)bmibuf; 803 804 IWICBitmapLock_GetDataPointer(lock, &size, &buffer); 805 806 hdc = CreateCompatibleDC(0); 807 808 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 809 bmi->bmiHeader.biBitCount = 0; 810 GetDIBits(hdc, hbm, 0, 0, NULL, bmi, DIB_RGB_COLORS); 811 bmi->bmiHeader.biHeight = -bm.bmHeight; 812 GetDIBits(hdc, hbm, 0, bm.bmHeight, buffer, bmi, DIB_RGB_COLORS); 813 814 DeleteDC(hdc); 815 IWICBitmapLock_Release(lock); 816 817 if (num_palette_entries) 818 { 819 IWICPalette *palette; 820 WICColor colors[256]; 821 UINT i; 822 823 hr = PaletteImpl_Create(&palette); 824 if (hr == S_OK) 825 { 826 for (i = 0; i < num_palette_entries; i++) 827 colors[i] = 0xff000000 | entry[i].peRed << 16 | 828 entry[i].peGreen << 8 | entry[i].peBlue; 829 830 hr = IWICPalette_InitializeCustom(palette, colors, num_palette_entries); 831 if (hr == S_OK) 832 hr = IWICBitmap_SetPalette(*bitmap, palette); 833 834 IWICPalette_Release(palette); 835 } 836 } 837 } 838 839 if (hr != S_OK) 840 { 841 IWICBitmap_Release(*bitmap); 842 *bitmap = NULL; 843 } 844 845 return hr; 846 } 847 848 static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 *iface, 849 HICON hicon, IWICBitmap **bitmap) 850 { 851 IWICBitmapLock *lock; 852 ICONINFO info; 853 BITMAP bm; 854 int width, height, x, y; 855 UINT stride, size; 856 BYTE *buffer; 857 DWORD *bits; 858 BITMAPINFO bi; 859 HDC hdc; 860 BOOL has_alpha; 861 HRESULT hr; 862 863 TRACE("(%p,%p,%p)\n", iface, hicon, bitmap); 864 865 if (!bitmap) return E_INVALIDARG; 866 867 if (!GetIconInfo(hicon, &info)) 868 return HRESULT_FROM_WIN32(GetLastError()); 869 870 GetObjectW(info.hbmColor ? info.hbmColor : info.hbmMask, sizeof(bm), &bm); 871 872 width = bm.bmWidth; 873 height = info.hbmColor ? abs(bm.bmHeight) : abs(bm.bmHeight) / 2; 874 stride = width * 4; 875 size = stride * height; 876 877 hr = BitmapImpl_Create(width, height, stride, size, NULL, 0, 878 &GUID_WICPixelFormat32bppBGRA, WICBitmapCacheOnLoad, bitmap); 879 if (hr != S_OK) goto failed; 880 881 hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock); 882 if (hr != S_OK) 883 { 884 IWICBitmap_Release(*bitmap); 885 goto failed; 886 } 887 IWICBitmapLock_GetDataPointer(lock, &size, &buffer); 888 889 hdc = CreateCompatibleDC(0); 890 891 memset(&bi, 0, sizeof(bi)); 892 bi.bmiHeader.biSize = sizeof(bi.bmiHeader); 893 bi.bmiHeader.biWidth = width; 894 bi.bmiHeader.biHeight = info.hbmColor ? -height: -height * 2; 895 bi.bmiHeader.biPlanes = 1; 896 bi.bmiHeader.biBitCount = 32; 897 bi.bmiHeader.biCompression = BI_RGB; 898 899 has_alpha = FALSE; 900 901 if (info.hbmColor) 902 { 903 GetDIBits(hdc, info.hbmColor, 0, height, buffer, &bi, DIB_RGB_COLORS); 904 905 if (bm.bmBitsPixel == 32) 906 { 907 /* If any pixel has a non-zero alpha, ignore hbmMask */ 908 bits = (DWORD *)buffer; 909 for (x = 0; x < width && !has_alpha; x++, bits++) 910 { 911 for (y = 0; y < height; y++) 912 { 913 if (*bits & 0xff000000) 914 { 915 has_alpha = TRUE; 916 break; 917 } 918 } 919 } 920 } 921 } 922 else 923 GetDIBits(hdc, info.hbmMask, 0, height, buffer, &bi, DIB_RGB_COLORS); 924 925 if (!has_alpha) 926 { 927 DWORD *rgba; 928 929 if (info.hbmMask) 930 { 931 BYTE *mask; 932 933 mask = HeapAlloc(GetProcessHeap(), 0, size); 934 if (!mask) 935 { 936 IWICBitmapLock_Release(lock); 937 IWICBitmap_Release(*bitmap); 938 DeleteDC(hdc); 939 hr = E_OUTOFMEMORY; 940 goto failed; 941 } 942 943 /* read alpha data from the mask */ 944 GetDIBits(hdc, info.hbmMask, info.hbmColor ? 0 : height, height, mask, &bi, DIB_RGB_COLORS); 945 946 for (y = 0; y < height; y++) 947 { 948 rgba = (DWORD *)(buffer + y * stride); 949 bits = (DWORD *)(mask + y * stride); 950 951 for (x = 0; x < width; x++, rgba++, bits++) 952 { 953 if (*bits) 954 *rgba = 0; 955 else 956 *rgba |= 0xff000000; 957 } 958 } 959 960 HeapFree(GetProcessHeap(), 0, mask); 961 } 962 else 963 { 964 /* set constant alpha of 255 */ 965 for (y = 0; y < height; y++) 966 { 967 rgba = (DWORD *)(buffer + y * stride); 968 for (x = 0; x < width; x++, rgba++) 969 *rgba |= 0xff000000; 970 } 971 } 972 973 } 974 975 IWICBitmapLock_Release(lock); 976 DeleteDC(hdc); 977 978 failed: 979 DeleteObject(info.hbmColor); 980 DeleteObject(info.hbmMask); 981 982 return hr; 983 } 984 985 static HRESULT WINAPI ImagingFactory_CreateComponentEnumerator(IWICImagingFactory2 *iface, 986 DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown) 987 { 988 TRACE("(%p,%u,%u,%p)\n", iface, componentTypes, options, ppIEnumUnknown); 989 return CreateComponentEnumerator(componentTypes, options, ppIEnumUnknown); 990 } 991 992 static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromDecoder( 993 IWICImagingFactory2 *iface, IWICBitmapDecoder *pIDecoder, 994 IWICFastMetadataEncoder **ppIFastEncoder) 995 { 996 FIXME("(%p,%p,%p): stub\n", iface, pIDecoder, ppIFastEncoder); 997 return E_NOTIMPL; 998 } 999 1000 static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromFrameDecode( 1001 IWICImagingFactory2 *iface, IWICBitmapFrameDecode *pIFrameDecoder, 1002 IWICFastMetadataEncoder **ppIFastEncoder) 1003 { 1004 FIXME("(%p,%p,%p): stub\n", iface, pIFrameDecoder, ppIFastEncoder); 1005 return E_NOTIMPL; 1006 } 1007 1008 static HRESULT WINAPI ImagingFactory_CreateQueryWriter(IWICImagingFactory2 *iface, 1009 REFGUID guidMetadataFormat, const GUID *pguidVendor, 1010 IWICMetadataQueryWriter **ppIQueryWriter) 1011 { 1012 FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidMetadataFormat), 1013 debugstr_guid(pguidVendor), ppIQueryWriter); 1014 return E_NOTIMPL; 1015 } 1016 1017 static HRESULT WINAPI ImagingFactory_CreateQueryWriterFromReader(IWICImagingFactory2 *iface, 1018 IWICMetadataQueryReader *pIQueryReader, const GUID *pguidVendor, 1019 IWICMetadataQueryWriter **ppIQueryWriter) 1020 { 1021 FIXME("(%p,%p,%s,%p): stub\n", iface, pIQueryReader, debugstr_guid(pguidVendor), 1022 ppIQueryWriter); 1023 return E_NOTIMPL; 1024 } 1025 1026 #ifndef __REACTOS__ 1027 static HRESULT WINAPI ImagingFactory_CreateImageEncoder(IWICImagingFactory2 *iface, ID2D1Device *device, IWICImageEncoder **encoder) 1028 { 1029 FIXME("%p,%p,%p stub.\n", iface, device, encoder); 1030 return E_NOTIMPL; 1031 } 1032 #endif 1033 1034 static const IWICImagingFactory2Vtbl ImagingFactory_Vtbl = { 1035 ImagingFactory_QueryInterface, 1036 ImagingFactory_AddRef, 1037 ImagingFactory_Release, 1038 ImagingFactory_CreateDecoderFromFilename, 1039 ImagingFactory_CreateDecoderFromStream, 1040 ImagingFactory_CreateDecoderFromFileHandle, 1041 ImagingFactory_CreateComponentInfo, 1042 ImagingFactory_CreateDecoder, 1043 ImagingFactory_CreateEncoder, 1044 ImagingFactory_CreatePalette, 1045 ImagingFactory_CreateFormatConverter, 1046 ImagingFactory_CreateBitmapScaler, 1047 ImagingFactory_CreateBitmapClipper, 1048 ImagingFactory_CreateBitmapFlipRotator, 1049 ImagingFactory_CreateStream, 1050 ImagingFactory_CreateColorContext, 1051 ImagingFactory_CreateColorTransformer, 1052 ImagingFactory_CreateBitmap, 1053 ImagingFactory_CreateBitmapFromSource, 1054 ImagingFactory_CreateBitmapFromSourceRect, 1055 ImagingFactory_CreateBitmapFromMemory, 1056 ImagingFactory_CreateBitmapFromHBITMAP, 1057 ImagingFactory_CreateBitmapFromHICON, 1058 ImagingFactory_CreateComponentEnumerator, 1059 ImagingFactory_CreateFastMetadataEncoderFromDecoder, 1060 ImagingFactory_CreateFastMetadataEncoderFromFrameDecode, 1061 ImagingFactory_CreateQueryWriter, 1062 ImagingFactory_CreateQueryWriterFromReader, 1063 #ifndef __REACTOS__ 1064 ImagingFactory_CreateImageEncoder, 1065 #endif 1066 }; 1067 1068 static HRESULT WINAPI ComponentFactory_QueryInterface(IWICComponentFactory *iface, REFIID iid, void **ppv) 1069 { 1070 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1071 return IWICImagingFactory2_QueryInterface(&This->IWICImagingFactory2_iface, iid, ppv); 1072 } 1073 1074 static ULONG WINAPI ComponentFactory_AddRef(IWICComponentFactory *iface) 1075 { 1076 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1077 return IWICImagingFactory2_AddRef(&This->IWICImagingFactory2_iface); 1078 } 1079 1080 static ULONG WINAPI ComponentFactory_Release(IWICComponentFactory *iface) 1081 { 1082 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1083 return IWICImagingFactory2_Release(&This->IWICImagingFactory2_iface); 1084 } 1085 1086 static HRESULT WINAPI ComponentFactory_CreateDecoderFromFilename(IWICComponentFactory *iface, LPCWSTR filename, 1087 const GUID *vendor, DWORD desired_access, WICDecodeOptions options, IWICBitmapDecoder **decoder) 1088 { 1089 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1090 return IWICImagingFactory2_CreateDecoderFromFilename(&This->IWICImagingFactory2_iface, filename, vendor, 1091 desired_access, options, decoder); 1092 } 1093 1094 static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(IWICComponentFactory *iface, IStream *stream, 1095 const GUID *vendor, WICDecodeOptions options, IWICBitmapDecoder **decoder) 1096 { 1097 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1098 return IWICImagingFactory2_CreateDecoderFromStream(&This->IWICImagingFactory2_iface, stream, vendor, 1099 options, decoder); 1100 } 1101 1102 static HRESULT WINAPI ComponentFactory_CreateDecoderFromFileHandle(IWICComponentFactory *iface, ULONG_PTR hFile, 1103 const GUID *vendor, WICDecodeOptions options, IWICBitmapDecoder **decoder) 1104 { 1105 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1106 return IWICImagingFactory2_CreateDecoderFromFileHandle(&This->IWICImagingFactory2_iface, hFile, vendor, 1107 options, decoder); 1108 } 1109 1110 static HRESULT WINAPI ComponentFactory_CreateComponentInfo(IWICComponentFactory *iface, REFCLSID component, 1111 IWICComponentInfo **info) 1112 { 1113 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1114 return IWICImagingFactory2_CreateComponentInfo(&This->IWICImagingFactory2_iface, component, info); 1115 } 1116 1117 static HRESULT WINAPI ComponentFactory_CreateDecoder(IWICComponentFactory *iface, REFGUID format, const GUID *vendor, 1118 IWICBitmapDecoder **decoder) 1119 { 1120 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1121 return IWICImagingFactory2_CreateDecoder(&This->IWICImagingFactory2_iface, format, vendor, decoder); 1122 } 1123 1124 static HRESULT WINAPI ComponentFactory_CreateEncoder(IWICComponentFactory *iface, REFGUID format, const GUID *vendor, 1125 IWICBitmapEncoder **encoder) 1126 { 1127 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1128 return IWICImagingFactory2_CreateEncoder(&This->IWICImagingFactory2_iface, format, vendor, encoder); 1129 } 1130 1131 static HRESULT WINAPI ComponentFactory_CreatePalette(IWICComponentFactory *iface, IWICPalette **palette) 1132 { 1133 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1134 return IWICImagingFactory2_CreatePalette(&This->IWICImagingFactory2_iface, palette); 1135 } 1136 1137 static HRESULT WINAPI ComponentFactory_CreateFormatConverter(IWICComponentFactory *iface, IWICFormatConverter **converter) 1138 { 1139 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1140 return IWICImagingFactory2_CreateFormatConverter(&This->IWICImagingFactory2_iface, converter); 1141 } 1142 1143 static HRESULT WINAPI ComponentFactory_CreateBitmapScaler(IWICComponentFactory *iface, IWICBitmapScaler **scaler) 1144 { 1145 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1146 return IWICImagingFactory2_CreateBitmapScaler(&This->IWICImagingFactory2_iface, scaler); 1147 } 1148 1149 static HRESULT WINAPI ComponentFactory_CreateBitmapClipper(IWICComponentFactory *iface, IWICBitmapClipper **clipper) 1150 { 1151 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1152 return IWICImagingFactory2_CreateBitmapClipper(&This->IWICImagingFactory2_iface, clipper); 1153 } 1154 1155 static HRESULT WINAPI ComponentFactory_CreateBitmapFlipRotator(IWICComponentFactory *iface, IWICBitmapFlipRotator **fliprotator) 1156 { 1157 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1158 return IWICImagingFactory2_CreateBitmapFlipRotator(&This->IWICImagingFactory2_iface, fliprotator); 1159 } 1160 1161 static HRESULT WINAPI ComponentFactory_CreateStream(IWICComponentFactory *iface, IWICStream **stream) 1162 { 1163 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1164 return IWICImagingFactory2_CreateStream(&This->IWICImagingFactory2_iface, stream); 1165 } 1166 1167 static HRESULT WINAPI ComponentFactory_CreateColorContext(IWICComponentFactory *iface, IWICColorContext **context) 1168 { 1169 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1170 return IWICImagingFactory2_CreateColorContext(&This->IWICImagingFactory2_iface, context); 1171 } 1172 1173 static HRESULT WINAPI ComponentFactory_CreateColorTransformer(IWICComponentFactory *iface, IWICColorTransform **transformer) 1174 { 1175 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1176 return IWICImagingFactory2_CreateColorTransformer(&This->IWICImagingFactory2_iface, transformer); 1177 } 1178 1179 static HRESULT WINAPI ComponentFactory_CreateBitmap(IWICComponentFactory *iface, UINT width, UINT height, REFWICPixelFormatGUID pixel_format, 1180 WICBitmapCreateCacheOption option, IWICBitmap **bitmap) 1181 { 1182 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1183 return IWICImagingFactory2_CreateBitmap(&This->IWICImagingFactory2_iface, width, height, pixel_format, option, bitmap); 1184 } 1185 1186 static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory *iface, IWICBitmapSource *source, 1187 WICBitmapCreateCacheOption option, IWICBitmap **bitmap) 1188 { 1189 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1190 return IWICImagingFactory2_CreateBitmapFromSource(&This->IWICImagingFactory2_iface, source, option, bitmap); 1191 } 1192 1193 static HRESULT WINAPI ComponentFactory_CreateBitmapFromSourceRect(IWICComponentFactory *iface, IWICBitmapSource *source, 1194 UINT x, UINT y, UINT width, UINT height, IWICBitmap **bitmap) 1195 { 1196 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1197 return IWICImagingFactory2_CreateBitmapFromSourceRect(&This->IWICImagingFactory2_iface, source, x, y, width, height, bitmap); 1198 } 1199 1200 static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory *iface, UINT width, UINT height, 1201 REFWICPixelFormatGUID format, UINT stride, UINT size, BYTE *buffer, IWICBitmap **bitmap) 1202 { 1203 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1204 return IWICImagingFactory2_CreateBitmapFromMemory(&This->IWICImagingFactory2_iface, width, height, format, stride, 1205 size, buffer, bitmap); 1206 } 1207 1208 static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface, HBITMAP hbm, HPALETTE hpal, 1209 WICBitmapAlphaChannelOption option, IWICBitmap **bitmap) 1210 { 1211 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1212 return IWICImagingFactory2_CreateBitmapFromHBITMAP(&This->IWICImagingFactory2_iface, hbm, hpal, option, bitmap); 1213 } 1214 1215 static HRESULT WINAPI ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory *iface, HICON hicon, IWICBitmap **bitmap) 1216 { 1217 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1218 return IWICImagingFactory2_CreateBitmapFromHICON(&This->IWICImagingFactory2_iface, hicon, bitmap); 1219 } 1220 1221 static HRESULT WINAPI ComponentFactory_CreateComponentEnumerator(IWICComponentFactory *iface, DWORD component_types, 1222 DWORD options, IEnumUnknown **enumerator) 1223 { 1224 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1225 return IWICImagingFactory2_CreateComponentEnumerator(&This->IWICImagingFactory2_iface, component_types, 1226 options, enumerator); 1227 } 1228 1229 static HRESULT WINAPI ComponentFactory_CreateFastMetadataEncoderFromDecoder(IWICComponentFactory *iface, IWICBitmapDecoder *decoder, 1230 IWICFastMetadataEncoder **encoder) 1231 { 1232 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1233 return IWICImagingFactory2_CreateFastMetadataEncoderFromDecoder(&This->IWICImagingFactory2_iface, decoder, encoder); 1234 } 1235 1236 static HRESULT WINAPI ComponentFactory_CreateFastMetadataEncoderFromFrameDecode(IWICComponentFactory *iface, 1237 IWICBitmapFrameDecode *frame_decode, IWICFastMetadataEncoder **encoder) 1238 { 1239 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1240 return IWICImagingFactory2_CreateFastMetadataEncoderFromFrameDecode(&This->IWICImagingFactory2_iface, frame_decode, encoder); 1241 } 1242 1243 static HRESULT WINAPI ComponentFactory_CreateQueryWriter(IWICComponentFactory *iface, REFGUID format, const GUID *vendor, 1244 IWICMetadataQueryWriter **writer) 1245 { 1246 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1247 return IWICImagingFactory2_CreateQueryWriter(&This->IWICImagingFactory2_iface, format, vendor, writer); 1248 } 1249 1250 static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromReader(IWICComponentFactory *iface, IWICMetadataQueryReader *reader, 1251 const GUID *vendor, IWICMetadataQueryWriter **writer) 1252 { 1253 ImagingFactory *This = impl_from_IWICComponentFactory(iface); 1254 return IWICImagingFactory2_CreateQueryWriterFromReader(&This->IWICImagingFactory2_iface, reader, vendor, writer); 1255 } 1256 1257 static HRESULT WINAPI ComponentFactory_CreateMetadataReader(IWICComponentFactory *iface, 1258 REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader) 1259 { 1260 FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), 1261 options, stream, reader); 1262 return E_NOTIMPL; 1263 } 1264 1265 static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface, 1266 REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader) 1267 { 1268 HRESULT hr; 1269 IEnumUnknown *enumreaders; 1270 IUnknown *unkreaderinfo; 1271 IWICMetadataReaderInfo *readerinfo; 1272 IWICPersistStream *wicpersiststream; 1273 ULONG num_fetched; 1274 GUID decoder_vendor; 1275 BOOL matches; 1276 LARGE_INTEGER zero; 1277 1278 TRACE("%p,%s,%s,%x,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor), 1279 options, stream, reader); 1280 1281 if (!format || !stream || !reader) 1282 return E_INVALIDARG; 1283 1284 zero.QuadPart = 0; 1285 1286 hr = CreateComponentEnumerator(WICMetadataReader, WICComponentEnumerateDefault, &enumreaders); 1287 if (FAILED(hr)) return hr; 1288 1289 *reader = NULL; 1290 1291 start: 1292 while (!*reader) 1293 { 1294 hr = IEnumUnknown_Next(enumreaders, 1, &unkreaderinfo, &num_fetched); 1295 1296 if (hr == S_OK) 1297 { 1298 hr = IUnknown_QueryInterface(unkreaderinfo, &IID_IWICMetadataReaderInfo, (void**)&readerinfo); 1299 1300 if (SUCCEEDED(hr)) 1301 { 1302 if (vendor) 1303 { 1304 hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &decoder_vendor); 1305 1306 if (FAILED(hr) || !IsEqualIID(vendor, &decoder_vendor)) 1307 { 1308 IWICMetadataReaderInfo_Release(readerinfo); 1309 IUnknown_Release(unkreaderinfo); 1310 continue; 1311 } 1312 } 1313 1314 hr = IWICMetadataReaderInfo_MatchesPattern(readerinfo, format, stream, &matches); 1315 1316 if (SUCCEEDED(hr) && matches) 1317 { 1318 hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL); 1319 1320 if (SUCCEEDED(hr)) 1321 hr = IWICMetadataReaderInfo_CreateInstance(readerinfo, reader); 1322 1323 if (SUCCEEDED(hr)) 1324 { 1325 hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream); 1326 1327 if (SUCCEEDED(hr)) 1328 { 1329 hr = IWICPersistStream_LoadEx(wicpersiststream, 1330 stream, vendor, options & WICPersistOptionMask); 1331 1332 IWICPersistStream_Release(wicpersiststream); 1333 } 1334 1335 if (FAILED(hr)) 1336 { 1337 IWICMetadataReader_Release(*reader); 1338 *reader = NULL; 1339 } 1340 } 1341 } 1342 1343 IUnknown_Release(readerinfo); 1344 } 1345 1346 IUnknown_Release(unkreaderinfo); 1347 } 1348 else 1349 break; 1350 } 1351 1352 if (!*reader && vendor) 1353 { 1354 vendor = NULL; 1355 IEnumUnknown_Reset(enumreaders); 1356 goto start; 1357 } 1358 1359 IEnumUnknown_Release(enumreaders); 1360 1361 if (!*reader && !(options & WICMetadataCreationFailUnknown)) 1362 { 1363 hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL); 1364 1365 if (SUCCEEDED(hr)) 1366 hr = UnknownMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void**)reader); 1367 1368 if (SUCCEEDED(hr)) 1369 { 1370 hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream); 1371 1372 if (SUCCEEDED(hr)) 1373 { 1374 hr = IWICPersistStream_LoadEx(wicpersiststream, stream, NULL, options & WICPersistOptionMask); 1375 1376 IWICPersistStream_Release(wicpersiststream); 1377 } 1378 1379 if (FAILED(hr)) 1380 { 1381 IWICMetadataReader_Release(*reader); 1382 *reader = NULL; 1383 } 1384 } 1385 } 1386 1387 if (*reader) 1388 return S_OK; 1389 else 1390 return WINCODEC_ERR_COMPONENTNOTFOUND; 1391 } 1392 1393 static HRESULT WINAPI ComponentFactory_CreateMetadataWriter(IWICComponentFactory *iface, 1394 REFGUID format, const GUID *vendor, DWORD options, IWICMetadataWriter **writer) 1395 { 1396 FIXME("%p,%s,%s,%x,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, writer); 1397 return E_NOTIMPL; 1398 } 1399 1400 static HRESULT WINAPI ComponentFactory_CreateMetadataWriterFromReader(IWICComponentFactory *iface, 1401 IWICMetadataReader *reader, const GUID *vendor, IWICMetadataWriter **writer) 1402 { 1403 FIXME("%p,%p,%s,%p: stub\n", iface, reader, debugstr_guid(vendor), writer); 1404 return E_NOTIMPL; 1405 } 1406 1407 static HRESULT WINAPI ComponentFactory_CreateQueryReaderFromBlockReader(IWICComponentFactory *iface, 1408 IWICMetadataBlockReader *block_reader, IWICMetadataQueryReader **query_reader) 1409 { 1410 TRACE("%p,%p,%p\n", iface, block_reader, query_reader); 1411 1412 if (!block_reader || !query_reader) 1413 return E_INVALIDARG; 1414 1415 return MetadataQueryReader_CreateInstance(block_reader, NULL, query_reader); 1416 } 1417 1418 static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory *iface, 1419 IWICMetadataBlockWriter *block_writer, IWICMetadataQueryWriter **query_writer) 1420 { 1421 FIXME("%p,%p,%p: stub\n", iface, block_writer, query_writer); 1422 return E_NOTIMPL; 1423 } 1424 1425 static HRESULT WINAPI ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory *iface, 1426 PROPBAG2 *options, UINT count, IPropertyBag2 **property) 1427 { 1428 TRACE("(%p,%p,%u,%p)\n", iface, options, count, property); 1429 return CreatePropertyBag2(options, count, property); 1430 } 1431 1432 static const IWICComponentFactoryVtbl ComponentFactory_Vtbl = { 1433 ComponentFactory_QueryInterface, 1434 ComponentFactory_AddRef, 1435 ComponentFactory_Release, 1436 ComponentFactory_CreateDecoderFromFilename, 1437 ComponentFactory_CreateDecoderFromStream, 1438 ComponentFactory_CreateDecoderFromFileHandle, 1439 ComponentFactory_CreateComponentInfo, 1440 ComponentFactory_CreateDecoder, 1441 ComponentFactory_CreateEncoder, 1442 ComponentFactory_CreatePalette, 1443 ComponentFactory_CreateFormatConverter, 1444 ComponentFactory_CreateBitmapScaler, 1445 ComponentFactory_CreateBitmapClipper, 1446 ComponentFactory_CreateBitmapFlipRotator, 1447 ComponentFactory_CreateStream, 1448 ComponentFactory_CreateColorContext, 1449 ComponentFactory_CreateColorTransformer, 1450 ComponentFactory_CreateBitmap, 1451 ComponentFactory_CreateBitmapFromSource, 1452 ComponentFactory_CreateBitmapFromSourceRect, 1453 ComponentFactory_CreateBitmapFromMemory, 1454 ComponentFactory_CreateBitmapFromHBITMAP, 1455 ComponentFactory_CreateBitmapFromHICON, 1456 ComponentFactory_CreateComponentEnumerator, 1457 ComponentFactory_CreateFastMetadataEncoderFromDecoder, 1458 ComponentFactory_CreateFastMetadataEncoderFromFrameDecode, 1459 ComponentFactory_CreateQueryWriter, 1460 ComponentFactory_CreateQueryWriterFromReader, 1461 ComponentFactory_CreateMetadataReader, 1462 ComponentFactory_CreateMetadataReaderFromContainer, 1463 ComponentFactory_CreateMetadataWriter, 1464 ComponentFactory_CreateMetadataWriterFromReader, 1465 ComponentFactory_CreateQueryReaderFromBlockReader, 1466 ComponentFactory_CreateQueryWriterFromBlockWriter, 1467 ComponentFactory_CreateEncoderPropertyBag 1468 }; 1469 1470 HRESULT ImagingFactory_CreateInstance(REFIID iid, void** ppv) 1471 { 1472 ImagingFactory *This; 1473 HRESULT ret; 1474 1475 TRACE("(%s,%p)\n", debugstr_guid(iid), ppv); 1476 1477 *ppv = NULL; 1478 1479 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); 1480 if (!This) return E_OUTOFMEMORY; 1481 1482 This->IWICImagingFactory2_iface.lpVtbl = &ImagingFactory_Vtbl; 1483 This->IWICComponentFactory_iface.lpVtbl = &ComponentFactory_Vtbl; 1484 This->ref = 1; 1485 1486 ret = IWICImagingFactory2_QueryInterface(&This->IWICImagingFactory2_iface, iid, ppv); 1487 IWICImagingFactory2_Release(&This->IWICImagingFactory2_iface); 1488 1489 return ret; 1490 } 1491 1492 HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT height, 1493 REFWICPixelFormatGUID format, HANDLE section, UINT stride, 1494 UINT offset, WICSectionAccessLevel wicaccess, IWICBitmap **bitmap) 1495 { 1496 SYSTEM_INFO sysinfo; 1497 UINT bpp, access, size, view_offset, view_size; 1498 void *view; 1499 HRESULT hr; 1500 1501 TRACE("%u,%u,%s,%p,%u,%u,%#x,%p\n", width, height, debugstr_guid(format), 1502 section, stride, offset, wicaccess, bitmap); 1503 1504 if (!width || !height || !section || !bitmap) return E_INVALIDARG; 1505 1506 hr = get_pixelformat_bpp(format, &bpp); 1507 if (FAILED(hr)) return hr; 1508 1509 switch (wicaccess) 1510 { 1511 case WICSectionAccessLevelReadWrite: 1512 access = FILE_MAP_READ | FILE_MAP_WRITE; 1513 break; 1514 1515 case WICSectionAccessLevelRead: 1516 access = FILE_MAP_READ; 1517 break; 1518 1519 default: 1520 FIXME("unsupported access %#x\n", wicaccess); 1521 return E_INVALIDARG; 1522 } 1523 1524 if (!stride) stride = (((bpp * width) + 31) / 32) * 4; 1525 size = stride * height; 1526 if (size / height != stride) return E_INVALIDARG; 1527 1528 GetSystemInfo(&sysinfo); 1529 view_offset = offset - (offset % sysinfo.dwAllocationGranularity); 1530 view_size = size + (offset - view_offset); 1531 1532 view = MapViewOfFile(section, access, 0, view_offset, view_size); 1533 if (!view) return HRESULT_FROM_WIN32(GetLastError()); 1534 1535 offset -= view_offset; 1536 hr = BitmapImpl_Create(width, height, stride, 0, view, offset, format, WICBitmapCacheOnLoad, bitmap); 1537 if (FAILED(hr)) UnmapViewOfFile(view); 1538 return hr; 1539 } 1540 1541 HRESULT WINAPI WICCreateBitmapFromSection(UINT width, UINT height, 1542 REFWICPixelFormatGUID format, HANDLE section, 1543 UINT stride, UINT offset, IWICBitmap **bitmap) 1544 { 1545 TRACE("%u,%u,%s,%p,%u,%u,%p\n", width, height, debugstr_guid(format), 1546 section, stride, offset, bitmap); 1547 1548 return WICCreateBitmapFromSectionEx(width, height, format, section, 1549 stride, offset, WICSectionAccessLevelRead, bitmap); 1550 } 1551