widl: Add support for protected attribute.
[wine.git] / dlls / wmphoto / jxrlib.c
blobd4ac02e591850d790ad4d1a9c2b49151ee63f4b8
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 #define NONAMELESSUNION
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winternl.h"
28 #include "winbase.h"
29 #include "objbase.h"
30 #define ERR JXR_ERR
31 #include "JXRGlue.h"
32 #undef ERR
34 #include "wincodecs_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
39 static const struct
41 const WICPixelFormatGUID *format;
42 UINT bpp;
43 } pixel_format_bpp[] =
45 {&GUID_PKPixelFormat128bppRGBAFixedPoint, 128},
46 {&GUID_PKPixelFormat128bppRGBAFloat, 128},
47 {&GUID_PKPixelFormat128bppRGBFloat, 128},
48 {&GUID_PKPixelFormat16bppRGB555, 16},
49 {&GUID_PKPixelFormat16bppRGB565, 16},
50 {&GUID_PKPixelFormat16bppGray, 16},
51 {&GUID_PKPixelFormat16bppGrayFixedPoint, 16},
52 {&GUID_PKPixelFormat16bppGrayHalf, 16},
53 {&GUID_PKPixelFormat24bppBGR, 24},
54 {&GUID_PKPixelFormat24bppRGB, 24},
55 {&GUID_PKPixelFormat32bppBGR, 32},
56 {&GUID_PKPixelFormat32bppRGB101010, 32},
57 {&GUID_PKPixelFormat32bppBGRA, 32},
58 {&GUID_PKPixelFormat32bppCMYK, 32},
59 {&GUID_PKPixelFormat32bppGrayFixedPoint, 32},
60 {&GUID_PKPixelFormat32bppGrayFloat, 32},
61 {&GUID_PKPixelFormat32bppRGBE, 32},
62 {&GUID_PKPixelFormat40bppCMYKAlpha, 40},
63 {&GUID_PKPixelFormat48bppRGB, 48},
64 {&GUID_PKPixelFormat48bppRGBFixedPoint, 48},
65 {&GUID_PKPixelFormat48bppRGBHalf, 48},
66 {&GUID_PKPixelFormat64bppCMYK, 64},
67 {&GUID_PKPixelFormat64bppRGBA, 64},
68 {&GUID_PKPixelFormat64bppRGBAFixedPoint, 64},
69 {&GUID_PKPixelFormat64bppRGBAHalf, 64},
70 {&GUID_PKPixelFormat80bppCMYKAlpha, 80},
71 {&GUID_PKPixelFormat8bppGray, 8},
72 {&GUID_PKPixelFormat96bppRGBFixedPoint, 96},
73 {&GUID_PKPixelFormatBlackWhite, 1},
76 static inline UINT pixel_format_get_bpp(const WICPixelFormatGUID *format)
78 int i;
79 for (i = 0; i < ARRAY_SIZE(pixel_format_bpp); ++i)
80 if (IsEqualGUID(format, pixel_format_bpp[i].format)) return pixel_format_bpp[i].bpp;
81 return 0;
84 struct wmp_decoder
86 struct decoder decoder_iface;
87 struct WMPStream WMPStream_iface;
88 PKImageDecode *decoder;
89 IStream *stream;
90 struct decoder_frame frame;
91 UINT frame_stride;
92 BYTE *frame_data;
95 static inline struct wmp_decoder *impl_from_decoder(struct decoder *iface)
97 return CONTAINING_RECORD(iface, struct wmp_decoder, decoder_iface);
100 static inline struct wmp_decoder *impl_from_WMPStream(struct WMPStream *iface)
102 return CONTAINING_RECORD(iface, struct wmp_decoder, WMPStream_iface);
105 static JXR_ERR wmp_stream_Close(struct WMPStream **piface)
107 TRACE("iface %p\n", piface);
108 return WMP_errSuccess;
111 static Bool wmp_stream_EOS(struct WMPStream *iface)
113 FIXME("iface %p, stub!\n", iface);
114 return FALSE;
117 static JXR_ERR wmp_stream_Read(struct WMPStream *iface, void *buf, size_t len)
119 struct wmp_decoder *This = impl_from_WMPStream(iface);
120 ULONG count;
121 if (FAILED(stream_read(This->stream, buf, len, &count)) || count != len)
123 WARN("Failed to read data!\n");
124 return WMP_errFileIO;
126 return WMP_errSuccess;
129 static JXR_ERR wmp_stream_Write(struct WMPStream *iface, const void *buf, size_t len)
131 struct wmp_decoder *This = impl_from_WMPStream(iface);
132 ULONG count;
133 if (FAILED(stream_write(This->stream, buf, len, &count)) || count != len)
135 WARN("Failed to write data!\n");
136 return WMP_errFileIO;
138 return WMP_errSuccess;
141 static JXR_ERR wmp_stream_SetPos(struct WMPStream *iface, size_t pos)
143 struct wmp_decoder *This = impl_from_WMPStream(iface);
144 if (FAILED(stream_seek(This->stream, pos, STREAM_SEEK_SET, NULL)))
146 WARN("Failed to set stream pos!\n");
147 return WMP_errFileIO;
149 return WMP_errSuccess;
152 static JXR_ERR wmp_stream_GetPos(struct WMPStream *iface, size_t *pos)
154 struct wmp_decoder *This = impl_from_WMPStream(iface);
155 ULONGLONG ofs;
156 if (FAILED(stream_seek(This->stream, 0, STREAM_SEEK_CUR, &ofs)))
158 WARN("Failed to get stream pos!\n");
159 return WMP_errFileIO;
161 *pos = ofs;
162 return WMP_errSuccess;
165 static HRESULT CDECL wmp_decoder_initialize(struct decoder *iface, IStream *stream, struct decoder_stat *st)
167 struct wmp_decoder *This = impl_from_decoder(iface);
168 HRESULT hr;
169 Float dpix, dpiy;
170 I32 width, height;
171 U32 count;
173 TRACE("iface %p, stream %p, st %p\n", iface, stream, st);
175 if (This->stream)
176 return WINCODEC_ERR_WRONGSTATE;
178 This->stream = stream;
179 if (FAILED(hr = stream_seek(This->stream, 0, STREAM_SEEK_SET, NULL)))
180 return hr;
181 if (This->decoder->Initialize(This->decoder, &This->WMPStream_iface))
183 ERR("Failed to initialize jxrlib decoder!\n");
184 return E_FAIL;
187 if (This->decoder->GetFrameCount(This->decoder, &st->frame_count))
189 ERR("Failed to get frame count!\n");
190 return E_FAIL;
193 if (st->frame_count > 1) FIXME("multi frame JPEG-XR not implemented\n");
194 st->frame_count = 1;
195 st->flags = WICBitmapDecoderCapabilityCanDecodeAllImages |
196 WICBitmapDecoderCapabilityCanDecodeSomeImages |
197 WICBitmapDecoderCapabilityCanEnumerateMetadata;
199 if (This->decoder->SelectFrame(This->decoder, 0))
201 ERR("Failed to select frame 0!\n");
202 return E_FAIL;
204 if (This->decoder->GetPixelFormat(This->decoder, &This->frame.pixel_format))
206 ERR("Failed to get frame pixel format!\n");
207 return E_FAIL;
209 if (This->decoder->GetSize(This->decoder, &width, &height))
211 ERR("Failed to get frame size!\n");
212 return E_FAIL;
214 if (This->decoder->GetResolution(This->decoder, &dpix, &dpiy))
216 ERR("Failed to get frame resolution!\n");
217 return E_FAIL;
219 if (This->decoder->GetColorContext(This->decoder, NULL, &count))
221 ERR("Failed to get frame color context size!\n");
222 return E_FAIL;
225 if (!(This->frame.bpp = pixel_format_get_bpp(&This->frame.pixel_format))) return E_FAIL;
226 This->frame.width = width;
227 This->frame.height = height;
228 This->frame.dpix = dpix;
229 This->frame.dpiy = dpiy;
230 This->frame.num_colors = 0;
231 if (count) This->frame.num_color_contexts = 1;
232 else This->frame.num_color_contexts = 0;
234 return S_OK;
237 static HRESULT CDECL wmp_decoder_get_frame_info(struct decoder *iface, UINT frame, struct decoder_frame *info)
239 struct wmp_decoder *This = impl_from_decoder(iface);
241 TRACE("iface %p, frame %d, info %p\n", iface, frame, info);
243 if (frame > 0)
245 FIXME("multi frame JPEG-XR not implemented\n");
246 return E_NOTIMPL;
249 *info = This->frame;
250 return S_OK;
253 static HRESULT CDECL wmp_decoder_copy_pixels(struct decoder *iface, UINT frame, const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
255 struct wmp_decoder *This = impl_from_decoder(iface);
256 PKRect pkrect;
257 U8 *frame_data;
259 TRACE("iface %p, frame %d, rect %p, stride %d, buffersize %d, buffer %p\n", iface, frame, prc, stride, buffersize, buffer);
261 if (frame > 0)
263 FIXME("multi frame JPEG-XR not implemented\n");
264 return E_NOTIMPL;
267 if (!This->frame_data)
269 pkrect.X = 0;
270 pkrect.Y = 0;
271 pkrect.Width = This->frame.width;
272 pkrect.Height = This->frame.height;
273 This->frame_stride = (This->frame.width * This->frame.bpp + 7) / 8;
274 if (!(frame_data = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, This->frame.height * This->frame_stride)))
275 return E_FAIL;
276 if (This->decoder->Copy(This->decoder, &pkrect, frame_data, stride))
278 ERR("Failed to copy frame data!\n");
279 RtlFreeHeap(GetProcessHeap(), 0, frame_data);
280 return E_FAIL;
283 This->frame_data = frame_data;
286 return copy_pixels(This->frame.bpp, This->frame_data,
287 This->frame.width, This->frame.height, This->frame_stride,
288 prc, stride, buffersize, buffer);
291 static HRESULT CDECL wmp_decoder_get_metadata_blocks(struct decoder* iface, UINT frame, UINT *count, struct decoder_block **blocks)
293 TRACE("iface %p, frame %d, count %p, blocks %p\n", iface, frame, count, blocks);
295 *count = 0;
296 *blocks = NULL;
297 return S_OK;
300 static HRESULT CDECL wmp_decoder_get_color_context(struct decoder* iface, UINT frame, UINT num, BYTE **data, DWORD *datasize)
302 struct wmp_decoder *This = impl_from_decoder(iface);
303 U32 count;
304 U8 *bytes;
306 TRACE("iface %p, frame %d, num %u, data %p, datasize %p\n", iface, frame, num, data, datasize);
308 *datasize = 0;
309 *data = NULL;
311 if (This->decoder->GetColorContext(This->decoder, NULL, &count))
313 ERR("Failed to get frame color context size!\n");
314 return E_FAIL;
316 *datasize = count;
318 bytes = RtlAllocateHeap(GetProcessHeap(), 0, count);
319 if (!bytes)
320 return E_OUTOFMEMORY;
322 if (This->decoder->GetColorContext(This->decoder, bytes, &count))
324 ERR("Failed to get frame color context!\n");
325 RtlFreeHeap(GetProcessHeap(), 0, bytes);
326 return E_FAIL;
329 *data = bytes;
330 return S_OK;
333 static void CDECL wmp_decoder_destroy(struct decoder* iface)
335 struct wmp_decoder *This = impl_from_decoder(iface);
337 TRACE("iface %p\n", iface);
339 This->decoder->Release(&This->decoder);
340 RtlFreeHeap(GetProcessHeap(), 0, This->frame_data);
341 RtlFreeHeap(GetProcessHeap(), 0, This);
344 static const struct decoder_funcs wmp_decoder_vtable = {
345 wmp_decoder_initialize,
346 wmp_decoder_get_frame_info,
347 wmp_decoder_copy_pixels,
348 wmp_decoder_get_metadata_blocks,
349 wmp_decoder_get_color_context,
350 wmp_decoder_destroy
353 HRESULT CDECL wmp_decoder_create(struct decoder_info *info, struct decoder **result)
355 struct wmp_decoder *This;
356 PKImageDecode *decoder;
358 if (PKImageDecode_Create_WMP(&decoder)) return E_FAIL;
359 This = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*This));
360 if (!This)
362 decoder->Release(&decoder);
363 return E_OUTOFMEMORY;
366 This->decoder_iface.vtable = &wmp_decoder_vtable;
367 This->WMPStream_iface.Close = &wmp_stream_Close;
368 This->WMPStream_iface.EOS = &wmp_stream_EOS;
369 This->WMPStream_iface.Read = &wmp_stream_Read;
370 This->WMPStream_iface.Write = &wmp_stream_Write;
371 This->WMPStream_iface.SetPos = &wmp_stream_SetPos;
372 This->WMPStream_iface.GetPos = &wmp_stream_GetPos;
374 This->decoder = decoder;
375 This->stream = NULL;
376 memset(&This->frame, 0, sizeof(This->frame));
377 This->frame_stride = 0;
378 This->frame_data = NULL;
380 *result = &This->decoder_iface;
382 info->container_format = GUID_ContainerFormatWmp;
383 info->block_format = GUID_ContainerFormatWmp;
384 info->clsid = CLSID_WICWmpDecoder;
386 return S_OK;