2 * Copyright 2009 Vincent Povirk for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wincodecs_private.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
49 DWORD bc2ClrImportant
;
50 /* same as BITMAPINFOHEADER until this point */
55 DWORD bc2HalftoneSize1
;
56 DWORD bc2HalftoneSize2
;
62 const IWICBitmapFrameDecodeVtbl
*lpVtbl
;
69 HRESULT WINAPI
BmpFrameDecode_QueryInterface(IWICBitmapFrameDecode
*iface
, REFIID iid
,
72 BmpFrameDecode
*This
= (BmpFrameDecode
*)iface
;
73 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
75 if (!ppv
) return E_INVALIDARG
;
77 if (IsEqualIID(&IID_IUnknown
, iid
) ||
78 IsEqualIID(&IID_IWICBitmapSource
, iid
) ||
79 IsEqualIID(&IID_IWICBitmapFrameDecode
, iid
))
89 IUnknown_AddRef((IUnknown
*)*ppv
);
93 static ULONG WINAPI
BmpFrameDecode_AddRef(IWICBitmapFrameDecode
*iface
)
95 BmpFrameDecode
*This
= (BmpFrameDecode
*)iface
;
96 ULONG ref
= InterlockedIncrement(&This
->ref
);
98 TRACE("(%p) refcount=%u\n", iface
, ref
);
103 static ULONG WINAPI
BmpFrameDecode_Release(IWICBitmapFrameDecode
*iface
)
105 BmpFrameDecode
*This
= (BmpFrameDecode
*)iface
;
106 ULONG ref
= InterlockedDecrement(&This
->ref
);
108 TRACE("(%p) refcount=%u\n", iface
, ref
);
112 IStream_Release(This
->stream
);
113 HeapFree(GetProcessHeap(), 0, This
);
119 static HRESULT WINAPI
BmpFrameDecode_GetSize(IWICBitmapFrameDecode
*iface
,
120 UINT
*puiWidth
, UINT
*puiHeight
)
122 FIXME("(%p,%p,%p): stub\n", iface
, puiWidth
, puiHeight
);
126 static HRESULT WINAPI
BmpFrameDecode_GetPixelFormat(IWICBitmapFrameDecode
*iface
,
127 WICPixelFormatGUID
*pPixelFormat
)
129 FIXME("(%p,%p): stub\n", iface
, pPixelFormat
);
133 static HRESULT WINAPI
BmpFrameDecode_GetResolution(IWICBitmapFrameDecode
*iface
,
134 double *pDpiX
, double *pDpiY
)
136 FIXME("(%p,%p,%p): stub\n", iface
, pDpiX
, pDpiY
);
140 static HRESULT WINAPI
BmpFrameDecode_CopyPalette(IWICBitmapFrameDecode
*iface
,
141 IWICPalette
*pIPalette
)
143 FIXME("(%p,%p): stub\n", iface
, pIPalette
);
147 static HRESULT WINAPI
BmpFrameDecode_CopyPixels(IWICBitmapFrameDecode
*iface
,
148 const WICRect
*prc
, UINT cbStride
, UINT cbBufferSize
, BYTE
*pbBuffer
)
150 FIXME("(%p,%p,%u,%u,%p): stub\n", iface
, prc
, cbStride
, cbBufferSize
, pbBuffer
);
154 static HRESULT WINAPI
BmpFrameDecode_GetMetadataQueryReader(IWICBitmapFrameDecode
*iface
,
155 IWICMetadataQueryReader
**ppIMetadataQueryReader
)
157 FIXME("(%p,%p): stub\n", iface
, ppIMetadataQueryReader
);
161 static HRESULT WINAPI
BmpFrameDecode_GetColorContexts(IWICBitmapFrameDecode
*iface
,
162 UINT cCount
, IWICColorContext
**ppIColorContexts
, UINT
*pcActualCount
)
164 FIXME("(%p,%u,%p,%p): stub\n", iface
, cCount
, ppIColorContexts
, pcActualCount
);
168 static HRESULT WINAPI
BmpFrameDecode_GetThumbnail(IWICBitmapFrameDecode
*iface
,
169 IWICBitmapSource
**ppIThumbnail
)
171 FIXME("(%p,%p): stub\n", iface
, ppIThumbnail
);
175 static const IWICBitmapFrameDecodeVtbl BmpFrameDecode_Vtbl
= {
176 BmpFrameDecode_QueryInterface
,
177 BmpFrameDecode_AddRef
,
178 BmpFrameDecode_Release
,
179 BmpFrameDecode_GetSize
,
180 BmpFrameDecode_GetPixelFormat
,
181 BmpFrameDecode_GetResolution
,
182 BmpFrameDecode_CopyPalette
,
183 BmpFrameDecode_CopyPixels
,
184 BmpFrameDecode_GetMetadataQueryReader
,
185 BmpFrameDecode_GetColorContexts
,
186 BmpFrameDecode_GetThumbnail
190 const IWICBitmapDecoderVtbl
*lpVtbl
;
194 BITMAPFILEHEADER bfh
;
196 BmpFrameDecode
*framedecode
;
199 static HRESULT
BmpDecoder_ReadHeaders(BmpDecoder
* This
, IStream
*stream
)
202 ULONG bytestoread
, bytesread
;
204 if (This
->initialized
) return WINCODEC_ERR_WRONGSTATE
;
206 hr
= IStream_Read(stream
, &This
->bfh
, sizeof(BITMAPFILEHEADER
), &bytesread
);
207 if (FAILED(hr
)) return hr
;
208 if (bytesread
!= sizeof(BITMAPFILEHEADER
) ||
209 This
->bfh
.bfType
!= 0x4d42 /* "BM" */) return E_FAIL
;
211 hr
= IStream_Read(stream
, &This
->bih
.bV5Size
, sizeof(DWORD
), &bytesread
);
212 if (FAILED(hr
)) return hr
;
213 if (bytesread
!= sizeof(DWORD
) ||
214 (This
->bih
.bV5Size
!= sizeof(BITMAPCOREHEADER
) &&
215 This
->bih
.bV5Size
!= sizeof(BITMAPCOREHEADER2
) &&
216 This
->bih
.bV5Size
!= sizeof(BITMAPINFOHEADER
) &&
217 This
->bih
.bV5Size
!= sizeof(BITMAPV4HEADER
) &&
218 This
->bih
.bV5Size
!= sizeof(BITMAPV5HEADER
))) return E_FAIL
;
220 bytestoread
= This
->bih
.bV5Size
-sizeof(DWORD
);
221 hr
= IStream_Read(stream
, &This
->bih
.bV5Width
, bytestoread
, &bytesread
);
222 if (FAILED(hr
)) return hr
;
223 if (bytestoread
!= bytesread
) return E_FAIL
;
225 This
->initialized
= TRUE
;
230 HRESULT WINAPI
BmpDecoder_QueryInterface(IWICBitmapDecoder
*iface
, REFIID iid
,
233 BmpDecoder
*This
= (BmpDecoder
*)iface
;
234 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
236 if (!ppv
) return E_INVALIDARG
;
238 if (IsEqualIID(&IID_IUnknown
, iid
) || IsEqualIID(&IID_IWICBitmapDecoder
, iid
))
245 return E_NOINTERFACE
;
248 IUnknown_AddRef((IUnknown
*)*ppv
);
252 static ULONG WINAPI
BmpDecoder_AddRef(IWICBitmapDecoder
*iface
)
254 BmpDecoder
*This
= (BmpDecoder
*)iface
;
255 ULONG ref
= InterlockedIncrement(&This
->ref
);
257 TRACE("(%p) refcount=%u\n", iface
, ref
);
262 static ULONG WINAPI
BmpDecoder_Release(IWICBitmapDecoder
*iface
)
264 BmpDecoder
*This
= (BmpDecoder
*)iface
;
265 ULONG ref
= InterlockedDecrement(&This
->ref
);
267 TRACE("(%p) refcount=%u\n", iface
, ref
);
271 if (This
->stream
) IStream_Release(This
->stream
);
272 if (This
->framedecode
) IUnknown_Release((IUnknown
*)This
->framedecode
);
273 HeapFree(GetProcessHeap(), 0, This
);
279 static HRESULT WINAPI
BmpDecoder_QueryCapability(IWICBitmapDecoder
*iface
, IStream
*pIStream
,
280 DWORD
*pdwCapability
)
282 FIXME("(%p,%p,%p): stub\n", iface
, pIStream
, pdwCapability
);
286 static HRESULT WINAPI
BmpDecoder_Initialize(IWICBitmapDecoder
*iface
, IStream
*pIStream
,
287 WICDecodeOptions cacheOptions
)
290 BmpDecoder
*This
= (BmpDecoder
*)iface
;
292 hr
= BmpDecoder_ReadHeaders(This
, pIStream
);
296 This
->stream
= pIStream
;
297 IStream_AddRef(pIStream
);
303 static HRESULT WINAPI
BmpDecoder_GetContainerFormat(IWICBitmapDecoder
*iface
,
304 GUID
*pguidContainerFormat
)
306 memcpy(pguidContainerFormat
, &GUID_ContainerFormatBmp
, sizeof(GUID
));
310 static HRESULT WINAPI
BmpDecoder_GetDecoderInfo(IWICBitmapDecoder
*iface
,
311 IWICBitmapDecoderInfo
**ppIDecoderInfo
)
313 FIXME("(%p,%p): stub\n", iface
, ppIDecoderInfo
);
317 static HRESULT WINAPI
BmpDecoder_CopyPalette(IWICBitmapDecoder
*iface
,
318 IWICPalette
*pIPalette
)
320 FIXME("(%p,%p): stub\n", iface
, pIPalette
);
324 static HRESULT WINAPI
BmpDecoder_GetMetadataQueryReader(IWICBitmapDecoder
*iface
,
325 IWICMetadataQueryReader
**ppIMetadataQueryReader
)
327 FIXME("(%p,%p): stub\n", iface
, ppIMetadataQueryReader
);
331 static HRESULT WINAPI
BmpDecoder_GetPreview(IWICBitmapDecoder
*iface
,
332 IWICBitmapSource
**ppIBitmapSource
)
334 FIXME("(%p,%p): stub\n", iface
, ppIBitmapSource
);
338 static HRESULT WINAPI
BmpDecoder_GetColorContexts(IWICBitmapDecoder
*iface
,
339 UINT cCount
, IWICColorContext
**ppIColorContexts
, UINT
*pcActualCount
)
341 FIXME("(%p,%u,%p,%p): stub\n", iface
, cCount
, ppIColorContexts
, pcActualCount
);
345 static HRESULT WINAPI
BmpDecoder_GetThumbnail(IWICBitmapDecoder
*iface
,
346 IWICBitmapSource
**ppIThumbnail
)
348 FIXME("(%p,%p): stub\n", iface
, ppIThumbnail
);
352 static HRESULT WINAPI
BmpDecoder_GetFrameCount(IWICBitmapDecoder
*iface
,
359 static HRESULT WINAPI
BmpDecoder_GetFrame(IWICBitmapDecoder
*iface
,
360 UINT index
, IWICBitmapFrameDecode
**ppIBitmapFrame
)
362 BmpDecoder
*This
= (BmpDecoder
*)iface
;
364 if (index
!= 0) return E_INVALIDARG
;
366 if (!This
->stream
) return WINCODEC_ERR_WRONGSTATE
;
368 if (!This
->framedecode
)
370 This
->framedecode
= HeapAlloc(GetProcessHeap(), 0, sizeof(BmpFrameDecode
));
371 if (!This
->framedecode
) return E_OUTOFMEMORY
;
373 This
->framedecode
->lpVtbl
= &BmpFrameDecode_Vtbl
;
374 This
->framedecode
->ref
= 1;
375 This
->framedecode
->stream
= This
->stream
;
376 IStream_AddRef(This
->stream
);
377 This
->framedecode
->bfh
= This
->bfh
;
378 This
->framedecode
->bih
= This
->bih
;
381 *ppIBitmapFrame
= (IWICBitmapFrameDecode
*)This
->framedecode
;
382 IWICBitmapFrameDecode_AddRef((IWICBitmapFrameDecode
*)This
->framedecode
);
387 static const IWICBitmapDecoderVtbl BmpDecoder_Vtbl
= {
388 BmpDecoder_QueryInterface
,
391 BmpDecoder_QueryCapability
,
392 BmpDecoder_Initialize
,
393 BmpDecoder_GetContainerFormat
,
394 BmpDecoder_GetDecoderInfo
,
395 BmpDecoder_CopyPalette
,
396 BmpDecoder_GetMetadataQueryReader
,
397 BmpDecoder_GetPreview
,
398 BmpDecoder_GetColorContexts
,
399 BmpDecoder_GetThumbnail
,
400 BmpDecoder_GetFrameCount
,
404 HRESULT
BmpDecoder_CreateInstance(IUnknown
*pUnkOuter
, REFIID iid
, void** ppv
)
409 TRACE("(%p,%s,%p)\n", pUnkOuter
, debugstr_guid(iid
), ppv
);
413 if (pUnkOuter
) return CLASS_E_NOAGGREGATION
;
415 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(BmpDecoder
));
416 if (!This
) return E_OUTOFMEMORY
;
418 This
->lpVtbl
= &BmpDecoder_Vtbl
;
420 This
->initialized
= FALSE
;
422 This
->framedecode
= NULL
;
424 ret
= IUnknown_QueryInterface((IUnknown
*)This
, iid
, ppv
);
425 IUnknown_Release((IUnknown
*)This
);