ReactOS 0.4.16-dev-981-g80eb313
libpng.c File Reference
#include <stdarg.h>
#include <png.h>
#include "ntstatus.h"
#include "windef.h"
#include "winternl.h"
#include "winbase.h"
#include "objbase.h"
#include "wincodecs_private.h"
#include "wine/debug.h"
Include dependency graph for libpng.c:

Go to the source code of this file.

Classes

struct  png_decoder
 
struct  png_pixelformat
 
struct  png_encoder
 

Macros

#define WIN32_NO_STATUS
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (wincodecs)
 
static struct png_decoderimpl_from_decoder (struct decoder *iface)
 
static void user_read_data (png_structp png_ptr, png_bytep data, png_size_t length)
 
static HRESULT CDECL png_decoder_initialize (struct decoder *iface, IStream *stream, struct decoder_stat *st)
 
static HRESULT CDECL png_decoder_get_frame_info (struct decoder *iface, UINT frame, struct decoder_frame *info)
 
static HRESULT CDECL png_decoder_copy_pixels (struct decoder *iface, UINT frame, const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
 
static HRESULT CDECL png_decoder_get_metadata_blocks (struct decoder *iface, UINT frame, UINT *count, struct decoder_block **blocks)
 
static HRESULT CDECL png_decoder_get_color_context (struct decoder *iface, UINT frame, UINT num, BYTE **data, DWORD *datasize)
 
static void CDECL png_decoder_destroy (struct decoder *iface)
 
HRESULT CDECL png_decoder_create (struct decoder_info *info, struct decoder **result)
 
static struct png_encoderimpl_from_encoder (struct encoder *iface)
 
static void user_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
 
static void user_flush (png_structp png_ptr)
 
static HRESULT CDECL png_encoder_initialize (struct encoder *encoder, IStream *stream)
 
static HRESULT CDECL png_encoder_get_supported_format (struct encoder *iface, GUID *pixel_format, DWORD *bpp, BOOL *indexed)
 
static HRESULT CDECL png_encoder_create_frame (struct encoder *encoder, const struct encoder_frame *encoder_frame)
 
static HRESULT CDECL png_encoder_write_lines (struct encoder *encoder, BYTE *data, DWORD line_count, DWORD stride)
 
static HRESULT CDECL png_encoder_commit_frame (struct encoder *encoder)
 
static HRESULT CDECL png_encoder_commit_file (struct encoder *encoder)
 
static void CDECL png_encoder_destroy (struct encoder *encoder)
 
HRESULT CDECL png_encoder_create (struct encoder_info *info, struct encoder **result)
 

Variables

static const struct decoder_funcs png_decoder_vtable
 
static const struct png_pixelformat formats []
 
static const struct encoder_funcs png_encoder_vtable
 

Macro Definition Documentation

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 24 of file libpng.c.

Function Documentation

◆ impl_from_decoder()

static struct png_decoder * impl_from_decoder ( struct decoder iface)
inlinestatic

◆ impl_from_encoder()

static struct png_encoder * impl_from_encoder ( struct encoder iface)
inlinestatic

◆ png_decoder_copy_pixels()

static HRESULT CDECL png_decoder_copy_pixels ( struct decoder iface,
UINT  frame,
const WICRect prc,
UINT  stride,
UINT  buffersize,
BYTE buffer 
)
static

Definition at line 352 of file libpng.c.

354{
355 struct png_decoder *This = impl_from_decoder(iface);
356
357 return copy_pixels(This->decoder_frame.bpp, This->image_bits,
358 This->decoder_frame.width, This->decoder_frame.height, This->stride,
359 prc, stride, buffersize, buffer);
360}
void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch, BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *size, const struct pixel_format_desc *format) DECLSPEC_HIDDEN
Definition: surface.c:1700
GLsizei stride
Definition: glext.h:5848
GLuint buffer
Definition: glext.h:5915
static struct png_decoder * impl_from_decoder(struct decoder *iface)
Definition: libpng.c:47
_Out_ LPRECT prc
Definition: ntgdi.h:1658

◆ png_decoder_create()

HRESULT CDECL png_decoder_create ( struct decoder_info info,
struct decoder **  result 
)

Definition at line 468 of file libpng.c.

469{
470 struct png_decoder *This;
471
472 This = malloc(sizeof(*This));
473
474 if (!This)
475 {
476 return E_OUTOFMEMORY;
477 }
478
479 This->decoder.vtable = &png_decoder_vtable;
480 This->image_bits = NULL;
481 This->color_profile = NULL;
482 *result = &This->decoder;
483
484 info->container_format = GUID_ContainerFormatPng;
485 info->block_format = GUID_ContainerFormatPng;
486 info->clsid = CLSID_WICPngDecoder;
487
488 return S_OK;
489}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
GLuint64EXT * result
Definition: glext.h:11304
#define S_OK
Definition: intsafe.h:52
static const struct decoder_funcs png_decoder_vtable
Definition: libpng.c:459

