ReactOS 0.4.16-dev-927-g467dec4
libpng.c
Go to the documentation of this file.
1/*
2 * Copyright 2016 Dmitry Timoshkov
3 * Copyright 2020 Esme Povirk
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#include <png.h>
22
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
30#include "wincodecs_private.h"
31
32#include "wine/debug.h"
33
35
37{
45};
46
47static inline struct png_decoder *impl_from_decoder(struct decoder* iface)
48{
49 return CONTAINING_RECORD(iface, struct png_decoder, decoder);
50}
51
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}
64
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}
344
346{
347 struct png_decoder *This = impl_from_decoder(iface);
348 *info = This->decoder_frame;
349 return S_OK;
350}
351
353 const WICRect *prc, UINT stride, UINT buffersize, BYTE *buffer)
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}
361
363 UINT frame, UINT *count, struct decoder_block **blocks)
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}
433
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}
449
450static void CDECL png_decoder_destroy(struct decoder* iface)
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}
458
459static const struct decoder_funcs png_decoder_vtable = {
466};
467
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}
490
498};
499
500static const struct png_pixelformat formats[] = {
501 {&GUID_WICPixelFormat32bppBGRA, 32, 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 1},
502 {&GUID_WICPixelFormat24bppBGR, 24, 8, PNG_COLOR_TYPE_RGB, 0, 1},
503 {&GUID_WICPixelFormatBlackWhite, 1, 1, PNG_COLOR_TYPE_GRAY, 0, 0},
504 {&GUID_WICPixelFormat2bppGray, 2, 2, PNG_COLOR_TYPE_GRAY, 0, 0},
505 {&GUID_WICPixelFormat4bppGray, 4, 4, PNG_COLOR_TYPE_GRAY, 0, 0},
506 {&GUID_WICPixelFormat8bppGray, 8, 8, PNG_COLOR_TYPE_GRAY, 0, 0},
507 {&GUID_WICPixelFormat16bppGray, 16, 16, PNG_COLOR_TYPE_GRAY, 0, 0},
508 {&GUID_WICPixelFormat32bppBGR, 32, 8, PNG_COLOR_TYPE_RGB, 1, 1},
509 {&GUID_WICPixelFormat48bppRGB, 48, 16, PNG_COLOR_TYPE_RGB, 0, 0},
510 {&GUID_WICPixelFormat64bppRGBA, 64, 16, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0},
511 {&GUID_WICPixelFormat1bppIndexed, 1, 1, PNG_COLOR_TYPE_PALETTE, 0, 0},
512 {&GUID_WICPixelFormat2bppIndexed, 2, 2, PNG_COLOR_TYPE_PALETTE, 0, 0},
513 {&GUID_WICPixelFormat4bppIndexed, 4, 4, PNG_COLOR_TYPE_PALETTE, 0, 0},
514 {&GUID_WICPixelFormat8bppIndexed, 8, 8, PNG_COLOR_TYPE_PALETTE, 0, 0},
515 {NULL},
516};
517
519{
525 const struct png_pixelformat *format;
530};
531
532static inline struct png_encoder *impl_from_encoder(struct encoder* iface)
533{
534 return CONTAINING_RECORD(iface, struct png_encoder, encoder);
535}
536
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}
549
551{
552}
553
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}
589
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}
609
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}
717
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}
758
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}
792
794{
795 return S_OK;
796}
797
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}
806
807static const struct encoder_funcs png_encoder_vtable = {
815};
816
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}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
static SIZE_T datasize
Definition: asm.c:30
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
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
DWORD bpp
Definition: surface.c:185
#define CDECL
Definition: compat.h:29
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizei stride
Definition: glext.h:5848
GLuint buffer
Definition: glext.h:5915
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint GLfloat * val
Definition: glext.h:7180
GLuint64EXT * result
Definition: glext.h:11304
GLuint GLuint num
Definition: glext.h:9618
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
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
static const struct encoder_funcs png_encoder_vtable
Definition: libpng.c:807
static void CDECL png_encoder_destroy(struct encoder *encoder)
Definition: libpng.c:798
static struct png_encoder * impl_from_encoder(struct encoder *iface)
Definition: libpng.c:532
static HRESULT CDECL png_encoder_initialize(struct encoder *encoder, IStream *stream)
Definition: libpng.c:554
static const struct decoder_funcs png_decoder_vtable
Definition: libpng.c:459
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 const struct png_pixelformat formats[]
Definition: libpng.c:500
static HRESULT CDECL png_decoder_initialize(struct decoder *iface, IStream *stream, struct decoder_stat *st)
Definition: libpng.c:65
HRESULT CDECL png_encoder_create(struct encoder_info *info, struct encoder **result)
Definition: libpng.c:817
static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
Definition: libpng.c:52
static void user_flush(png_structp png_ptr)
Definition: libpng.c:550
static struct png_decoder * impl_from_decoder(struct decoder *iface)
Definition: libpng.c:47
static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
Definition: libpng.c:537
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_encoder_commit_frame(struct encoder *encoder)
Definition: libpng.c:759
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
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
HRESULT CDECL png_decoder_create(struct decoder_info *info, struct decoder **result)
Definition: libpng.c:468
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
const GUID * guid
static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
Definition: mipmap.c:4858
static int blocks
Definition: mkdosfs.c:527
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define for
Definition: utility.h:88
#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
static int stream_read
Definition: htmldoc.c:205
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
_Out_ LPRECT prc
Definition: ntgdi.h:1658
png_voidp PNGAPI png_get_io_ptr(png_const_structrp png_ptr)
Definition: png.c:686
#define PNG_FILTER_SUB
Definition: png.h:1463
#define PNG_FILTER_PAETH
Definition: png.h:1466
#define PNG_FILTER_NONE
Definition: png.h:1462
png_structrp png_ptr
Definition: png.h:1080
#define PNG_COMPRESSION_TYPE_DEFAULT
Definition: png.h:676
#define PNG_FILTER_AVG
Definition: png.h:1465
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_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_LIBPNG_VER_STRING
Definition: png.h:281
#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
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
size_t png_size_t
Definition: pngconf.h:523
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
int seek(void *fd, ulong off, int mode)
Definition: pe.c:51
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
WICColor palette[256]
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
BYTE * image_bits
Definition: libpng.c:42
DWORD color_profile_len
Definition: libpng.c:44
UINT stride
Definition: libpng.c:41
BYTE * color_profile
Definition: libpng.c:43
IStream * stream
Definition: libpng.c:39
png_structp png_ptr
Definition: libpng.c:522
const struct png_pixelformat * format
Definition: libpng.c:525
struct encoder_frame encoder_frame
Definition: libpng.c:524
png_infop info_ptr
Definition: libpng.c:523
IStream * stream
Definition: libpng.c:521
UINT lines_written
Definition: libpng.c:529
UINT passes
Definition: libpng.c:528
UINT stride
Definition: libpng.c:527
BYTE * data
Definition: libpng.c:526
BOOL swap_rgb
Definition: libpng.c:497
const WICPixelFormatGUID * guid
Definition: libpng.c:492
BOOL remove_filler
Definition: libpng.c:496
int color_type
Definition: libpng.c:495
Definition: parse.h:23
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define setjmp
Definition: setjmp.h:209
int ret
@ WICPngFilterUnspecified
Definition: wincodec.idl:181
@ WICBitmapDecoderCapabilityCanDecodeSomeImages
Definition: wincodec.idl:51
@ WICBitmapDecoderCapabilityCanEnumerateMetadata
Definition: wincodec.idl:52
@ WICBitmapDecoderCapabilityCanDecodeAllImages
Definition: wincodec.idl:50
HRESULT CDECL stream_write(IStream *stream, const void *buffer, ULONG write, ULONG *bytes_written)
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)
#define ENCODER_FLAGS_SUPPORTS_METADATA
@ ENCODER_OPTION_INTERLACE
@ ENCODER_OPTION_FILTER
@ ENCODER_OPTION_END
@ WICMetadataCreationAllowUnknown
Definition: wincodecsdk.idl:34
#define WINCODEC_ERR_UNKNOWNIMAGEFORMAT
Definition: winerror.h:3283
unsigned char BYTE
Definition: xxhash.c:193