d3dx9: Unify calling parse_mesh helper functions.
[wine.git] / dlls / wmphoto / jxrlib.c
blobc5ce59b454e6d28c7ca164aae5be9377a1d8a5f7
1 /*
2 * Interface with jxr library
4 * Copyright 2020 Esme Povirk
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #include "ntstatus.h"
24 #define WIN32_NO_STATUS
25 #include "windef.h"
26 #include "winternl.h"
27 #include "winbase.h"
28 #include "objbase.h"
29 #define ERR JXR_ERR
30 #include "JXRGlue.h"
31 #undef ERR
33 #include "wincodecs_private.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
38 static const struct
40 const WICPixelFormatGUID *format;
41 UINT bpp;
42 } pixel_format_bpp[] =
44 {&GUID_PKPixelFormat128bppRGBAFixedPoint, 128},
45 {&GUID_PKPixelFormat128bppRGBAFloat, 128},
46 {&GUID_PKPixelFormat128bppRGBFloat, 128},
47 {&GUID_PKPixelFormat16bppRGB555, 16},
48 {&GUID_PKPixelFormat16bppRGB565, 16},
49 {&GUID_PKPixelFormat16bppGray, 16},
50 {&GUID_PKPixelFormat16bppGrayFixedPoint, 16},
51 {&GUID_PKPixelFormat16bppGrayHalf, 16},
52 {&GUID_PKPixelFormat24bppBGR, 24},
53 {&GUID_PKPixelFormat24bppRGB, 24},
54 {&GUID_PKPixelFormat32bppBGR, 32},
55 {&GUID_PKPixelFormat32bppRGB101010, 32},
56 {&GUID_PKPixelFormat32bppBGRA, 32},
57 {&GUID_PKPixelFormat32bppCMYK, 32},
58 {&GUID_PKPixelFormat32bppGrayFixedPoint, 32},
59 {&GUID_PKPixelFormat32bppGrayFloat, 32},
60 {&GUID_PKPixelFormat32bppRGBE, 32},
61 {&GUID_PKPixelFormat40bppCMYKAlpha, 40},
62 {&GUID_PKPixelFormat48bppRGB, 48},
63 {&GUID_PKPixelFormat48bppRGBFixedPoint, 48},
64 {&GUID_PKPixelFormat48bppRGBHalf, 48},
65 {&GUID_PKPixelFormat64bppCMYK, 64},
66 {&GUID_PKPixelFormat64bppRGBA, 64},
67 {&GUID_PKPixelFormat64bppRGBAFixedPoint, 64},
68 {&GUID_PKPixelFormat64bppRGBAHalf, 64},
69 {&GUID_PKPixelFormat80bppCMYKAlpha, 80},
70 {&GUID_PKPixelFormat8bppGray, 8},
71 {&GUID_PKPixelFormat96bppRGBFixedPoint, 96},
72 {&GUID_PKPixelFormatBlackWhite, 1},
75 static inline UINT pixel_format_get_bpp(const WICPixelFormatGUID *format)
77 int i;
78 for (i = 0; i < ARRAY_SIZE(pixel_format_bpp); ++i)
79 if (IsEqualGUID(format, pixel_format_bpp[i].format)) return pixel_format_bpp[i].bpp;
80 return 0;
83 struct wmp_decoder
85 struct decoder decoder_iface;
86 struct WMPStream WMPStream_iface;
87 PKImageDecode *decoder;
88 IStream *stream;
89 struct decoder_frame frame;
90 UINT frame_stride;
91 BYTE *frame_data;
94 static inline struct wmp_decoder *impl_from_decoder(struct decoder *iface)
96 return CONTAINING_RECORD(iface, struct wmp_decoder, decoder_iface);
99 static inline struct wmp_decoder *impl_from_WMPStream(struct WMPStream *iface)
101 return CONTAINING_RECORD(iface, struct wmp_decoder, WMPStream_iface);
104 static JXR_ERR wmp_stream_Close(struct WMPStream **piface)
106 TRACE("iface %p\n", piface);
107 return WMP_errSuccess;
110 static Bool wmp_stream_EOS(struct WMPStream *iface)
112 FIXME("iface %p, stub!\n", iface);
113 return FALSE;
116 static JXR_ERR wmp_stream_Read(struct WMPStream *iface, void *buf, size_t len)
118 struct wmp_decoder *This = impl_from_WMPStream(iface);
119 ULONG count;
120 if (FAILED(stream_read(This->stream, buf, len, &count)) || count != len)
122 WARN("Failed to read data!\n");
123 return WMP_errFileIO;
125 return WMP_errSuccess;
128 static JXR_ERR wmp_stream_Write(struct WMPStream *iface, const void *buf, size_t len)
130 struct wmp_decoder *This = impl_from_WMPStream(iface);
131 ULONG count;
132 if (FAILED(stream_write(This->stream, buf, len, &count)) || count != len)
134 WARN("Failed to write data!\n");
135 return WMP_errFileIO;
137 return WMP_errSuccess;
140 static JXR_ERR wmp_stream_SetPos(struct WMPStream *iface, size_t pos)
142 struct wmp_decoder *This = impl_from_WMPStream(iface);
143 if (FAILED(stream_seek(This->stream, pos, STREAM_SEEK_SET, NULL)))
145 WARN("Failed to set stream pos!\n");
146 return WMP_errFileIO;
148 return WMP_errSuccess;
151 static JXR_ERR wmp_stream_GetPos(struct WMPStream *iface, size_t *pos)
153 struct wmp_decoder *This = impl_from_WMPStream(iface);
154 ULONGLONG ofs;
155 if (FAILED(stream_seek(This->stream, 0, STREAM_SEEK_CUR, &ofs)))
157 WARN("Failed to get stream pos!\n");
158 return WMP_errFileIO;
160 *pos = ofs;
161 return WMP_errSuccess;
164 static HRESULT CDECL wmp_decoder_initialize(struct decoder *iface, IStream *stream, struct decoder_stat *st)
166 struct wmp_decoder *This = impl_from_decoder(iface);
167 HRESULT hr;
168 Float dpix, dpiy;
169 I32 width, height;
170 U32 count;
172 TRACE("iface %p, stream %p, st %p\n", iface, stream, st);
174 if (This->stream)
175 return WINCODEC_ERR_WRONGSTATE;
177 This->stream = stream;
178 if (FAILED(hr = stream_seek(This->stream, 0, STREAM_SEEK_SET, NULL)))
179 return hr;
180 if (This->decoder->Initialize(This->decoder, &This->WMPStream_iface))
182 ERR("Failed to initialize jxrlib decoder!\n");
183 return E_FAIL;
186 if (This->decoder->GetFrameCount(This->decoder, &st->frame_count))
188 ERR("Failed to get frame count!\n");
189 return E_FAIL;
192 if (st->frame_count > 1) FIXME("multi frame JPEG-XR not implemented\n");
193 st->frame_count = 1;
194 st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages |
195 WICBitmapDecoderCapabilityCanDecodeSomeImages |
196 WICBitmapDecoderCapabilityCanEnumerateMetadata;
198 if (This->decoder->SelectFrame(This->decoder, 0))
200 ERR("Failed to select frame 0!\n");
201 return E_FAIL;
203 if (This->decoder->GetPixelFormat(This->decoder, &This->frame.pixel_format))
205 ERR("Failed to get frame pixel format!\n");
206 return E_FAIL;
208 if (This->decoder->GetSize(This->decoder, &width, &height))
210 ERR("Failed to get frame size!\n");
211 return E_FAIL;
213 if (This->decoder->GetResolution(This->decoder, &dpix, &dpiy))
215 ERR("Failed to get frame resolution!\n");
216 return E_FAIL;
218 if (This->decoder->GetColorContext(This->decoder, NULL, &count))
220 ERR("Failed to get frame color context size!\n");
221 return E_FAIL;
224 if (!(This->frame.bpp = pixel_format_get_bpp(&This->frame.pixel_format))) return E_FAIL;
225 This->frame.width = width;
226 This->frame.height = height;
227 This->frame.dpix = dpix;
228 This->frame.dpiy = dpiy;
229 This->frame.num_colors = 0;
230 if (count) This->frame.num_color_contexts = 1;
231 else This->frame.num_color_contexts = 0;
233 return S_OK;
236 static HRESULT CDECL wmp_decoder_get_frame_info(struct decoder *iface, UINT frame, struct decoder_frame *info)
238 struct wmp_decoder *This = impl_from_decoder(iface);
240 TRACE("iface %p, frame %d, info %p\n", iface, frame, info);
242 if (frame > 0)
244 FIXME("multi frame JPEG-XR not implemented\n");
245 return E_NOTIMPL;
248 *info = This->frame;
249 return S_OK;
252 static HRESULT CDECL wmp_decoder_copy_pixels(struct decoder *iface, UINT frame, const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
254 struct wmp_decoder *This = impl_from_decoder(iface);
255 PKRect pkrect;
256 U8 *frame_data;
258 TRACE("iface %p, frame %d, rect %p, stride %d, buffersize %d, buffer %p\n", iface, frame, prc, stride, buffersize, buffer);
260 if (frame > 0)
262 FIXME("multi frame JPEG-XR not implemented\n");
263 return E_NOTIMPL;
266 if (!This->frame_data)
268 pkrect.X = 0;
269 pkrect.Y = 0;
270 pkrect.Width = This->frame.width;
271 pkrect.Height = This->frame.height;
272 This->frame_stride = (This->frame.width * This->frame.bpp + 7) / 8;
273 if (!(frame_data = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, This->frame.height * This->frame_stride)))
274 return E_FAIL;
275 if (This->decoder->Copy(This->decoder, &pkrect, frame_data, stride))
277 ERR("Failed to copy frame data!\n");
278 RtlFreeHeap(GetProcessHeap(), 0, frame_data);
279 return E_FAIL;
282 This->frame_data = frame_data;
285 return copy_pixels(This->frame.bpp, This->frame_data,
286 This->frame.width, This->frame.height, This->frame_stride,
287 prc, stride, buffersize, buffer);
290 static HRESULT CDECL wmp_decoder_get_metadata_blocks(struct decoder* iface, UINT frame, UINT *count, struct decoder_block **blocks)
292 TRACE("iface %p, frame %d, count %p, blocks %p\n", iface, frame, count, blocks);
294 *count = 0;
295 *blocks = NULL;
296 return S_OK;
299 static HRESULT CDECL wmp_decoder_get_color_context(struct decoder* iface, UINT frame, UINT num, BYTE **data, DWORD *datasize)
301 struct wmp_decoder *This = impl_from_decoder(iface);
302 U32 count;
303 U8 *bytes;
305 TRACE("iface %p, frame %d, num %u, data %p, datasize %p\n", iface, frame, num, data, datasize);
307 *datasize = 0;
308 *data = NULL;
310 if (This->decoder->GetColorContext(This->decoder, NULL, &count))
312 ERR("Failed to get frame color context size!\n");
313 return E_FAIL;
315 *datasize = count;
317 bytes = RtlAllocateHeap(GetProcessHeap(), 0, count);
318 if (!bytes)
319 return E_OUTOFMEMORY;
321 if (This->decoder->GetColorContext(This->decoder, bytes, &count))
323 ERR("Failed to get frame color context!\n");
324 RtlFreeHeap(GetProcessHeap(), 0, bytes);
325 return E_FAIL;
328 *data = bytes;
329 return S_OK;
332 static void CDECL wmp_decoder_destroy(struct decoder* iface)
334 struct wmp_decoder *This = impl_from_decoder(iface);
336 TRACE("iface %p\n", iface);
338 This->decoder->Release(&This->decoder);
339 RtlFreeHeap(GetProcessHeap(), 0, This->frame_data);
340 RtlFreeHeap(GetProcessHeap(), 0, This);
343 static const struct decoder_funcs wmp_decoder_vtable = {
344 wmp_decoder_initialize,
345 wmp_decoder_get_frame_info,
346 wmp_decoder_copy_pixels,
347 wmp_decoder_get_metadata_blocks,
348 wmp_decoder_get_color_context,
349 wmp_decoder_destroy
352 HRESULT CDECL wmp_decoder_create(struct decoder_info *info, struct decoder **result)
354 struct wmp_decoder *This;
355 PKImageDecode *decoder;
357 if (PKImageDecode_Create_WMP(&decoder)) return E_FAIL;
358 This = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*This));
359 if (!This)
361 decoder->Release(&decoder);
362 return E_OUTOFMEMORY;
365 This->decoder_iface.vtable = &wmp_decoder_vtable;
366 This->WMPStream_iface.Close = &wmp_stream_Close;
367 This->WMPStream_iface.EOS = &wmp_stream_EOS;
368 This->WMPStream_iface.Read = &wmp_stream_Read;
369 This->WMPStream_iface.Write = &wmp_stream_Write;
370 This->WMPStream_iface.SetPos = &wmp_stream_SetPos;
371 This->WMPStream_iface.GetPos = &wmp_stream_GetPos;
373 This->decoder = decoder;
374 This->stream = NULL;
375 memset(&This->frame, 0, sizeof(This->frame));
376 This->frame_stride = 0;
377 This->frame_data = NULL;
379 *result = &This->decoder_iface;
381 info->container_format = GUID_ContainerFormatWmp;
382 info->block_format = GUID_ContainerFormatWmp;
383 info->clsid = CLSID_WICWmpDecoder;
385 return S_OK;