Referenced by PngDecoder_CreateInstance().

◆ png_decoder_destroy()

static void CDECL png_decoder_destroy ( struct decoder iface)
static

Definition at line 450 of file libpng.c.

451{
452 struct png_decoder *This = impl_from_decoder(iface);
453
454 free(This->image_bits);
455 free(This->color_profile);
456 free(This);
457}
#define free
Definition: debug_ros.c:5

◆ png_decoder_get_color_context()

static HRESULT CDECL png_decoder_get_color_context ( struct decoder iface,
UINT  frame,
UINT  num,
BYTE **  data,
DWORD datasize 
)
static

Definition at line 434 of file libpng.c.

436{
437 struct png_decoder *This = impl_from_decoder(iface);
438
439 *data = malloc(This->color_profile_len);
440 *datasize = This->color_profile_len;
441
442 if (!*data)
443 return E_OUTOFMEMORY;
444
445 memcpy(*data, This->color_profile, This->color_profile_len);
446
447 return S_OK;
448}
static SIZE_T datasize
Definition: asm.c:30
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

◆ png_decoder_get_frame_info()

static HRESULT CDECL png_decoder_get_frame_info ( struct decoder iface,
UINT  frame,
struct decoder_frame info 
)
static

Definition at line 345 of file libpng.c.

346{
347 struct png_decoder *This = impl_from_decoder(iface);
348 *info = This->decoder_frame;
349 return S_OK;
350}

◆ png_decoder_get_metadata_blocks()

static HRESULT CDECL png_decoder_get_metadata_blocks ( struct decoder iface,
UINT  frame,
UINT count,
struct decoder_block **  blocks 
)
static

Definition at line 362 of file libpng.c.

364{
365 struct png_decoder *This = impl_from_decoder(iface);
366 HRESULT hr;
367 struct decoder_block *result = NULL;
369 BYTE chunk_type[4];
370 ULONG chunk_size;
371 ULONGLONG chunk_start;
372 ULONG metadata_blocks_size = 0;
373
374 seek = 8;
375 *count = 0;
376
377 do
378 {
379 hr = stream_seek(This->stream, seek, STREAM_SEEK_SET, &chunk_start);
380 if (FAILED(hr)) goto end;
381
382 hr = read_png_chunk(This->stream, chunk_type, NULL, &chunk_size);
383 if (FAILED(hr)) goto end;
384
385 if (chunk_type[0] >= 'a' && chunk_type[0] <= 'z' &&
386 memcmp(chunk_type, "tRNS", 4) && memcmp(chunk_type, "pHYs", 4))
387 {
388 /* This chunk is considered metadata. */
389 if (*count == metadata_blocks_size)
390 {
391 struct decoder_block *new_metadata_blocks;
392 ULONG new_metadata_blocks_size;
393
394 new_metadata_blocks_size = 4 + metadata_blocks_size * 2;
395 new_metadata_blocks = malloc(new_metadata_blocks_size * sizeof(*new_metadata_blocks));
396
397 if (!new_metadata_blocks)
398 {
400 goto end;
401 }
402
403 memcpy(new_metadata_blocks, result,
404 *count * sizeof(*new_metadata_blocks));
405
406 free(result);
407 result = new_metadata_blocks;
408 metadata_blocks_size = new_metadata_blocks_size;
409 }
410
411 result[*count].offset = chunk_start;
412 result[*count].length = chunk_size + 12;
414 (*count)++;
415 }
416
417 seek = chunk_start + chunk_size + 12; /* skip data and CRC */
418 } while (memcmp(chunk_type, "IEND", 4));
419
420end:
421 if (SUCCEEDED(hr))
422 {
423 *blocks = result;
424 }
425 else
426 {
427 *count = 0;
428 *blocks = NULL;
429 free(result);
430 }
431 return hr;
432}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
static int blocks
Definition: mkdosfs.c:527
int seek(void *fd, ulong off, int mode)
Definition: pe.c:51
HRESULT hr
Definition: shlfolder.c:183
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
HRESULT CDECL stream_seek(IStream *stream, LONGLONG ofs, DWORD origin, ULONGLONG *new_position)
HRESULT read_png_chunk(IStream *stream, BYTE *type, BYTE **data, ULONG *data_size)
@ WICMetadataCreationAllowUnknown
Definition: wincodecsdk.idl:34
unsigned char BYTE
Definition: xxhash.c:193

◆ png_decoder_initialize()

static HRESULT CDECL png_decoder_initialize ( struct decoder iface,
IStream stream,
struct decoder_stat st 
)
static

