ReactOS 0.4.16-dev-1007-g2e85425
pngformat.c
Go to the documentation of this file.
1/*
2 * Copyright 2009 Vincent Povirk for CodeWeavers
3 * Copyright 2016 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 <stdarg.h>
21
22#define COBJMACROS
23
24#include "windef.h"
25#include "winbase.h"
26#include "objbase.h"
27#include "shlwapi.h"
28
29#include "wincodecs_private.h"
30
31#include "wine/debug.h"
32
34{
35 return data[0] << 8 | data[1];
36}
37
39{
40 return data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
41}
42
43static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor,
44 DWORD persist_options, MetadataItem **items, DWORD *item_count)
45{
46 HRESULT hr;
47 BYTE type[4];
48 BYTE *data;
49 ULONG data_size;
50 ULONG name_len, value_len;
51 BYTE *name_end_ptr;
54
55 hr = read_png_chunk(stream, type, &data, &data_size);
56 if (FAILED(hr)) return hr;
57
58 name_end_ptr = memchr(data, 0, data_size);
59
60 name_len = name_end_ptr - data;
61
62 if (!name_end_ptr || name_len > 79)
63 {
64 free(data);
65 return E_FAIL;
66 }
67
68 value_len = data_size - name_len - 1;
69
70 result = calloc(1, sizeof(MetadataItem));
71 name = CoTaskMemAlloc(name_len + 1);
72 value = CoTaskMemAlloc(value_len + 1);
73 if (!result || !name || !value)
74 {
75 free(data);
76 free(result);
79 return E_OUTOFMEMORY;
80 }
81
82 PropVariantInit(&result[0].schema);
83 PropVariantInit(&result[0].id);
84 PropVariantInit(&result[0].value);
85
86 memcpy(name, data, name_len + 1);
87 memcpy(value, name_end_ptr + 1, value_len);
88 value[value_len] = 0;
89
90 result[0].id.vt = VT_LPSTR;
91 result[0].id.pszVal = name;
92 result[0].value.vt = VT_LPSTR;
93 result[0].value.pszVal = value;
94
95 *items = result;
96 *item_count = 1;
97
98 free(data);
99
100 return S_OK;
101}
102
104 0,
105 &CLSID_WICPngTextMetadataReader,
107};
108
110{
112}
113
114static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor,
115 DWORD persist_options, MetadataItem **items, DWORD *item_count)
116{
117 HRESULT hr;
118 BYTE type[4];
119 BYTE *data;
120 ULONG data_size;
121 ULONG gamma;
122 LPWSTR name;
124
125 hr = read_png_chunk(stream, type, &data, &data_size);
126 if (FAILED(hr)) return hr;
127
128 if (data_size < 4)
129 {
130 free(data);
131 return E_FAIL;
132 }
133
134 gamma = read_ulong_be(data);
135
136 free(data);
137
138 result = calloc(1, sizeof(MetadataItem));
139 SHStrDupW(L"ImageGamma", &name);
140 if (!result || !name)
141 {
142 free(result);
144 return E_OUTOFMEMORY;
145 }
146
147 PropVariantInit(&result[0].schema);
148 PropVariantInit(&result[0].id);
149 PropVariantInit(&result[0].value);
150
151 result[0].id.vt = VT_LPWSTR;
152 result[0].id.pwszVal = name;
153 result[0].value.vt = VT_UI4;
154 result[0].value.ulVal = gamma;
155
156 *items = result;
157 *item_count = 1;
158
159 return S_OK;
160}
161
163 0,
164 &CLSID_WICPngGamaMetadataReader,
166};
167
169{
171}
172
173static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor,
174 DWORD persist_options, MetadataItem **items, DWORD *item_count)
175{
176 HRESULT hr;
177 BYTE type[4];
178 BYTE *data;
179 ULONG data_size;
180 static const WCHAR names[8][12] = {
181 L"WhitePointX",
182 L"WhitePointY",
183 L"RedX",
184 L"RedY",
185 L"GreenX",
186 L"GreenY",
187 L"BlueX",
188 L"BlueY",
189 };
190 LPWSTR dyn_names[8] = {0};
192 int i;
193
194 hr = read_png_chunk(stream, type, &data, &data_size);
195 if (FAILED(hr)) return hr;
196
197 if (data_size < 32)
198 {
199 free(data);
200 return E_FAIL;
201 }
202
203 result = calloc(8, sizeof(MetadataItem));
204 for (i=0; i<8; i++)
205 {
206 SHStrDupW(names[i], &dyn_names[i]);
207 if (!dyn_names[i]) break;
208 }
209 if (!result || i < 8)
210 {
211 free(result);
212 for (i=0; i<8; i++)
213 CoTaskMemFree(dyn_names[i]);
214 free(data);
215 return E_OUTOFMEMORY;
216 }
217
218 for (i=0; i<8; i++)
219 {
220 PropVariantInit(&result[i].schema);
221
222 PropVariantInit(&result[i].id);
223 result[i].id.vt = VT_LPWSTR;
224 result[i].id.pwszVal = dyn_names[i];
225
226 PropVariantInit(&result[i].value);
227 result[i].value.vt = VT_UI4;
228 result[i].value.ulVal = read_ulong_be(&data[i*4]);
229 }
230
231 *items = result;
232 *item_count = 8;
233
234 free(data);
235
236 return S_OK;
237}
238
240 0,
241 &CLSID_WICPngChrmMetadataReader,
243};
244
246{
248}
249
250static HRESULT LoadHistMetadata(IStream *stream, const GUID *preferred_vendor,
251 DWORD persist_options, MetadataItem **items, DWORD *item_count)
252{
253 HRESULT hr;
254 BYTE type[4];
255 BYTE *data;
256 ULONG data_size, element_count, i;
257 LPWSTR name;
259 USHORT *elements;
260
261 hr = read_png_chunk(stream, type, &data, &data_size);
262 if (FAILED(hr)) return hr;
263
264 element_count = data_size / 2;
265 elements = CoTaskMemAlloc(element_count * sizeof(USHORT));
266 if (!elements)
267 {
268 free(data);
269 return E_OUTOFMEMORY;
270 }
271 for (i = 0; i < element_count; i++)
272 elements[i] = read_ushort_be(data + i * 2);
273
274 free(data);
275
276 result = calloc(1, sizeof(MetadataItem));
277 SHStrDupW(L"Frequencies", &name);
278 if (!result || !name) {
279 free(result);
281 CoTaskMemFree(elements);
282 return E_OUTOFMEMORY;
283 }
284
285 PropVariantInit(&result[0].schema);
286 PropVariantInit(&result[0].id);
287 PropVariantInit(&result[0].value);
288
289 result[0].id.vt = VT_LPWSTR;
290 result[0].id.pwszVal = name;
291
292 result[0].value.vt = VT_UI2|VT_VECTOR;
293 result[0].value.caui.cElems = element_count;
294 result[0].value.caui.pElems = elements;
295
296 *items = result;
297 *item_count = 1;
298
299 return S_OK;
300}
301
303 0,
304 &CLSID_WICPngHistMetadataReader,
306};
307
309{
311}
312
313static HRESULT LoadTimeMetadata(IStream *stream, const GUID *preferred_vendor,
314 DWORD persist_options, MetadataItem **items, DWORD *item_count)
315{
316 HRESULT hr;
317 BYTE type[4];
318 BYTE *data;
319 ULONG data_size, i;
321 static const WCHAR *names[6] =
322 {
323 L"Year",
324 L"Month",
325 L"Day",
326 L"Hour",
327 L"Minute",
328 L"Second",
329 };
330 LPWSTR id_values[6] = {0};
331
332
333 hr = read_png_chunk(stream, type, &data, &data_size);
334 if (FAILED(hr)) return hr;
335
336 if (data_size != 7)
337 {
338 free(data);
339 return E_FAIL;
340 }
341
342 result = calloc(6, sizeof(MetadataItem));
343 for (i = 0; i < 6; i++)
344 {
345 SHStrDupW(names[i], &id_values[i]);
346 if (!id_values[i]) break;
347 }
348 if (!result || i < 6)
349 {
350 free(result);
351 for (i = 0; i < 6; i++)
352 CoTaskMemFree(id_values[i]);
353 free(data);
354 return E_OUTOFMEMORY;
355 }
356
357 for (i = 0; i < 6; i++)
358 {
359 PropVariantInit(&result[i].schema);
360 PropVariantInit(&result[i].id);
361 PropVariantInit(&result[i].value);
362
363 result[i].id.vt = VT_LPWSTR;
364 result[i].id.pwszVal = id_values[i];
365 }
366
367 result[0].value.vt = VT_UI2;
368 result[0].value.uiVal = read_ushort_be(data);
369 result[1].value.vt = VT_UI1;
370 result[1].value.bVal = data[2];
371 result[2].value.vt = VT_UI1;
372 result[2].value.bVal = data[3];
373 result[3].value.vt = VT_UI1;
374 result[3].value.bVal = data[4];
375 result[4].value.vt = VT_UI1;
376 result[4].value.bVal = data[5];
377 result[5].value.vt = VT_UI1;
378 result[5].value.bVal = data[6];
379
380 *items = result;
381 *item_count = 6;
382
383 free(data);
384
385 return S_OK;
386}
387
389 0,
390 &CLSID_WICPngTimeMetadataReader,
392};
393
395{
397}
398
400{
401 HRESULT hr;
402 struct decoder *decoder;
404
406
407 if (SUCCEEDED(hr))
409
410 return hr;
411}
412
414{
415 HRESULT hr;
416 struct encoder *encoder;
418
420
421 if (SUCCEEDED(hr))
423
424 return hr;
425}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
HRESULT CommonDecoder_CreateInstance(struct decoder *decoder, const struct decoder_info *decoder_info, REFIID iid, void **ppv)
Definition: decoder.c:780
@ VT_LPSTR
Definition: compat.h:2324
@ VT_UI2
Definition: compat.h:2312
@ VT_LPWSTR
Definition: compat.h:2325
@ VT_UI4
Definition: compat.h:2313
@ VT_VECTOR
Definition: compat.h:2340
@ VT_UI1
Definition: compat.h:2311
HRESULT WINAPI SHStrDupW(LPCWSTR src, LPWSTR *dest)
Definition: string.c:2018
static HRESULT LoadChrmMetadata(IStream *stream, const GUID *preferred_vendor, DWORD persist_options, MetadataItem **items, DWORD *item_count)
Definition: pngformat.c:173
static ULONG read_ulong_be(BYTE *data)
Definition: pngformat.c:38
HRESULT PngDecoder_CreateInstance(REFIID iid, void **ppv)
Definition: pngformat.c:399
HRESULT PngEncoder_CreateInstance(REFIID iid, void **ppv)
Definition: pngformat.c:413
static HRESULT LoadTextMetadata(IStream *stream, const GUID *preferred_vendor, DWORD persist_options, MetadataItem **items, DWORD *item_count)
Definition: pngformat.c:43
static HRESULT LoadTimeMetadata(IStream *stream, const GUID *preferred_vendor, DWORD persist_options, MetadataItem **items, DWORD *item_count)
Definition: pngformat.c:313
HRESULT PngGamaReader_CreateInstance(REFIID iid, void **ppv)
Definition: pngformat.c:168
static const MetadataHandlerVtbl TextReader_Vtbl
Definition: pngformat.c:103
HRESULT PngHistReader_CreateInstance(REFIID iid, void **ppv)
Definition: pngformat.c:308
static USHORT read_ushort_be(BYTE *data)
Definition: pngformat.c:33
static const MetadataHandlerVtbl HistReader_Vtbl
Definition: pngformat.c:302
static const MetadataHandlerVtbl TimeReader_Vtbl
Definition: pngformat.c:388
static const MetadataHandlerVtbl GamaReader_Vtbl
Definition: pngformat.c:162
HRESULT PngTimeReader_CreateInstance(REFIID iid, void **ppv)
Definition: pngformat.c:394
static HRESULT LoadGamaMetadata(IStream *stream, const GUID *preferred_vendor, DWORD persist_options, MetadataItem **items, DWORD *item_count)
Definition: pngformat.c:114
HRESULT PngTextReader_CreateInstance(REFIID iid, void **ppv)
Definition: pngformat.c:109
static HRESULT LoadHistMetadata(IStream *stream, const GUID *preferred_vendor, DWORD persist_options, MetadataItem **items, DWORD *item_count)
Definition: pngformat.c:250
HRESULT PngChrmReader_CreateInstance(REFIID iid, void **ppv)
Definition: pngformat.c:245
static const MetadataHandlerVtbl ChrmReader_Vtbl
Definition: pngformat.c:239
HRESULT CommonEncoder_CreateInstance(struct encoder *encoder, const struct encoder_info *encoder_info, REFIID iid, void **ppv)
Definition: encoder.c:867
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint GLuint * names
Definition: glext.h:11545
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
HRESULT CDECL png_encoder_create(struct encoder_info *info, struct encoder **result)
Definition: libpng.c:817
HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result)
Definition: libpng.c:468
HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, REFIID iid, void **ppv)
const WCHAR * schema
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memchr(s, c, n)
Definition: mkisofs.h:875
#define L(x)
Definition: ntvdm.h:50
static TCHAR * items[]
Definition: page1.c:45
unsigned short USHORT
Definition: pedump.c:61
#define REFIID
Definition: guiddef.h:118
#define calloc
Definition: rosglue.h:14
HRESULT hr
Definition: shlfolder.c:183
Definition: name.c:39
Definition: parse.h:23
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:96
HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size)
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
unsigned char BYTE
Definition: xxhash.c:193