1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2003 University of Southern California
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.
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
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/
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.
28 * The Original Code is the cairo graphics library.
30 * The Initial Developer of the Original Code is University of Southern
34 * Carl D. Worth <cworth@cworth.org>
35 * Kristian Høgsberg <krh@redhat.com>
36 * Chris Wilson <chris@chris-wilson.co.uk>
41 #include "cairo-error-private.h"
42 #include "cairo-image-surface-private.h"
43 #include "cairo-output-stream-private.h"
44 #include "cairo-ttrace.h"
53 * @Short_Description: Reading and writing PNG images
54 * @See_Also: #cairo_surface_t
56 * The PNG functions allow reading PNG images into image surfaces, and writing
57 * any surface to a PNG file.
59 * It is a toy API. It only offers very simple support for reading and
60 * writing PNG files, which is sufficient for testing and
61 * demonstration purposes. Applications which need more control over
62 * the generated PNG file should access the pixel data directly, using
63 * cairo_image_surface_get_data() or a backend-specific access
64 * function, and process it with another library, e.g. gdk-pixbuf or
69 * CAIRO_HAS_PNG_FUNCTIONS:
71 * Defined if the PNG functions are available.
72 * This macro can be used to conditionally compile code using the cairo
78 struct png_read_closure_t {
79 cairo_read_func_t read_func;
81 cairo_output_stream_t *png_data;
85 /* Unpremultiplies data and converts native endian ARGB => RGBA bytes */
87 unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
91 for (i = 0; i < row_info->rowbytes; i += 4) {
92 uint8_t *b = &data[i];
96 memcpy (&pixel, b, sizeof (uint32_t));
97 alpha = (pixel & 0xff000000) >> 24;
99 b[0] = b[1] = b[2] = b[3] = 0;
101 b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
102 b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha;
103 b[2] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha;
109 /* Converts native endian xRGB => RGBx bytes */
111 convert_data_to_bytes (png_structp png, png_row_infop row_info, png_bytep data)
115 for (i = 0; i < row_info->rowbytes; i += 4) {
116 uint8_t *b = &data[i];
119 memcpy (&pixel, b, sizeof (uint32_t));
121 b[0] = (pixel & 0xff0000) >> 16;
122 b[1] = (pixel & 0x00ff00) >> 8;
123 b[2] = (pixel & 0x0000ff) >> 0;
128 /* Use a couple of simple error callbacks that do not print anything to
129 * stderr and rely on the user to check for errors via the #cairo_status_t
133 png_simple_error_callback (png_structp png,
134 png_const_charp error_msg)
136 cairo_status_t *error = png_get_error_ptr (png);
138 /* default to the most likely error */
139 if (*error == CAIRO_STATUS_SUCCESS)
140 *error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
142 #ifdef PNG_SETJMP_SUPPORTED
143 longjmp (png_jmpbuf (png), 1);
146 /* if we get here, then we have to choice but to abort ... */
150 png_simple_warning_callback (png_structp png,
151 png_const_charp error_msg)
153 /* png does not expect to abort and will try to tidy up and continue
154 * loading the image after a warning. So we also want to return the
155 * (incorrect?) surface.
157 * We use our own warning callback to squelch any attempts by libpng
158 * to write to stderr as we may not be in control of that output.
163 /* Starting with libpng-1.2.30, we must explicitly specify an output_flush_fn.
164 * Otherwise, we will segfault if we are writing to a stream. */
166 png_simple_output_flush_fn (png_structp png_ptr)
170 static cairo_status_t
171 write_png (cairo_surface_t *surface,
172 png_rw_ptr write_func,
175 CAIRO_TRACE_BEGIN (__func__);
177 cairo_int_status_t status;
178 cairo_image_surface_t *image;
179 cairo_image_surface_t * volatile clone;
183 png_byte **volatile rows = NULL;
188 status = _cairo_surface_acquire_source_image (surface,
192 if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
193 CAIRO_TRACE_END (__func__);
194 return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
196 else if (unlikely (status)) {
197 CAIRO_TRACE_END (__func__);
201 /* PNG complains about "Image width or height is zero in IHDR" */
202 if (image->width == 0 || image->height == 0) {
203 status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
207 /* Handle the various fallback formats (e.g. low bit-depth XServers)
208 * by coercing them to a simpler format using pixman.
210 clone = _cairo_image_surface_coerce (image);
211 status = clone->base.status;
212 if (unlikely (status))
215 rows = _cairo_malloc_ab (clone->height, sizeof (png_byte*));
216 if (unlikely (rows == NULL)) {
217 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
221 for (i = 0; i < clone->height; i++)
222 rows[i] = (png_byte *) clone->data + i * clone->stride;
224 png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status,
225 png_simple_error_callback,
226 png_simple_warning_callback);
227 if (unlikely (png == NULL)) {
228 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
232 info = png_create_info_struct (png);
233 if (unlikely (info == NULL)) {
234 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
238 #ifdef PNG_SETJMP_SUPPORTED
239 if (setjmp (png_jmpbuf (png)))
243 png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn);
245 switch (clone->format) {
246 case CAIRO_FORMAT_ARGB32:
248 if (_cairo_image_analyze_transparency (clone) == CAIRO_IMAGE_IS_OPAQUE)
249 png_color_type = PNG_COLOR_TYPE_RGB;
251 png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
253 case CAIRO_FORMAT_RGB30:
255 png_color_type = PNG_COLOR_TYPE_RGB;
257 case CAIRO_FORMAT_RGB24:
259 png_color_type = PNG_COLOR_TYPE_RGB;
261 case CAIRO_FORMAT_A8:
263 png_color_type = PNG_COLOR_TYPE_GRAY;
265 case CAIRO_FORMAT_A1:
267 png_color_type = PNG_COLOR_TYPE_GRAY;
268 #ifndef WORDS_BIGENDIAN
269 png_set_packswap (png);
272 case CAIRO_FORMAT_INVALID:
273 case CAIRO_FORMAT_RGB16_565:
275 status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
279 png_set_IHDR (png, info,
284 PNG_COMPRESSION_TYPE_DEFAULT,
285 PNG_FILTER_TYPE_DEFAULT);
287 white.gray = (1 << bpc) - 1;
288 white.red = white.blue = white.green = white.gray;
289 png_set_bKGD (png, info, &white);
291 if (0) { /* XXX extract meta-data from surface (i.e. creation date) */
294 png_convert_from_time_t (&pt, time (NULL));
295 png_set_tIME (png, info, &pt);
298 /* We have to call png_write_info() before setting up the write
299 * transformation, since it stores data internally in 'png'
300 * that is needed for the write transformation functions to work.
302 png_write_info (png, info);
304 if (png_color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
305 png_set_write_user_transform_fn (png, unpremultiply_data);
306 } else if (png_color_type == PNG_COLOR_TYPE_RGB) {
307 png_set_write_user_transform_fn (png, convert_data_to_bytes);
308 png_set_filler (png, 0, PNG_FILLER_AFTER);
311 png_write_image (png, rows);
312 png_write_end (png, info);
315 png_destroy_write_struct (&png, &info);
319 cairo_surface_destroy (&clone->base);
321 _cairo_surface_release_source_image (surface, image, image_extra);
323 CAIRO_TRACE_END (__func__);
328 stdio_write_func (png_structp png, png_bytep data, png_size_t size)
332 fp = png_get_io_ptr (png);
334 size_t ret = fwrite (data, 1, size, fp);
337 if (size && ferror (fp)) {
338 cairo_status_t *error = png_get_error_ptr (png);
339 if (*error == CAIRO_STATUS_SUCCESS)
340 *error = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
341 png_error (png, NULL);
347 * cairo_surface_write_to_png:
348 * @surface: a #cairo_surface_t with pixel contents
349 * @filename: the name of a file to write to
351 * Writes the contents of @surface to a new file @filename as a PNG
354 * Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
355 * successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY if memory could not
356 * be allocated for the operation or
357 * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
358 * pixel contents, or %CAIRO_STATUS_WRITE_ERROR if an I/O error occurs
359 * while attempting to write the file.
364 cairo_surface_write_to_png (cairo_surface_t *surface,
365 const char *filename)
368 cairo_status_t status;
371 return surface->status;
373 if (surface->finished)
374 return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
376 fp = fopen (filename, "wb");
380 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
382 return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
386 status = write_png (surface, stdio_write_func, fp);
388 if (fclose (fp) && status == CAIRO_STATUS_SUCCESS)
389 status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
394 struct png_write_closure_t {
395 cairo_write_func_t write_func;
400 stream_write_func (png_structp png, png_bytep data, png_size_t size)
402 cairo_status_t status;
403 struct png_write_closure_t *png_closure;
405 png_closure = png_get_io_ptr (png);
406 status = png_closure->write_func (png_closure->closure, data, size);
407 if (unlikely (status)) {
408 cairo_status_t *error = png_get_error_ptr (png);
409 if (*error == CAIRO_STATUS_SUCCESS)
411 png_error (png, NULL);
416 * cairo_surface_write_to_png_stream:
417 * @surface: a #cairo_surface_t with pixel contents
418 * @write_func: a #cairo_write_func_t
419 * @closure: closure data for the write function
421 * Writes the image surface to the write function.
423 * Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
424 * successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY is returned if
425 * memory could not be allocated for the operation,
426 * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
432 cairo_surface_write_to_png_stream (cairo_surface_t *surface,
433 cairo_write_func_t write_func,
436 CAIRO_TRACE_BEGIN (__func__);
437 struct png_write_closure_t png_closure;
439 if (surface->status) {
440 CAIRO_TRACE_END (__func__);
441 return surface->status;
444 if (surface->finished) {
445 CAIRO_TRACE_END (__func__);
446 return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
449 png_closure.write_func = write_func;
450 png_closure.closure = closure;
452 CAIRO_TRACE_END (__func__);
453 return write_png (surface, stream_write_func, &png_closure);
455 slim_hidden_def (cairo_surface_write_to_png_stream);
458 multiply_alpha (int alpha, int color)
460 int temp = (alpha * color) + 0x80;
461 return ((temp + (temp >> 8)) >> 8);
464 /* Premultiplies data and converts RGBA bytes => native endian */
466 premultiply_data (png_structp png,
467 png_row_infop row_info,
472 for (i = 0; i < row_info->rowbytes; i += 4) {
473 uint8_t *base = &data[i];
474 uint8_t alpha = base[3];
480 uint8_t red = base[0];
481 uint8_t green = base[1];
482 uint8_t blue = base[2];
485 red = multiply_alpha (alpha, red);
486 green = multiply_alpha (alpha, green);
487 blue = multiply_alpha (alpha, blue);
489 p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
491 memcpy (base, &p, sizeof (uint32_t));
495 /* Converts RGBx bytes to native endian xRGB */
497 convert_bytes_to_data (png_structp png, png_row_infop row_info, png_bytep data)
501 for (i = 0; i < row_info->rowbytes; i += 4) {
502 uint8_t *base = &data[i];
503 uint8_t red = base[0];
504 uint8_t green = base[1];
505 uint8_t blue = base[2];
508 pixel = (0xff << 24) | (red << 16) | (green << 8) | (blue << 0);
509 memcpy (base, &pixel, sizeof (uint32_t));
513 static cairo_status_t
514 stdio_read_func (void *closure, unsigned char *data, unsigned int size)
516 FILE *file = closure;
521 ret = fread (data, 1, size, file);
525 if (size && (feof (file) || ferror (file)))
526 return _cairo_error (CAIRO_STATUS_READ_ERROR);
529 return CAIRO_STATUS_SUCCESS;
533 stream_read_func (png_structp png, png_bytep data, png_size_t size)
535 cairo_status_t status;
536 struct png_read_closure_t *png_closure;
538 png_closure = png_get_io_ptr (png);
539 status = png_closure->read_func (png_closure->closure, data, size);
540 if (unlikely (status)) {
541 cairo_status_t *error = png_get_error_ptr (png);
542 if (*error == CAIRO_STATUS_SUCCESS)
544 png_error (png, NULL);
547 _cairo_output_stream_write (png_closure->png_data, data, size);
550 static cairo_surface_t *
551 read_png (struct png_read_closure_t *png_closure)
553 cairo_surface_t *surface;
554 png_struct *png = NULL;
556 png_byte *data = NULL;
557 png_byte **row_pointers = NULL;
558 png_uint_32 png_width, png_height;
559 int depth, color_type, interlace, stride;
561 cairo_format_t format;
562 cairo_status_t status;
563 unsigned char *mime_data;
564 unsigned long mime_data_length;
566 png_closure->png_data = _cairo_memory_stream_create ();
568 /* XXX: Perhaps we'll want some other error handlers? */
569 png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
571 png_simple_error_callback,
572 png_simple_warning_callback);
573 if (unlikely (png == NULL)) {
574 surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
578 info = png_create_info_struct (png);
579 if (unlikely (info == NULL)) {
580 surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
584 png_set_read_fn (png, png_closure, stream_read_func);
586 status = CAIRO_STATUS_SUCCESS;
587 #ifdef PNG_SETJMP_SUPPORTED
588 if (setjmp (png_jmpbuf (png))) {
589 surface = _cairo_surface_create_in_error (status);
594 png_read_info (png, info);
596 png_get_IHDR (png, info,
597 &png_width, &png_height, &depth,
598 &color_type, &interlace, NULL, NULL);
599 if (unlikely (status)) { /* catch any early warnings */
600 surface = _cairo_surface_create_in_error (status);
604 /* convert palette/gray image to rgb */
605 if (color_type == PNG_COLOR_TYPE_PALETTE)
606 png_set_palette_to_rgb (png);
608 /* expand gray bit depth if needed */
609 if (color_type == PNG_COLOR_TYPE_GRAY) {
610 #if PNG_LIBPNG_VER >= 10209
611 png_set_expand_gray_1_2_4_to_8 (png);
613 png_set_gray_1_2_4_to_8 (png);
617 /* transform transparency to alpha */
618 if (png_get_valid (png, info, PNG_INFO_tRNS))
619 png_set_tRNS_to_alpha (png);
622 png_set_strip_16 (png);
625 png_set_packing (png);
627 /* convert grayscale to RGB */
628 if (color_type == PNG_COLOR_TYPE_GRAY ||
629 color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
631 png_set_gray_to_rgb (png);
634 if (interlace != PNG_INTERLACE_NONE)
635 png_set_interlace_handling (png);
637 png_set_filler (png, 0xff, PNG_FILLER_AFTER);
639 /* recheck header after setting EXPAND options */
640 png_read_update_info (png, info);
641 png_get_IHDR (png, info,
642 &png_width, &png_height, &depth,
643 &color_type, &interlace, NULL, NULL);
645 ! (color_type == PNG_COLOR_TYPE_RGB ||
646 color_type == PNG_COLOR_TYPE_RGB_ALPHA))
648 surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_READ_ERROR));
652 switch (color_type) {
655 /* fall-through just in case ;-) */
657 case PNG_COLOR_TYPE_RGB_ALPHA:
658 format = CAIRO_FORMAT_ARGB32;
659 png_set_read_user_transform_fn (png, premultiply_data);
662 case PNG_COLOR_TYPE_RGB:
663 format = CAIRO_FORMAT_RGB24;
664 png_set_read_user_transform_fn (png, convert_bytes_to_data);
668 stride = cairo_format_stride_for_width (format, png_width);
670 surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
674 data = _cairo_malloc_ab (png_height, stride);
675 if (unlikely (data == NULL)) {
676 surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
680 row_pointers = _cairo_malloc_ab (png_height, sizeof (char *));
681 if (unlikely (row_pointers == NULL)) {
682 surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
686 for (i = 0; i < png_height; i++)
687 row_pointers[i] = &data[i * stride];
689 png_read_image (png, row_pointers);
690 png_read_end (png, info);
692 if (unlikely (status)) { /* catch any late warnings - probably hit an error already */
693 surface = _cairo_surface_create_in_error (status);
697 surface = cairo_image_surface_create_for_data (data, format,
698 png_width, png_height,
703 _cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface);
706 _cairo_debug_check_image_surface_is_defined (surface);
708 status = _cairo_memory_stream_destroy (png_closure->png_data,
711 png_closure->png_data = NULL;
712 if (unlikely (status)) {
713 cairo_surface_destroy (surface);
714 surface = _cairo_surface_create_in_error (status);
718 status = cairo_surface_set_mime_data (surface,
724 if (unlikely (status)) {
726 cairo_surface_destroy (surface);
727 surface = _cairo_surface_create_in_error (status);
735 png_destroy_read_struct (&png, &info, NULL);
736 if (png_closure->png_data != NULL) {
737 cairo_status_t status_ignored;
739 status_ignored = _cairo_output_stream_destroy (png_closure->png_data);
746 * cairo_image_surface_create_from_png:
747 * @filename: name of PNG file to load
749 * Creates a new image surface and initializes the contents to the
752 * Return value: a new #cairo_surface_t initialized with the contents
753 * of the PNG file, or a "nil" surface if any error occurred. A nil
754 * surface can be checked for with cairo_surface_status(surface) which
755 * may return one of the following values:
757 * %CAIRO_STATUS_NO_MEMORY
758 * %CAIRO_STATUS_FILE_NOT_FOUND
759 * %CAIRO_STATUS_READ_ERROR
761 * Alternatively, you can allow errors to propagate through the drawing
762 * operations and check the status on the context upon completion
763 * using cairo_status().
768 cairo_image_surface_create_from_png (const char *filename)
770 struct png_read_closure_t png_closure;
771 cairo_surface_t *surface;
773 png_closure.closure = fopen (filename, "rb");
774 if (png_closure.closure == NULL) {
775 cairo_status_t status;
778 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
781 status = _cairo_error (CAIRO_STATUS_FILE_NOT_FOUND);
784 status = _cairo_error (CAIRO_STATUS_READ_ERROR);
787 return _cairo_surface_create_in_error (status);
790 png_closure.read_func = stdio_read_func;
792 surface = read_png (&png_closure);
794 fclose (png_closure.closure);
800 * cairo_image_surface_create_from_png_stream:
801 * @read_func: function called to read the data of the file
802 * @closure: data to pass to @read_func.
804 * Creates a new image surface from PNG data read incrementally
805 * via the @read_func function.
807 * Return value: a new #cairo_surface_t initialized with the contents
808 * of the PNG file or a "nil" surface if the data read is not a valid PNG image
809 * or memory could not be allocated for the operation. A nil
810 * surface can be checked for with cairo_surface_status(surface) which
811 * may return one of the following values:
813 * %CAIRO_STATUS_NO_MEMORY
814 * %CAIRO_STATUS_READ_ERROR
816 * Alternatively, you can allow errors to propagate through the drawing
817 * operations and check the status on the context upon completion
818 * using cairo_status().
823 cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func,
826 struct png_read_closure_t png_closure;
828 png_closure.read_func = read_func;
829 png_closure.closure = closure;
831 return read_png (&png_closure);