Definition at line 65 of file libpng.c.

66{
67 struct png_decoder *This = impl_from_decoder(iface);
71 int color_type, bit_depth;
72 png_bytep trans;
73 int num_trans;
74 png_uint_32 transparency;
75 png_color_16p trans_values;
76 png_uint_32 ret, xres, yres;
77 int unit_type;
78 png_colorp png_palette;
79 int num_palette;
80 int i;
82 png_bytep *row_pointers=NULL;
83 png_charp cp_name;
84 png_bytep cp_profile;
85 png_uint_32 cp_len;
86 int cp_compression;
87
88 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
89 if (!png_ptr)
90 {
91 return E_FAIL;
92 }
93
94 info_ptr = png_create_info_struct(png_ptr);
95 if (!info_ptr)
96 {
97 png_destroy_read_struct(&png_ptr, NULL, NULL);
98 return E_FAIL;
99 }
100
101 /* set up setjmp/longjmp error handling */
103 {
105 goto end;
106 }
107 png_set_crc_action(png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
108 png_set_chunk_malloc_max(png_ptr, 0);
109
110 /* seek to the start of the stream */
111 hr = stream_seek(stream, 0, STREAM_SEEK_SET, NULL);
112 if (FAILED(hr))
113 {
114 goto end;
115 }
116
117 /* set up custom i/o handling */
118 png_set_read_fn(png_ptr, stream, user_read_data);
119
120 /* read the header */
121 png_read_info(png_ptr, info_ptr);
122
123 /* choose a pixel format */
124 color_type = png_get_color_type(png_ptr, info_ptr);
125 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
126
127 /* PNGs with bit-depth greater than 8 are network byte order. Windows does not expect this. */
128 if (bit_depth > 8)
129 png_set_swap(png_ptr);
130
131 /* check for color-keyed alpha */
132 transparency = png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values);
133 if (!transparency)
134 num_trans = 0;
135
136 if (transparency && (color_type == PNG_COLOR_TYPE_RGB ||
137 (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 16)))
138 {
139 /* expand to RGBA */
140 if (color_type == PNG_COLOR_TYPE_GRAY)
141 png_set_gray_to_rgb(png_ptr);
142 png_set_tRNS_to_alpha(png_ptr);
143 color_type = PNG_COLOR_TYPE_RGB_ALPHA;
144 }
145
146 switch (color_type)
147 {
149 /* WIC does not support grayscale alpha formats so use RGBA */
150 png_set_gray_to_rgb(png_ptr);
151 /* fall through */
153 This->decoder_frame.bpp = bit_depth * 4;
154 switch (bit_depth)
155 {
156 case 8:
157 png_set_bgr(png_ptr);
158 This->decoder_frame.pixel_format = GUID_WICPixelFormat32bppBGRA;
159 break;
160 case 16: This->decoder_frame.pixel_format = GUID_WICPixelFormat64bppRGBA; break;
161 default:
162 ERR("invalid RGBA bit depth: %i\n", bit_depth);
163 hr = E_FAIL;
164 goto end;
165 }
166 break;
168 This->decoder_frame.bpp = bit_depth;
169 if (!transparency)
170 {
171 switch (bit_depth)
172 {
173 case 1: This->decoder_frame.pixel_format = GUID_WICPixelFormatBlackWhite; break;
174 case 2: This->decoder_frame.pixel_format = GUID_WICPixelFormat2bppGray; break;
175 case 4: This->decoder_frame.pixel_format = GUID_WICPixelFormat4bppGray; break;
176 case 8: This->decoder_frame.pixel_format = GUID_WICPixelFormat8bppGray; break;
177 case 16: This->decoder_frame.pixel_format = GUID_WICPixelFormat16bppGray; break;
178 default:
179 ERR("invalid grayscale bit depth: %i\n", bit_depth);
180 hr = E_FAIL;
181 goto end;
182 }
183 break;
184 }
185 /* else fall through */
187 This->decoder_frame.bpp = bit_depth;
188 switch (bit_depth)
189 {
190 case 1: This->decoder_frame.pixel_format = GUID_WICPixelFormat1bppIndexed; break;
191 case 2: This->decoder_frame.pixel_format = GUID_WICPixelFormat2bppIndexed; break;
192 case 4: This->decoder_frame.pixel_format = GUID_WICPixelFormat4bppIndexed; break;
193 case 8: This->decoder_frame.pixel_format = GUID_WICPixelFormat8bppIndexed; break;
194 default:
195 ERR("invalid indexed color bit depth: %i\n", bit_depth);
196 hr = E_FAIL;
197 goto end;
198 }
199 break;
201 This->decoder_frame.bpp = bit_depth * 3;
202 switch (bit_depth)
203 {
204 case 8:
205 png_set_bgr(png_ptr);
206 This->decoder_frame.pixel_format = GUID_WICPixelFormat24bppBGR;
207 break;
208 case 16: This->decoder_frame.pixel_format = GUID_WICPixelFormat48bppRGB; break;
209 default:
210 ERR("invalid RGB color bit depth: %i\n", bit_depth);
211 hr = E_FAIL;
212 goto end;
213 }
214 break;
215 default:
216 ERR("invalid color type %i\n", color_type);
217 hr = E_FAIL;
218 goto end;
219 }
220
221 This->decoder_frame.width = png_get_image_width(png_ptr, info_ptr);
222 This->decoder_frame.height = png_get_image_height(png_ptr, info_ptr);
223
224 ret = png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type);
225
226 if (ret && unit_type == PNG_RESOLUTION_METER)
227 {
228 This->decoder_frame.dpix = xres * 0.0254;
229 This->decoder_frame.dpiy = yres * 0.0254;
230 }
231 else
232 {
233 WARN("no pHYs block present\n");
234 This->decoder_frame.dpix = This->decoder_frame.dpiy = 96.0;
235 }
236
237 ret = png_get_iCCP(png_ptr, info_ptr, &cp_name, &cp_compression, &cp_profile, &cp_len);
238 if (ret)
239 {
240 This->decoder_frame.num_color_contexts = 1;
241 This->color_profile_len = cp_len;
242 This->color_profile = malloc(cp_len);
243 if (!This->color_profile)
244 {
246 goto end;
247 }
248 memcpy(This->color_profile, cp_profile, cp_len);
249 }
250 else
251 This->decoder_frame.num_color_contexts = 0;
252
253 if (color_type == PNG_COLOR_TYPE_PALETTE)
254 {
255 ret = png_get_PLTE(png_ptr, info_ptr, &png_palette, &num_palette);
256 if (!ret)
257 {
258 ERR("paletted image with no PLTE chunk\n");
259 hr = E_FAIL;
260 goto end;
261 }
262
263 if (num_palette > 256)
264 {
265 ERR("palette has %i colors?!\n", num_palette);
266 hr = E_FAIL;
267 goto end;
268 }
269
270 This->decoder_frame.num_colors = num_palette;
271 for (i=0; i<num_palette; i++)
272 {
273 BYTE alpha = (i < num_trans) ? trans[i] : 0xff;
274 This->decoder_frame.palette[i] = (alpha << 24 |
275 png_palette[i].red << 16|
276 png_palette[i].green << 8|
277 png_palette[i].blue);
278 }
279 }
280 else if (color_type == PNG_COLOR_TYPE_GRAY && transparency && bit_depth <= 8) {
281 num_palette = 1 << bit_depth;
282
283 This->decoder_frame.num_colors = num_palette;
284 for (i=0; i<num_palette; i++)
285 {
286 BYTE alpha = (i == trans_values[0].gray) ? 0 : 0xff;
287 BYTE val = i * 255 / (num_palette - 1);
288 This->decoder_frame.palette[i] = (alpha << 24 | val << 16 | val << 8 | val);
289 }
290 }
291 else
292 {
293 This->decoder_frame.num_colors = 0;
294 }
295
296 This->stride = (This->decoder_frame.width * This->decoder_frame.bpp + 7) / 8;
297 image_size = This->stride * This->decoder_frame.height;
298
299 This->image_bits = malloc(image_size);
300 if (!This->image_bits)
301 {
303 goto end;
304 }
305
306 row_pointers = malloc(sizeof(png_bytep)*This->decoder_frame.height);
307 if (!row_pointers)
308 {
310 goto end;
311 }
312
313 for (i=0; i<This->decoder_frame.height; i++)
314 row_pointers[i] = This->image_bits + i * This->stride;
315
316 png_read_image(png_ptr, row_pointers);
317
318 free(row_pointers);
319 row_pointers = NULL;
320
321 /* png_read_end intentionally not called to not seek to the end of the file */
322
326 st->frame_count = 1;
327
328 This->stream = stream;
329
330 hr = S_OK;
331
332end:
333 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
334 free(row_pointers);
335 if (FAILED(hr))
336 {
337 free(This->image_bits);
338 This->image_bits = NULL;
339 free(This->color_profile);
340 This->color_profile = NULL;
341 }
342 return hr;
343}
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define E_FAIL
Definition: ddrawi.h:102
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
GLuint GLfloat * val
Definition: glext.h:7180
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
static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
Definition: libpng.c:52
static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
Definition: mipmap.c:4858
#define PNG_COLOR_TYPE_RGB
Definition: image.c:5165
#define PNG_COLOR_TYPE_RGB_ALPHA
Definition: image.c:5168
#define PNG_COLOR_TYPE_GRAY_ALPHA
Definition: image.c:5167
#define PNG_COLOR_TYPE_GRAY
Definition: image.c:5164
#define PNG_COLOR_TYPE_PALETTE
Definition: image.c:5166
unsigned int UINT
Definition: ndis.h:50
png_structrp png_ptr
Definition: png.h:1080
png_uint_32
Definition: png.h:1936
#define png_jmpbuf(png_ptr)
Definition: png.h:949
#define PNG_CRC_QUIET_USE
Definition: png.h:1437
#define PNG_RESOLUTION_METER
Definition: png.h:708
#define PNG_LIBPNG_VER_STRING
Definition: png.h:281
png_const_structrp png_const_inforp info_ptr
Definition: png.h:1937
char * png_charp
Definition: pngconf.h:589
png_byte * png_bytep
Definition: pngconf.h:579
png_uint_16 gray
Definition: png.h:491
png_byte blue
Definition: png.h:479
png_byte red
Definition: png.h:477
png_byte green
Definition: png.h:478
IStream * stream
Definition: libpng.c:39
Definition: parse.h:23
#define setjmp
Definition: setjmp.h:209
int ret
@ WICBitmapDecoderCapabilityCanDecodeSomeImages
Definition: wincodec.idl:51
@ WICBitmapDecoderCapabilityCanEnumerateMetadata
Definition: wincodec.idl:52
@ WICBitmapDecoderCapabilityCanDecodeAllImages
Definition: wincodec.idl:50
#define WINCODEC_ERR_UNKNOWNIMAGEFORMAT
Definition: winerror.h:3283

