Tizen 2.0 Release
[framework/graphics/cairo.git] / src / cairo-png.c
1 /* cairo - a vector graphics library with display and print output
2  *
3  * Copyright © 2003 University of Southern California
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it either under the terms of the GNU Lesser General Public
7  * License version 2.1 as published by the Free Software Foundation
8  * (the "LGPL") or, at your option, under the terms of the Mozilla
9  * Public License Version 1.1 (the "MPL"). If you do not alter this
10  * notice, a recipient may use your version of this file under either
11  * the MPL or the LGPL.
12  *
13  * You should have received a copy of the LGPL along with this library
14  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16  * You should have received a copy of the MPL along with this library
17  * in the file COPYING-MPL-1.1
18  *
19  * The contents of this file are subject to the Mozilla Public License
20  * Version 1.1 (the "License"); you may not use this file except in
21  * compliance with the License. You may obtain a copy of the License at
22  * http://www.mozilla.org/MPL/
23  *
24  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26  * the specific language governing rights and limitations.
27  *
28  * The Original Code is the cairo graphics library.
29  *
30  * The Initial Developer of the Original Code is University of Southern
31  * California.
32  *
33  * Contributor(s):
34  *      Carl D. Worth <cworth@cworth.org>
35  *      Kristian Høgsberg <krh@redhat.com>
36  *      Chris Wilson <chris@chris-wilson.co.uk>
37  */
38
39 #include "cairoint.h"
40
41 #include "cairo-error-private.h"
42 #include "cairo-image-surface-private.h"
43 #include "cairo-output-stream-private.h"
44
45 #include <stdio.h>
46 #include <errno.h>
47 #include <png.h>
48
49 /**
50  * SECTION:cairo-png
51  * @Title: PNG Support
52  * @Short_Description: Reading and writing PNG images
53  * @See_Also: #cairo_surface_t
54  *
55  * The PNG functions allow reading PNG images into image surfaces, and writing
56  * any surface to a PNG file.
57  *
58  * It is a toy API. It only offers very simple support for reading and
59  * writing PNG files, which is sufficient for testing and
60  * demonstration purposes. Applications which need more control over
61  * the generated PNG file should access the pixel data directly, using
62  * cairo_image_surface_get_data() or a backend-specific access
63  * function, and process it with another library, e.g. gdk-pixbuf or
64  * libpng.
65  **/
66
67 /**
68  * CAIRO_HAS_PNG_FUNCTIONS:
69  *
70  * Defined if the PNG functions are available.
71  * This macro can be used to conditionally compile code using the cairo
72  * PNG functions.
73  *
74  * Since: 1.0
75  **/
76
77 struct png_read_closure_t {
78     cairo_read_func_t            read_func;
79     void                        *closure;
80     cairo_output_stream_t       *png_data;
81 };
82
83
84 /* Unpremultiplies data and converts native endian ARGB => RGBA bytes */
85 static void
86 unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
87 {
88     unsigned int i;
89
90     for (i = 0; i < row_info->rowbytes; i += 4) {
91         uint8_t *b = &data[i];
92         uint32_t pixel;
93         uint8_t  alpha;
94
95         memcpy (&pixel, b, sizeof (uint32_t));
96         alpha = (pixel & 0xff000000) >> 24;
97         if (alpha == 0) {
98             b[0] = b[1] = b[2] = b[3] = 0;
99         } else {
100             b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
101             b[1] = (((pixel & 0x00ff00) >>  8) * 255 + alpha / 2) / alpha;
102             b[2] = (((pixel & 0x0000ff) >>  0) * 255 + alpha / 2) / alpha;
103             b[3] = alpha;
104         }
105     }
106 }
107
108 /* Converts native endian xRGB => RGBx bytes */
109 static void
110 convert_data_to_bytes (png_structp png, png_row_infop row_info, png_bytep data)
111 {
112     unsigned int i;
113
114     for (i = 0; i < row_info->rowbytes; i += 4) {
115         uint8_t *b = &data[i];
116         uint32_t pixel;
117
118         memcpy (&pixel, b, sizeof (uint32_t));
119
120         b[0] = (pixel & 0xff0000) >> 16;
121         b[1] = (pixel & 0x00ff00) >>  8;
122         b[2] = (pixel & 0x0000ff) >>  0;
123         b[3] = 0;
124     }
125 }
126
127 /* Use a couple of simple error callbacks that do not print anything to
128  * stderr and rely on the user to check for errors via the #cairo_status_t
129  * return.
130  */
131 static void
132 png_simple_error_callback (png_structp png,
133                            png_const_charp error_msg)
134 {
135     cairo_status_t *error = png_get_error_ptr (png);
136
137     /* default to the most likely error */
138     if (*error == CAIRO_STATUS_SUCCESS)
139         *error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
140
141 #ifdef PNG_SETJMP_SUPPORTED
142     longjmp (png_jmpbuf (png), 1);
143 #endif
144
145     /* if we get here, then we have to choice but to abort ... */
146 }
147
148 static void
149 png_simple_warning_callback (png_structp png,
150                              png_const_charp error_msg)
151 {
152     cairo_status_t *error = png_get_error_ptr (png);
153
154     /* default to the most likely error */
155     if (*error == CAIRO_STATUS_SUCCESS)
156         *error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
157
158     /* png does not expect to abort and will try to tidy up after a warning */
159 }
160
161
162 /* Starting with libpng-1.2.30, we must explicitly specify an output_flush_fn.
163  * Otherwise, we will segfault if we are writing to a stream. */
164 static void
165 png_simple_output_flush_fn (png_structp png_ptr)
166 {
167 }
168
169 static cairo_status_t
170 write_png (cairo_surface_t      *surface,
171            png_rw_ptr           write_func,
172            void                 *closure)
173 {
174     int i;
175     cairo_int_status_t status;
176     cairo_image_surface_t *image;
177     cairo_image_surface_t * volatile clone;
178     void *image_extra;
179     png_struct *png;
180     png_info *info;
181     png_byte **volatile rows = NULL;
182     png_color_16 white;
183     int png_color_type;
184     int bpc;
185
186     status = _cairo_surface_acquire_source_image (surface,
187                                                   &image,
188                                                   &image_extra);
189
190     if (status == CAIRO_INT_STATUS_UNSUPPORTED)
191         return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
192     else if (unlikely (status))
193         return status;
194
195     /* PNG complains about "Image width or height is zero in IHDR" */
196     if (image->width == 0 || image->height == 0) {
197         status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
198         goto BAIL1;
199     }
200
201     /* Handle the various fallback formats (e.g. low bit-depth XServers)
202      * by coercing them to a simpler format using pixman.
203      */
204     clone = _cairo_image_surface_coerce (image);
205     status = clone->base.status;
206     if (unlikely (status))
207         goto BAIL1;
208
209     rows = _cairo_malloc_ab (clone->height, sizeof (png_byte*));
210     if (unlikely (rows == NULL)) {
211         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
212         goto BAIL2;
213     }
214
215     for (i = 0; i < clone->height; i++)
216         rows[i] = (png_byte *) clone->data + i * clone->stride;
217
218     png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status,
219                                    png_simple_error_callback,
220                                    png_simple_warning_callback);
221     if (unlikely (png == NULL)) {
222         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
223         goto BAIL3;
224     }
225
226     info = png_create_info_struct (png);
227     if (unlikely (info == NULL)) {
228         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
229         goto BAIL4;
230     }
231
232 #ifdef PNG_SETJMP_SUPPORTED
233     if (setjmp (png_jmpbuf (png)))
234         goto BAIL4;
235 #endif
236
237     png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn);
238
239     switch (clone->format) {
240     case CAIRO_FORMAT_ARGB32:
241         bpc = 8;
242         if (_cairo_image_analyze_transparency (clone) == CAIRO_IMAGE_IS_OPAQUE)
243             png_color_type = PNG_COLOR_TYPE_RGB;
244         else
245             png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
246         break;
247     case CAIRO_FORMAT_RGB30:
248         bpc = 10;
249         png_color_type = PNG_COLOR_TYPE_RGB;
250         break;
251     case CAIRO_FORMAT_RGB24:
252         bpc = 8;
253         png_color_type = PNG_COLOR_TYPE_RGB;
254         break;
255     case CAIRO_FORMAT_A8:
256         bpc = 8;
257         png_color_type = PNG_COLOR_TYPE_GRAY;
258         break;
259     case CAIRO_FORMAT_A1:
260         bpc = 1;
261         png_color_type = PNG_COLOR_TYPE_GRAY;
262 #ifndef WORDS_BIGENDIAN
263         png_set_packswap (png);
264 #endif
265         break;
266     case CAIRO_FORMAT_INVALID:
267     case CAIRO_FORMAT_RGB16_565:
268     default:
269         status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
270         goto BAIL4;
271     }
272
273     png_set_IHDR (png, info,
274                   clone->width,
275                   clone->height, bpc,
276                   png_color_type,
277                   PNG_INTERLACE_NONE,
278                   PNG_COMPRESSION_TYPE_DEFAULT,
279                   PNG_FILTER_TYPE_DEFAULT);
280
281     white.gray = (1 << bpc) - 1;
282     white.red = white.blue = white.green = white.gray;
283     png_set_bKGD (png, info, &white);
284
285     if (0) { /* XXX extract meta-data from surface (i.e. creation date) */
286         png_time pt;
287
288         png_convert_from_time_t (&pt, time (NULL));
289         png_set_tIME (png, info, &pt);
290     }
291
292     /* We have to call png_write_info() before setting up the write
293      * transformation, since it stores data internally in 'png'
294      * that is needed for the write transformation functions to work.
295      */
296     png_write_info (png, info);
297
298     if (png_color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
299         png_set_write_user_transform_fn (png, unpremultiply_data);
300     } else if (png_color_type == PNG_COLOR_TYPE_RGB) {
301         png_set_write_user_transform_fn (png, convert_data_to_bytes);
302         png_set_filler (png, 0, PNG_FILLER_AFTER);
303     }
304
305     png_write_image (png, rows);
306     png_write_end (png, info);
307
308 BAIL4:
309     png_destroy_write_struct (&png, &info);
310 BAIL3:
311     free (rows);
312 BAIL2:
313     cairo_surface_destroy (&clone->base);
314 BAIL1:
315     _cairo_surface_release_source_image (surface, image, image_extra);
316
317     return status;
318 }
319
320 static void
321 stdio_write_func (png_structp png, png_bytep data, png_size_t size)
322 {
323     FILE *fp;
324
325     fp = png_get_io_ptr (png);
326     while (size) {
327         size_t ret = fwrite (data, 1, size, fp);
328         size -= ret;
329         data += ret;
330         if (size && ferror (fp)) {
331             cairo_status_t *error = png_get_error_ptr (png);
332             if (*error == CAIRO_STATUS_SUCCESS)
333                 *error = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
334             png_error (png, NULL);
335         }
336     }
337 }
338
339 /**
340  * cairo_surface_write_to_png:
341  * @surface: a #cairo_surface_t with pixel contents
342  * @filename: the name of a file to write to
343  *
344  * Writes the contents of @surface to a new file @filename as a PNG
345  * image.
346  *
347  * Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
348  * successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY if memory could not
349  * be allocated for the operation or
350  * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
351  * pixel contents, or %CAIRO_STATUS_WRITE_ERROR if an I/O error occurs
352  * while attempting to write the file.
353  *
354  * Since: 1.0
355  **/
356 cairo_status_t
357 cairo_surface_write_to_png (cairo_surface_t     *surface,
358                             const char          *filename)
359 {
360     FILE *fp;
361     cairo_status_t status;
362
363     if (surface->status)
364         return surface->status;
365
366     if (surface->finished)
367         return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
368
369     fp = fopen (filename, "wb");
370     if (fp == NULL) {
371         switch (errno) {
372         case ENOMEM:
373             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
374         default:
375             return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
376         }
377     }
378
379     status = write_png (surface, stdio_write_func, fp);
380
381     if (fclose (fp) && status == CAIRO_STATUS_SUCCESS)
382         status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
383
384     return status;
385 }
386
387 struct png_write_closure_t {
388     cairo_write_func_t           write_func;
389     void                        *closure;
390 };
391
392 static void
393 stream_write_func (png_structp png, png_bytep data, png_size_t size)
394 {
395     cairo_status_t status;
396     struct png_write_closure_t *png_closure;
397
398     png_closure = png_get_io_ptr (png);
399     status = png_closure->write_func (png_closure->closure, data, size);
400     if (unlikely (status)) {
401         cairo_status_t *error = png_get_error_ptr (png);
402         if (*error == CAIRO_STATUS_SUCCESS)
403             *error = status;
404         png_error (png, NULL);
405     }
406 }
407
408 /**
409  * cairo_surface_write_to_png_stream:
410  * @surface: a #cairo_surface_t with pixel contents
411  * @write_func: a #cairo_write_func_t
412  * @closure: closure data for the write function
413  *
414  * Writes the image surface to the write function.
415  *
416  * Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
417  * successfully.  Otherwise, %CAIRO_STATUS_NO_MEMORY is returned if
418  * memory could not be allocated for the operation,
419  * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
420  * pixel contents.
421  *
422  * Since: 1.0
423  **/
424 cairo_status_t
425 cairo_surface_write_to_png_stream (cairo_surface_t      *surface,
426                                    cairo_write_func_t   write_func,
427                                    void                 *closure)
428 {
429     struct png_write_closure_t png_closure;
430
431     if (surface->status)
432         return surface->status;
433
434     if (surface->finished)
435         return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
436
437     png_closure.write_func = write_func;
438     png_closure.closure = closure;
439
440     return write_png (surface, stream_write_func, &png_closure);
441 }
442 slim_hidden_def (cairo_surface_write_to_png_stream);
443
444 static inline int
445 multiply_alpha (int alpha, int color)
446 {
447     int temp = (alpha * color) + 0x80;
448     return ((temp + (temp >> 8)) >> 8);
449 }
450
451 /* Premultiplies data and converts RGBA bytes => native endian */
452 static void
453 premultiply_data (png_structp   png,
454                   png_row_infop row_info,
455                   png_bytep     data)
456 {
457     unsigned int i;
458
459     for (i = 0; i < row_info->rowbytes; i += 4) {
460         uint8_t *base  = &data[i];
461         uint8_t  alpha = base[3];
462         uint32_t p;
463
464         if (alpha == 0) {
465             p = 0;
466         } else {
467             uint8_t  red   = base[0];
468             uint8_t  green = base[1];
469             uint8_t  blue  = base[2];
470
471             if (alpha != 0xff) {
472                 red   = multiply_alpha (alpha, red);
473                 green = multiply_alpha (alpha, green);
474                 blue  = multiply_alpha (alpha, blue);
475             }
476             p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
477         }
478         memcpy (base, &p, sizeof (uint32_t));
479     }
480 }
481
482 /* Converts RGBx bytes to native endian xRGB */
483 static void
484 convert_bytes_to_data (png_structp png, png_row_infop row_info, png_bytep data)
485 {
486     unsigned int i;
487
488     for (i = 0; i < row_info->rowbytes; i += 4) {
489         uint8_t *base  = &data[i];
490         uint8_t  red   = base[0];
491         uint8_t  green = base[1];
492         uint8_t  blue  = base[2];
493         uint32_t pixel;
494
495         pixel = (0xff << 24) | (red << 16) | (green << 8) | (blue << 0);
496         memcpy (base, &pixel, sizeof (uint32_t));
497     }
498 }
499
500 static cairo_status_t
501 stdio_read_func (void *closure, unsigned char *data, unsigned int size)
502 {
503     FILE *file = closure;
504
505     while (size) {
506         size_t ret;
507
508         ret = fread (data, 1, size, file);
509         size -= ret;
510         data += ret;
511
512         if (size && (feof (file) || ferror (file)))
513             return _cairo_error (CAIRO_STATUS_READ_ERROR);
514     }
515
516     return CAIRO_STATUS_SUCCESS;
517 }
518
519 static void
520 stream_read_func (png_structp png, png_bytep data, png_size_t size)
521 {
522     cairo_status_t status;
523     struct png_read_closure_t *png_closure;
524
525     png_closure = png_get_io_ptr (png);
526     status = png_closure->read_func (png_closure->closure, data, size);
527     if (unlikely (status)) {
528         cairo_status_t *error = png_get_error_ptr (png);
529         if (*error == CAIRO_STATUS_SUCCESS)
530             *error = status;
531         png_error (png, NULL);
532     }
533
534     _cairo_output_stream_write (png_closure->png_data, data, size);
535 }
536
537 static cairo_surface_t *
538 read_png (struct png_read_closure_t *png_closure)
539 {
540     cairo_surface_t *surface;
541     png_struct *png = NULL;
542     png_info *info;
543     png_byte *data = NULL;
544     png_byte **row_pointers = NULL;
545     png_uint_32 png_width, png_height;
546     int depth, color_type, interlace, stride;
547     unsigned int i;
548     cairo_format_t format;
549     cairo_status_t status;
550     unsigned char *mime_data;
551     unsigned long mime_data_length;
552
553     png_closure->png_data = _cairo_memory_stream_create ();
554
555     /* XXX: Perhaps we'll want some other error handlers? */
556     png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
557                                   &status,
558                                   png_simple_error_callback,
559                                   png_simple_warning_callback);
560     if (unlikely (png == NULL)) {
561         surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
562         goto BAIL;
563     }
564
565     info = png_create_info_struct (png);
566     if (unlikely (info == NULL)) {
567         surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
568         goto BAIL;
569     }
570
571     png_set_read_fn (png, png_closure, stream_read_func);
572
573     status = CAIRO_STATUS_SUCCESS;
574 #ifdef PNG_SETJMP_SUPPORTED
575     if (setjmp (png_jmpbuf (png))) {
576         surface = _cairo_surface_create_in_error (status);
577         goto BAIL;
578     }
579 #endif
580
581     png_read_info (png, info);
582
583     png_get_IHDR (png, info,
584                   &png_width, &png_height, &depth,
585                   &color_type, &interlace, NULL, NULL);
586     if (unlikely (status)) { /* catch any early warnings */
587         surface = _cairo_surface_create_in_error (status);
588         goto BAIL;
589     }
590
591     /* convert palette/gray image to rgb */
592     if (color_type == PNG_COLOR_TYPE_PALETTE)
593         png_set_palette_to_rgb (png);
594
595     /* expand gray bit depth if needed */
596     if (color_type == PNG_COLOR_TYPE_GRAY) {
597 #if PNG_LIBPNG_VER >= 10209
598         png_set_expand_gray_1_2_4_to_8 (png);
599 #else
600         png_set_gray_1_2_4_to_8 (png);
601 #endif
602     }
603
604     /* transform transparency to alpha */
605     if (png_get_valid (png, info, PNG_INFO_tRNS))
606         png_set_tRNS_to_alpha (png);
607
608     if (depth == 16)
609         png_set_strip_16 (png);
610
611     if (depth < 8)
612         png_set_packing (png);
613
614     /* convert grayscale to RGB */
615     if (color_type == PNG_COLOR_TYPE_GRAY ||
616         color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
617     {
618         png_set_gray_to_rgb (png);
619     }
620
621     if (interlace != PNG_INTERLACE_NONE)
622         png_set_interlace_handling (png);
623
624     png_set_filler (png, 0xff, PNG_FILLER_AFTER);
625
626     /* recheck header after setting EXPAND options */
627     png_read_update_info (png, info);
628     png_get_IHDR (png, info,
629                   &png_width, &png_height, &depth,
630                   &color_type, &interlace, NULL, NULL);
631     if (depth != 8 ||
632         ! (color_type == PNG_COLOR_TYPE_RGB ||
633            color_type == PNG_COLOR_TYPE_RGB_ALPHA))
634     {
635         surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_READ_ERROR));
636         goto BAIL;
637     }
638
639     switch (color_type) {
640         default:
641             ASSERT_NOT_REACHED;
642             /* fall-through just in case ;-) */
643
644         case PNG_COLOR_TYPE_RGB_ALPHA:
645             format = CAIRO_FORMAT_ARGB32;
646             png_set_read_user_transform_fn (png, premultiply_data);
647             break;
648
649         case PNG_COLOR_TYPE_RGB:
650             format = CAIRO_FORMAT_RGB24;
651             png_set_read_user_transform_fn (png, convert_bytes_to_data);
652             break;
653     }
654
655     stride = cairo_format_stride_for_width (format, png_width);
656     if (stride < 0) {
657         surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
658         goto BAIL;
659     }
660
661     data = _cairo_malloc_ab (png_height, stride);
662     if (unlikely (data == NULL)) {
663         surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
664         goto BAIL;
665     }
666
667     row_pointers = _cairo_malloc_ab (png_height, sizeof (char *));
668     if (unlikely (row_pointers == NULL)) {
669         surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
670         goto BAIL;
671     }
672
673     for (i = 0; i < png_height; i++)
674         row_pointers[i] = &data[i * stride];
675
676     png_read_image (png, row_pointers);
677     png_read_end (png, info);
678
679     if (unlikely (status)) { /* catch any late warnings - probably hit an error already */
680         surface = _cairo_surface_create_in_error (status);
681         goto BAIL;
682     }
683
684     surface = cairo_image_surface_create_for_data (data, format,
685                                                    png_width, png_height,
686                                                    stride);
687     if (surface->status)
688         goto BAIL;
689
690     _cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface);
691     data = NULL;
692
693     _cairo_debug_check_image_surface_is_defined (surface);
694
695     status = _cairo_memory_stream_destroy (png_closure->png_data,
696                                            &mime_data,
697                                            &mime_data_length);
698     png_closure->png_data = NULL;
699     if (unlikely (status)) {
700         cairo_surface_destroy (surface);
701         surface = _cairo_surface_create_in_error (status);
702         goto BAIL;
703     }
704
705     status = cairo_surface_set_mime_data (surface,
706                                           CAIRO_MIME_TYPE_PNG,
707                                           mime_data,
708                                           mime_data_length,
709                                           free,
710                                           mime_data);
711     if (unlikely (status)) {
712         free (mime_data);
713         cairo_surface_destroy (surface);
714         surface = _cairo_surface_create_in_error (status);
715         goto BAIL;
716     }
717
718  BAIL:
719     free (row_pointers);
720     free (data);
721     if (png != NULL)
722         png_destroy_read_struct (&png, &info, NULL);
723     if (png_closure->png_data != NULL) {
724         cairo_status_t status_ignored;
725
726         status_ignored = _cairo_output_stream_destroy (png_closure->png_data);
727     }
728
729     return surface;
730 }
731
732 /**
733  * cairo_image_surface_create_from_png:
734  * @filename: name of PNG file to load
735  *
736  * Creates a new image surface and initializes the contents to the
737  * given PNG file.
738  *
739  * Return value: a new #cairo_surface_t initialized with the contents
740  * of the PNG file, or a "nil" surface if any error occurred. A nil
741  * surface can be checked for with cairo_surface_status(surface) which
742  * may return one of the following values:
743  *
744  *      %CAIRO_STATUS_NO_MEMORY
745  *      %CAIRO_STATUS_FILE_NOT_FOUND
746  *      %CAIRO_STATUS_READ_ERROR
747  *
748  * Alternatively, you can allow errors to propagate through the drawing
749  * operations and check the status on the context upon completion
750  * using cairo_status().
751  *
752  * Since: 1.0
753  **/
754 cairo_surface_t *
755 cairo_image_surface_create_from_png (const char *filename)
756 {
757     struct png_read_closure_t png_closure;
758     cairo_surface_t *surface;
759
760     png_closure.closure = fopen (filename, "rb");
761     if (png_closure.closure == NULL) {
762         cairo_status_t status;
763         switch (errno) {
764         case ENOMEM:
765             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
766             break;
767         case ENOENT:
768             status = _cairo_error (CAIRO_STATUS_FILE_NOT_FOUND);
769             break;
770         default:
771             status = _cairo_error (CAIRO_STATUS_READ_ERROR);
772             break;
773         }
774         return _cairo_surface_create_in_error (status);
775     }
776
777     png_closure.read_func = stdio_read_func;
778
779     surface = read_png (&png_closure);
780
781     fclose (png_closure.closure);
782
783     return surface;
784 }
785
786 /**
787  * cairo_image_surface_create_from_png_stream:
788  * @read_func: function called to read the data of the file
789  * @closure: data to pass to @read_func.
790  *
791  * Creates a new image surface from PNG data read incrementally
792  * via the @read_func function.
793  *
794  * Return value: a new #cairo_surface_t initialized with the contents
795  * of the PNG file or a "nil" surface if the data read is not a valid PNG image
796  * or memory could not be allocated for the operation.  A nil
797  * surface can be checked for with cairo_surface_status(surface) which
798  * may return one of the following values:
799  *
800  *      %CAIRO_STATUS_NO_MEMORY
801  *      %CAIRO_STATUS_READ_ERROR
802  *
803  * Alternatively, you can allow errors to propagate through the drawing
804  * operations and check the status on the context upon completion
805  * using cairo_status().
806  *
807  * Since: 1.0
808  **/
809 cairo_surface_t *
810 cairo_image_surface_create_from_png_stream (cairo_read_func_t   read_func,
811                                             void                *closure)
812 {
813     struct png_read_closure_t png_closure;
814
815     png_closure.read_func = read_func;
816     png_closure.closure = closure;
817
818     return read_png (&png_closure);
819 }