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
impl_from_IWICComponentFactory(IWICComponentFactory * iface)45 static inline ImagingFactory *impl_from_IWICComponentFactory(IWICComponentFactory *iface)
46 {
47 return CONTAINING_RECORD(iface, ImagingFactory, IWICComponentFactory_iface);
48 }
49
impl_from_IWICImagingFactory2(IWICImagingFactory2 * iface)50 static inline ImagingFactory *impl_from_IWICImagingFactory2(IWICImagingFactory2 *iface)
51 {
52 return CONTAINING_RECORD(iface, ImagingFactory, IWICImagingFactory2_iface);
53 }
54
ImagingFactory_QueryInterface(IWICImagingFactory2 * iface,REFIID iid,void ** ppv)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
ImagingFactory_AddRef(IWICImagingFactory2 * iface)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
ImagingFactory_Release(IWICImagingFactory2 * iface)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
ImagingFactory_CreateDecoderFromFilename(IWICImagingFactory2 * iface,LPCWSTR wzFilename,const GUID * pguidVendor,DWORD dwDesiredAccess,WICDecodeOptions metadataOptions,IWICBitmapDecoder ** ppIDecoder)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
find_decoder(IStream * pIStream,const GUID * pguidVendor,WICDecodeOptions metadataOptions,IWICBitmapDecoder ** decoder)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
ImagingFactory_CreateDecoderFromStream(IWICImagingFactory2 * iface,IStream * pIStream,const GUID * pguidVendor,WICDecodeOptions metadataOptions,IWICBitmapDecoder ** ppIDecoder)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
ImagingFactory_CreateDecoderFromFileHandle(IWICImagingFactory2 * iface,ULONG_PTR hFile,const GUID * pguidVendor,WICDecodeOptions metadataOptions,IWICBitmapDecoder ** ppIDecoder)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
ImagingFactory_CreateComponentInfo(IWICImagingFactory2 * iface,REFCLSID clsidComponent,IWICComponentInfo ** ppIInfo)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
ImagingFactory_CreateDecoder(IWICImagingFactory2 * iface,REFGUID guidContainerFormat,const GUID * pguidVendor,IWICBitmapDecoder ** ppIDecoder)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
ImagingFactory_CreateEncoder(IWICImagingFactory2 * iface,REFGUID guidContainerFormat,const GUID * pguidVendor,IWICBitmapEncoder ** ppIEncoder)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
ImagingFactory_CreatePalette(IWICImagingFactory2 * iface,IWICPalette ** ppIPalette)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
ImagingFactory_CreateFormatConverter(IWICImagingFactory2 * iface,IWICFormatConverter ** ppIFormatConverter)437 static HRESULT WINAPI ImagingFactory_CreateFormatConverter(IWICImagingFactory2 *iface,
438 IWICFormatConverter **ppIFormatConverter)
439 {
440 return FormatConverter_CreateInstance(&IID_IWICFormatConverter, (void**)ppIFormatConverter);
441 }
442
ImagingFactory_CreateBitmapScaler(IWICImagingFactory2 * iface,IWICBitmapScaler ** ppIBitmapScaler)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
ImagingFactory_CreateBitmapClipper(IWICImagingFactory2 * iface,IWICBitmapClipper ** ppIBitmapClipper)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
ImagingFactory_CreateBitmapFlipRotator(IWICImagingFactory2 * iface,IWICBitmapFlipRotator ** ppIBitmapFlipRotator)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
ImagingFactory_CreateStream(IWICImagingFactory2 * iface,IWICStream ** ppIWICStream)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
ImagingFactory_CreateColorContext(IWICImagingFactory2 * iface,IWICColorContext ** ppIColorContext)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
ImagingFactory_CreateColorTransformer(IWICImagingFactory2 * iface,IWICColorTransform ** ppIColorTransform)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
ImagingFactory_CreateBitmap(IWICImagingFactory2 * iface,UINT uiWidth,UINT uiHeight,REFWICPixelFormatGUID pixelFormat,WICBitmapCreateCacheOption option,IWICBitmap ** ppIBitmap)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
create_bitmap_from_source_rect(IWICBitmapSource * piBitmapSource,const WICRect * rect,WICBitmapCreateCacheOption option,IWICBitmap ** ppIBitmap)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
ImagingFactory_CreateBitmapFromSource(IWICImagingFactory2 * iface,IWICBitmapSource * piBitmapSource,WICBitmapCreateCacheOption option,IWICBitmap ** ppIBitmap)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
ImagingFactory_CreateBitmapFromSourceRect(IWICImagingFactory2 * iface,IWICBitmapSource * piBitmapSource,UINT x,UINT y,UINT width,UINT height,IWICBitmap ** ppIBitmap)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
ImagingFactory_CreateBitmapFromMemory(IWICImagingFactory2 * iface,UINT width,UINT height,REFWICPixelFormatGUID format,UINT stride,UINT size,BYTE * buffer,IWICBitmap ** bitmap)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
get_16bpp_format(HBITMAP hbm,WICPixelFormatGUID * format)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
ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory2 * iface,HBITMAP hbm,HPALETTE hpal,WICBitmapAlphaChannelOption option,IWICBitmap ** bitmap)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
ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 * iface,HICON hicon,IWICBitmap ** bitmap)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
ImagingFactory_CreateComponentEnumerator(IWICImagingFactory2 * iface,DWORD componentTypes,DWORD options,IEnumUnknown ** ppIEnumUnknown)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
ImagingFactory_CreateFastMetadataEncoderFromDecoder(IWICImagingFactory2 * iface,IWICBitmapDecoder * pIDecoder,IWICFastMetadataEncoder ** ppIFastEncoder)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
ImagingFactory_CreateFastMetadataEncoderFromFrameDecode(IWICImagingFactory2 * iface,IWICBitmapFrameDecode * pIFrameDecoder,IWICFastMetadataEncoder ** ppIFastEncoder)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
ImagingFactory_CreateQueryWriter(IWICImagingFactory2 * iface,REFGUID guidMetadataFormat,const GUID * pguidVendor,IWICMetadataQueryWriter ** ppIQueryWriter)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
ImagingFactory_CreateQueryWriterFromReader(IWICImagingFactory2 * iface,IWICMetadataQueryReader * pIQueryReader,const GUID * pguidVendor,IWICMetadataQueryWriter ** ppIQueryWriter)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__
ImagingFactory_CreateImageEncoder(IWICImagingFactory2 * iface,ID2D1Device * device,IWICImageEncoder ** encoder)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
ComponentFactory_QueryInterface(IWICComponentFactory * iface,REFIID iid,void ** ppv)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
ComponentFactory_AddRef(IWICComponentFactory * iface)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
ComponentFactory_Release(IWICComponentFactory * iface)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
ComponentFactory_CreateDecoderFromFilename(IWICComponentFactory * iface,LPCWSTR filename,const GUID * vendor,DWORD desired_access,WICDecodeOptions options,IWICBitmapDecoder ** decoder)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
ComponentFactory_CreateDecoderFromStream(IWICComponentFactory * iface,IStream * stream,const GUID * vendor,WICDecodeOptions options,IWICBitmapDecoder ** decoder)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
ComponentFactory_CreateDecoderFromFileHandle(IWICComponentFactory * iface,ULONG_PTR hFile,const GUID * vendor,WICDecodeOptions options,IWICBitmapDecoder ** decoder)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
ComponentFactory_CreateComponentInfo(IWICComponentFactory * iface,REFCLSID component,IWICComponentInfo ** info)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
ComponentFactory_CreateDecoder(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,IWICBitmapDecoder ** decoder)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
ComponentFactory_CreateEncoder(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,IWICBitmapEncoder ** encoder)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
ComponentFactory_CreatePalette(IWICComponentFactory * iface,IWICPalette ** palette)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
ComponentFactory_CreateFormatConverter(IWICComponentFactory * iface,IWICFormatConverter ** converter)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
ComponentFactory_CreateBitmapScaler(IWICComponentFactory * iface,IWICBitmapScaler ** scaler)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
ComponentFactory_CreateBitmapClipper(IWICComponentFactory * iface,IWICBitmapClipper ** clipper)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
ComponentFactory_CreateBitmapFlipRotator(IWICComponentFactory * iface,IWICBitmapFlipRotator ** fliprotator)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
ComponentFactory_CreateStream(IWICComponentFactory * iface,IWICStream ** stream)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
ComponentFactory_CreateColorContext(IWICComponentFactory * iface,IWICColorContext ** context)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
ComponentFactory_CreateColorTransformer(IWICComponentFactory * iface,IWICColorTransform ** transformer)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
ComponentFactory_CreateBitmap(IWICComponentFactory * iface,UINT width,UINT height,REFWICPixelFormatGUID pixel_format,WICBitmapCreateCacheOption option,IWICBitmap ** bitmap)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
ComponentFactory_CreateBitmapFromSource(IWICComponentFactory * iface,IWICBitmapSource * source,WICBitmapCreateCacheOption option,IWICBitmap ** bitmap)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
ComponentFactory_CreateBitmapFromSourceRect(IWICComponentFactory * iface,IWICBitmapSource * source,UINT x,UINT y,UINT width,UINT height,IWICBitmap ** bitmap)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
ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory * iface,UINT width,UINT height,REFWICPixelFormatGUID format,UINT stride,UINT size,BYTE * buffer,IWICBitmap ** bitmap)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
ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory * iface,HBITMAP hbm,HPALETTE hpal,WICBitmapAlphaChannelOption option,IWICBitmap ** bitmap)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
ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory * iface,HICON hicon,IWICBitmap ** bitmap)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
ComponentFactory_CreateComponentEnumerator(IWICComponentFactory * iface,DWORD component_types,DWORD options,IEnumUnknown ** enumerator)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
ComponentFactory_CreateFastMetadataEncoderFromDecoder(IWICComponentFactory * iface,IWICBitmapDecoder * decoder,IWICFastMetadataEncoder ** encoder)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
ComponentFactory_CreateFastMetadataEncoderFromFrameDecode(IWICComponentFactory * iface,IWICBitmapFrameDecode * frame_decode,IWICFastMetadataEncoder ** encoder)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
ComponentFactory_CreateQueryWriter(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,IWICMetadataQueryWriter ** writer)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
ComponentFactory_CreateQueryWriterFromReader(IWICComponentFactory * iface,IWICMetadataQueryReader * reader,const GUID * vendor,IWICMetadataQueryWriter ** writer)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
ComponentFactory_CreateMetadataReader(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,DWORD options,IStream * stream,IWICMetadataReader ** reader)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
ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,DWORD options,IStream * stream,IWICMetadataReader ** reader)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
ComponentFactory_CreateMetadataWriter(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,DWORD options,IWICMetadataWriter ** writer)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
ComponentFactory_CreateMetadataWriterFromReader(IWICComponentFactory * iface,IWICMetadataReader * reader,const GUID * vendor,IWICMetadataWriter ** writer)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
ComponentFactory_CreateQueryReaderFromBlockReader(IWICComponentFactory * iface,IWICMetadataBlockReader * block_reader,IWICMetadataQueryReader ** query_reader)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
ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory * iface,IWICMetadataBlockWriter * block_writer,IWICMetadataQueryWriter ** query_writer)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
ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory * iface,PROPBAG2 * options,UINT count,IPropertyBag2 ** property)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
ImagingFactory_CreateInstance(REFIID iid,void ** ppv)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
WICCreateBitmapFromSectionEx(UINT width,UINT height,REFWICPixelFormatGUID format,HANDLE section,UINT stride,UINT offset,WICSectionAccessLevel wicaccess,IWICBitmap ** bitmap)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
WICCreateBitmapFromSection(UINT width,UINT height,REFWICPixelFormatGUID format,HANDLE section,UINT stride,UINT offset,IWICBitmap ** bitmap)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