◆ png_encoder_commit_file()

static HRESULT CDECL png_encoder_commit_file ( struct encoder encoder)
static

Definition at line 793 of file libpng.c.

794{
795 return S_OK;
796}

◆ png_encoder_commit_frame()

static HRESULT CDECL png_encoder_commit_frame ( struct encoder encoder)
static

Definition at line 759 of file libpng.c.

760{
762 png_byte **row_pointers=NULL;
763
764 /* set up setjmp/longjmp error handling */
765 if (setjmp(png_jmpbuf(This->png_ptr)))
766 {
767 free(row_pointers);
768 return E_FAIL;
769 }
770
771 if (This->encoder_frame.interlace)
772 {
773 int i;
774
775 row_pointers = malloc(This->encoder_frame.height * sizeof(png_byte*));
776 if (!row_pointers)
777 return E_OUTOFMEMORY;
778
779 for (i=0; i<This->encoder_frame.height; i++)
780 row_pointers[i] = This->data + This->stride * i;
781
782 for (i=0; i<This->passes; i++)
783 png_write_rows(This->png_ptr, row_pointers, This->encoder_frame.height);
784 }
785
786 png_write_end(This->png_ptr, This->info_ptr);
787
788 free(row_pointers);
789
790 return S_OK;
791}
static struct png_encoder * impl_from_encoder(struct encoder *iface)
Definition: libpng.c:532
#define for
Definition: utility.h:88

◆ png_encoder_create()

HRESULT CDECL png_encoder_create ( struct encoder_info info,
struct encoder **  result 
)

Definition at line 817 of file libpng.c.

818{
819 struct png_encoder *This;
820
821 This = malloc(sizeof(*This));
822
823 if (!This)
824 {
825 return E_OUTOFMEMORY;
826 }
827
828 This->encoder.vtable = &png_encoder_vtable;
829 This->png_ptr = NULL;
830 This->info_ptr = NULL;
831 This->data = NULL;
832 *result = &This->encoder;
833
835 info->container_format = GUID_ContainerFormatPng;
836 info->clsid = CLSID_WICPngEncoder;
837 info->encoder_options[0] = ENCODER_OPTION_INTERLACE;
838 info->encoder_options[1] = ENCODER_OPTION_FILTER;
839 info->encoder_options[2] = ENCODER_OPTION_END;
840
841 return S_OK;
842}
static const struct encoder_funcs png_encoder_vtable
Definition: libpng.c:807
#define ENCODER_FLAGS_SUPPORTS_METADATA
@ ENCODER_OPTION_INTERLACE
@ ENCODER_OPTION_FILTER
@ ENCODER_OPTION_END

Referenced by PngEncoder_CreateInstance().

◆ png_encoder_create_frame()

static HRESULT CDECL png_encoder_create_frame ( struct encoder encoder,
const struct encoder_frame encoder_frame 
)
static

Definition at line 610 of file libpng.c.

611{
613 int i;
614
615 for (i=0; formats[i].guid; i++)
616 {
617 if (memcmp(formats[i].guid, &encoder_frame->pixel_format, sizeof(GUID)) == 0)
618 {
619 This->format = &formats[i];
620 break;
621 }
622 }
623
624 if (!formats[i].guid)
625 {
626 ERR("invalid pixel format %s\n", wine_dbgstr_guid(&encoder_frame->pixel_format));
627 return E_FAIL;
628 }
629
630 /* set up setjmp/longjmp error handling */
631 if (setjmp(png_jmpbuf(This->png_ptr)))
632 return E_FAIL;
633
634 This->encoder_frame = *encoder_frame;
635 This->lines_written = 0;
636
638 {
639 /* libpng requires us to write all data multiple times in this case. */
640 This->stride = (This->format->bpp * encoder_frame->width + 7)/8;
641 This->data = malloc(encoder_frame->height * This->stride);
642 if (!This->data)
643 return E_OUTOFMEMORY;
644 }
645
646 /* Tell PNG we need to byte swap if writing a >8-bpp image */
647 if (This->format->bit_depth > 8)
648 png_set_swap(This->png_ptr);
649
650 png_set_IHDR(This->png_ptr, This->info_ptr, encoder_frame->width, encoder_frame->height,
651 This->format->bit_depth, This->format->color_type,
654
655 if (encoder_frame->dpix != 0.0 && encoder_frame->dpiy != 0.0)
656 {
657 png_set_pHYs(This->png_ptr, This->info_ptr, (encoder_frame->dpix+0.0127) / 0.0254,
658 (encoder_frame->dpiy+0.0127) / 0.0254, PNG_RESOLUTION_METER);
659 }
660
661 if (This->format->color_type == PNG_COLOR_TYPE_PALETTE && encoder_frame->num_colors)
662 {
663 png_color png_palette[256];
664 png_byte trans[256];
665 UINT i, num_trans = 0, colors;
666
667 /* Newer libpng versions don't accept larger palettes than the declared
668 * bit depth, so we need to generate the palette of the correct length.
669 */
670 colors = min(encoder_frame->num_colors, 1 << This->format->bit_depth);
671
672 for (i = 0; i < colors; i++)
673 {
674 png_palette[i].red = (encoder_frame->palette[i] >> 16) & 0xff;
675 png_palette[i].green = (encoder_frame->palette[i] >> 8) & 0xff;
676 png_palette[i].blue = encoder_frame->palette[i] & 0xff;
677 trans[i] = (encoder_frame->palette[i] >> 24) & 0xff;
678 if (trans[i] != 0xff)
679 num_trans = i+1;
680 }
681
682 png_set_PLTE(This->png_ptr, This->info_ptr, png_palette, colors);
683
684 if (num_trans)
685 png_set_tRNS(This->png_ptr, This->info_ptr, trans, num_trans, NULL);
686 }
687
688 png_write_info(This->png_ptr, This->info_ptr);
689
690 if (This->format->remove_filler)
691 png_set_filler(This->png_ptr, 0, PNG_FILLER_AFTER);
692
693 if (This->format->swap_rgb)
694 png_set_bgr(This->png_ptr);
695
697 This->passes = png_set_interlace_handling(This->png_ptr);
698
700 {
701 static const int png_filter_map[] =
702 {
703 /* WICPngFilterUnspecified */ PNG_NO_FILTERS,
704 /* WICPngFilterNone */ PNG_FILTER_NONE,
705 /* WICPngFilterSub */ PNG_FILTER_SUB,
706 /* WICPngFilterUp */ PNG_FILTER_UP,
707 /* WICPngFilterAverage */ PNG_FILTER_AVG,
708 /* WICPngFilterPaeth */ PNG_FILTER_PAETH,
709 /* WICPngFilterAdaptive */ PNG_ALL_FILTERS,
710 };
711
712 png_set_filter(This->png_ptr, 0, png_filter_map[encoder_frame->filter]);
713 }
714
715 return S_OK;
716}
static const struct png_pixelformat formats[]
Definition: libpng.c:500
const GUID * guid
#define min(a, b)
Definition: monoChain.cc:55
#define PNG_FILTER_SUB
Definition: png.h:1463
#define PNG_FILTER_PAETH
Definition: png.h:1466
#define PNG_FILTER_NONE
Definition: png.h:1462
#define PNG_COMPRESSION_TYPE_DEFAULT
Definition: png.h:676
#define PNG_FILTER_AVG
Definition: png.h:1465
#define PNG_ALL_FILTERS
Definition: png.h:1468
#define PNG_FILLER_AFTER
Definition: png.h:1246
#define PNG_INTERLACE_ADAM7
Definition: png.h:685
#define PNG_FILTER_UP
Definition: png.h:1464
#define PNG_FILTER_TYPE_DEFAULT
Definition: png.h:681
#define PNG_NO_FILTERS
Definition: png.h:1461
#define PNG_INTERLACE_NONE
Definition: png.h:684
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
WICColor palette[256]
struct encoder_frame encoder_frame
Definition: libpng.c:524
@ WICPngFilterUnspecified
Definition: wincodec.idl:181

◆ png_encoder_destroy()

static void CDECL png_encoder_destroy ( struct encoder encoder)
static

Definition at line 798 of file libpng.c.

799{
801 if (This->png_ptr)
802 png_destroy_write_struct(&This->png_ptr, &This->info_ptr);
803 free(This->data);
804 free(This);
805}

◆ png_encoder_get_supported_format()

static HRESULT CDECL png_encoder_get_supported_format ( struct encoder iface,
GUID pixel_format,
DWORD bpp,
BOOL indexed 
)
static

Definition at line 590 of file libpng.c.

591{
592 int i;
593
594 for (i=0; formats[i].guid; i++)
595 {
596 if (memcmp(formats[i].guid, pixel_format, sizeof(GUID)) == 0)
597 break;
598 }
599
600 if (!formats[i].guid)
601 i = 0;
602
603 *pixel_format = *formats[i].guid;
604 *bpp = formats[i].bpp;
605 *indexed = (formats[i].color_type == PNG_COLOR_TYPE_PALETTE);
606
607 return S_OK;
608}
DWORD bpp
Definition: surface.c:185

◆ png_encoder_initialize()

static HRESULT CDECL png_encoder_initialize ( struct encoder encoder,
IStream stream 
)
static

Definition at line 554 of file libpng.c.

555{
557
558 TRACE("(%p,%p)\n", encoder, stream);
559
560 /* initialize libpng */
561 This->png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
562 if (!This->png_ptr)
563 return E_FAIL;
564
565 This->info_ptr = png_create_info_struct(This->png_ptr);
566 if (!This->info_ptr)
567 {
568 png_destroy_write_struct(&This->png_ptr, NULL);
569 This->png_ptr = NULL;
570 return E_FAIL;
571 }
572
573 This->stream = stream;
574
575 /* set up setjmp/longjmp error handling */
576 if (setjmp(png_jmpbuf(This->png_ptr)))
577 {
578 png_destroy_write_struct(&This->png_ptr, &This->info_ptr);
579 This->png_ptr = NULL;
580 This->stream = NULL;
581 return E_FAIL;
582 }
583
584 /* set up custom i/o handling */
585 png_set_write_fn(This->png_ptr, This, user_write_data, user_flush);
586
587 return S_OK;
588}
static void user_flush(png_structp png_ptr)
Definition: libpng.c:550
static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
Definition: libpng.c:537
#define TRACE(s)
Definition: solgame.cpp:4
IStream * stream
Definition: libpng.c:521

◆ png_encoder_write_lines()

static HRESULT CDECL png_encoder_write_lines ( struct encoder encoder,
BYTE data,
DWORD  line_count,
DWORD  stride 
)
static

Definition at line 718 of file libpng.c.

719{
721 png_byte **row_pointers=NULL;
722 UINT i;
723
724 if (This->encoder_frame.interlace)
725 {
726 /* Just store the data so we can write it in multiple passes in Commit. */
727 for (i=0; i<line_count; i++)
728 memcpy(This->data + This->stride * (This->lines_written + i),
729 data + stride * i,
730 This->stride);
731
732 This->lines_written += line_count;
733
734 return S_OK;
735 }
736
737 /* set up setjmp/longjmp error handling */
738 if (setjmp(png_jmpbuf(This->png_ptr)))
739 {
740 free(row_pointers);
741 return E_FAIL;
742 }
743
744 row_pointers = malloc(line_count * sizeof(png_byte*));
745 if (!row_pointers)
746 return E_OUTOFMEMORY;
747
748 for (i=0; i<line_count; i++)
749 row_pointers[i] = data + stride * i;
750
751 png_write_rows(This->png_ptr, row_pointers, line_count);
752 This->lines_written += line_count;
753
754 free(row_pointers);
755
756 return S_OK;
757}

◆ user_flush()

static void user_flush ( png_structp  png_ptr)
static

Definition at line 550 of file libpng.c.

551{
552}

Referenced by png_encoder_initialize().

◆ user_read_data()

static void user_read_data ( png_structp  png_ptr,
png_bytep  data,
png_size_t  length 
)
static

Definition at line 52 of file libpng.c.

53{
55 HRESULT hr;
56 ULONG bytesread;
57
58 hr = stream_read(stream, data, length, &bytesread);
59 if (FAILED(hr) || bytesread != length)
60 {
61 png_error(png_ptr, "failed reading data");
62 }
63}
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
static int stream_read
Definition: htmldoc.c:205
png_voidp PNGAPI png_get_io_ptr(png_const_structrp png_ptr)
Definition: png.c:686

Referenced by png_decoder_initialize().

◆ user_write_data()

static void user_write_data ( png_structp  png_ptr,
png_bytep  data,
png_size_t  length 
)
static

Definition at line 537 of file libpng.c.

538{
540 HRESULT hr;
541 ULONG byteswritten;
542
543 hr = stream_write(This->stream, data, length, &byteswritten);
544 if (FAILED(hr) || byteswritten != length)
545 {
546 png_error(png_ptr, "failed writing data");
547 }
548}
HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written)

Referenced by lzw_state_init(), and png_encoder_initialize().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( wincodecs  )

Variable Documentation

◆ formats

const struct png_pixelformat formats[]
static
Initial value:
= {
{&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1},
{&GUID_WICPixelFormat24bppBGR, 24, 8, PNG_COLOR_TYPE_RGB, 0, 1},
{&GUID_WICPixelFormatBlackWhite, 1, 1, PNG_COLOR_TYPE_GRAY, 0, 0},
{&GUID_WICPixelFormat2bppGray, 2, 2, PNG_COLOR_TYPE_GRAY, 0, 0},
{&GUID_WICPixelFormat4bppGray, 4, 4, PNG_COLOR_TYPE_GRAY, 0, 0},
{&GUID_WICPixelFormat8bppGray, 8, 8, PNG_COLOR_TYPE_GRAY, 0, 0},
{&GUID_WICPixelFormat16bppGray, 16, 16, PNG_COLOR_TYPE_GRAY, 0, 0},
{&GUID_WICPixelFormat32bppBGR, 32, 8, PNG_COLOR_TYPE_RGB, 1, 1},
{&GUID_WICPixelFormat48bppRGB, 48, 16, PNG_COLOR_TYPE_RGB, 0, 0},
{&GUID_WICPixelFormat64bppRGBA, 64, 16, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0},
{&GUID_WICPixelFormat1bppIndexed, 1, 1, PNG_COLOR_TYPE_PALETTE, 0, 0},
{&GUID_WICPixelFormat2bppIndexed, 2, 2, PNG_COLOR_TYPE_PALETTE, 0, 0},
{&GUID_WICPixelFormat4bppIndexed, 4, 4, PNG_COLOR_TYPE_PALETTE, 0, 0},
{&GUID_WICPixelFormat8bppIndexed, 8, 8, PNG_COLOR_TYPE_PALETTE, 0, 0},
{NULL},
}

Definition at line 500 of file libpng.c.

Referenced by png_encoder_create_frame(), and png_encoder_get_supported_format().

◆ png_decoder_vtable

const struct decoder_funcs png_decoder_vtable
static
Initial value:
= {
}
static HRESULT CDECL png_decoder_get_color_context(struct decoder *iface, UINT frame, UINT num, BYTE **data, DWORD *datasize)
Definition: libpng.c:434
static void CDECL png_decoder_destroy(struct decoder *iface)
Definition: libpng.c:450
static HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, struct decoder_stat *st)
Definition: libpng.c:65
static HRESULT CDECL png_decoder_copy_pixels(struct decoder *iface, UINT frame, const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
Definition: libpng.c:352
static HRESULT CDECL png_decoder_get_metadata_blocks(struct decoder *iface, UINT frame, UINT *count, struct decoder_block **blocks)
Definition: libpng.c:362
static HRESULT CDECL png_decoder_get_frame_info(struct decoder *iface, UINT frame, struct decoder_frame *info)
Definition: libpng.c:345

Definition at line 459 of file libpng.c.

Referenced by png_decoder_create().

◆ png_encoder_vtable

const struct encoder_funcs png_encoder_vtable
static
Initial value:
= {
}
static void CDECL png_encoder_destroy(struct encoder *encoder)
Definition: libpng.c:798
static HRESULT CDECL png_encoder_initialize(struct encoder *encoder, IStream *stream)
Definition: libpng.c:554
static HRESULT CDECL png_encoder_commit_frame(struct encoder *encoder)
Definition: libpng.c:759
static HRESULT CDECL png_encoder_get_supported_format(struct encoder *iface, GUID *pixel_format, DWORD *bpp, BOOL *indexed)
Definition: libpng.c:590
static HRESULT CDECL png_encoder_write_lines(struct encoder *encoder, BYTE *data, DWORD line_count, DWORD stride)
Definition: libpng.c:718
static HRESULT CDECL png_encoder_commit_file(struct encoder *encoder)
Definition: libpng.c:793
static HRESULT CDECL png_encoder_create_frame(struct encoder *encoder, const struct encoder_frame *encoder_frame)
Definition: libpng.c:610

Definition at line 807 of file libpng.c.

Referenced by png_encoder_create().