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
66735
unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data)
87
{
88
    unsigned int i;
89

            
90
27444182
    for (i = 0; i < row_info->rowbytes; i += 4) {
91
27377447
        uint8_t *b = &data[i];
92
        uint32_t pixel;
93
        uint8_t  alpha;
94

            
95
27377447
	memcpy (&pixel, b, sizeof (uint32_t));
96
27377447
	alpha = (pixel & 0xff000000) >> 24;
97
27377447
        if (alpha == 0) {
98
1779647
	    b[0] = b[1] = b[2] = b[3] = 0;
99
	} else {
100
25597800
            b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha;
101
25597800
            b[1] = (((pixel & 0x00ff00) >>  8) * 255 + alpha / 2) / alpha;
102
25597800
            b[2] = (((pixel & 0x0000ff) >>  0) * 255 + alpha / 2) / alpha;
103
25597800
	    b[3] = alpha;
104
	}
105
    }
106
66735
}
107

            
108
static uint16_t f_to_u16(float val)
109
{
110
    if (val < 0)
111
	return 0;
112
    else if (val > 1)
113
	return 65535;
114
    else
115
	return (uint16_t)(val * 65535.f);
116
}
117

            
118
static void
119
unpremultiply_float (float *f, uint16_t *d16, unsigned width)
120
{
121
    unsigned int i;
122

            
123
    for (i = 0; i < width; i++) {
124
	float r, g, b, a;
125

            
126
	r = *f++;
127
	g = *f++;
128
	b = *f++;
129
	a = *f++;
130

            
131
	if (a > 0) {
132
	    *d16++ = f_to_u16(r / a);
133
	    *d16++ = f_to_u16(g / a);
134
	    *d16++ = f_to_u16(b / a);
135
	    *d16++ = f_to_u16(a);
136
	} else {
137
	    *d16++ = 0;
138
	    *d16++ = 0;
139
	    *d16++ = 0;
140
	    *d16++ = 0;
141
	}
142
    }
143
}
144

            
145
static void
146
6
premultiply_float (float *f, const uint16_t *d16, unsigned int width)
147
{
148
6
    unsigned int i = width;
149

            
150
    /* Convert d16 in place back to float */
151
18
    while (i--) {
152
12
	float a = d16[i * 4 + 3] / 65535.f;
153

            
154
12
	f[i * 4 + 3] = a;
155
12
	f[i * 4 + 2] = (float)d16[i * 4 + 2] / 65535.f * a;
156
12
	f[i * 4 + 1] = (float)d16[i * 4 + 1] / 65535.f * a;
157
12
	f[i * 4] = (float)d16[i * 4] / 65535.f * a;
158
    }
159
6
}
160

            
161
static void convert_u16_to_float (float *f, const uint16_t *d16, unsigned int width)
162
{
163
    /* Convert d16 in place back to float */
164
    unsigned int i = width;
165

            
166
    while (i--) {
167
	f[i * 3 + 2] = (float)d16[i * 4 + 2] / 65535.f;
168
	f[i * 3 + 1] = (float)d16[i * 4 + 1] / 65535.f;
169
	f[i * 3] = (float)d16[i * 4] / 65535.f;
170
    }
171
}
172

            
173
static void
174
convert_float_to_u16 (float *f, uint16_t *d16, unsigned int width)
175
{
176
    unsigned int i;
177

            
178
    for (i = 0; i < width; i++) {
179
	*d16++ = f_to_u16(*f++);
180
	*d16++ = f_to_u16(*f++);
181
	*d16++ = f_to_u16(*f++);
182
	*d16++ = 0;
183
    }
184
}
185

            
186
/* Converts native endian xRGB => RGBx bytes */
187
static void
188
197868
convert_data_to_bytes (png_structp png, png_row_infop row_info, png_bytep data)
189
{
190
    unsigned int i;
191

            
192
78656032
    for (i = 0; i < row_info->rowbytes; i += 4) {
193
78458164
        uint8_t *b = &data[i];
194
        uint32_t pixel;
195

            
196
78458164
	memcpy (&pixel, b, sizeof (uint32_t));
197

            
198
78458164
	b[0] = (pixel & 0xff0000) >> 16;
199
78458164
	b[1] = (pixel & 0x00ff00) >>  8;
200
78458164
	b[2] = (pixel & 0x0000ff) >>  0;
201
78458164
	b[3] = 0;
202
    }
203
197868
}
204

            
205
/* Use a couple of simple error callbacks that do not print anything to
206
 * stderr and rely on the user to check for errors via the #cairo_status_t
207
 * return.
208
 */
209
static void
210
5
png_simple_error_callback (png_structp png,
211
	                   png_const_charp error_msg)
212
{
213
5
    cairo_status_t *error = png_get_error_ptr (png);
214

            
215
    /* default to the most likely error */
216
5
    if (*error == CAIRO_STATUS_SUCCESS)
217
1
	*error = _cairo_error (CAIRO_STATUS_PNG_ERROR);
218

            
219
#ifdef PNG_SETJMP_SUPPORTED
220
5
    longjmp (png_jmpbuf (png), 1);
221
#endif
222

            
223
    /* if we get here, then we have to choice but to abort ... */
224
}
225

            
226
static void
227
png_simple_warning_callback (png_structp png,
228
	                     png_const_charp error_msg)
229
{
230
    /* png does not expect to abort and will try to tidy up and continue
231
     * loading the image after a warning. So we also want to return the
232
     * (incorrect?) surface.
233
     *
234
     * We use our own warning callback to squelch any attempts by libpng
235
     * to write to stderr as we may not be in control of that output.
236
     */
237
}
238

            
239

            
240
/* Starting with libpng-1.2.30, we must explicitly specify an output_flush_fn.
241
 * Otherwise, we will segfault if we are writing to a stream. */
242
static void
243
png_simple_output_flush_fn (png_structp png_ptr)
244
{
245
}
246

            
247
static cairo_status_t
248
2052
write_png (cairo_surface_t	*surface,
249
	   png_rw_ptr		write_func,
250
	   void			*closure)
251
{
252
    int i;
253
    cairo_int_status_t status;
254
    cairo_image_surface_t *image;
255
    cairo_image_surface_t * volatile clone;
256
    void *image_extra;
257
    png_struct *png;
258
    png_info *info;
259
2052
    png_byte **volatile rows = NULL;
260
    png_color_16 white;
261
    int png_color_type;
262
    int bpc;
263
2052
    unsigned char *volatile u16_copy = NULL;
264

            
265
2052
    status = _cairo_surface_acquire_source_image (surface,
266
						  &image,
267
						  &image_extra);
268

            
269
2052
    if (status == CAIRO_INT_STATUS_UNSUPPORTED)
270
	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
271
2052
    else if (unlikely (status))
272
        return status;
273

            
274
    /* PNG complains about "Image width or height is zero in IHDR" */
275
2052
    if (image->width == 0 || image->height == 0) {
276
	status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
277
	goto BAIL1;
278
    }
279

            
280
    /* Don't coerce to a lower resolution format */
281
2052
    if (image->format == CAIRO_FORMAT_RGB96F ||
282
2052
        image->format == CAIRO_FORMAT_RGBA128F) {
283
	u16_copy = _cairo_malloc_ab (image->width * 8, image->height);
284
	if (!u16_copy) {
285
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
286
	    goto BAIL1;
287
	}
288
	clone = (cairo_image_surface_t *)cairo_surface_reference (&image->base);
289
    } else {
290
	  /* Handle the various fallback formats (e.g. low bit-depth XServers)
291
	  * by coercing them to a simpler format using pixman.
292
	  */
293
2052
	  clone = _cairo_image_surface_coerce (image);
294
2052
	  status = clone->base.status;
295
    }
296
2052
    if (unlikely (status))
297
        goto BAIL1;
298

            
299
2052
    rows = _cairo_malloc_ab (clone->height, sizeof (png_byte*));
300
2052
    if (unlikely (rows == NULL)) {
301
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
302
	goto BAIL2;
303
    }
304

            
305
2052
    if (!u16_copy) {
306
266659
	for (i = 0; i < clone->height; i++)
307
264607
	    rows[i] = (png_byte *)clone->data + i * clone->stride;
308
    } else {
309
	for (i = 0; i < clone->height; i++) {
310
	    float *float_line = (float *)&clone->data[i * clone->stride];
311
	    uint16_t *u16_line = (uint16_t *)&u16_copy[i * clone->width * 8];
312

            
313
	    if (image->format == CAIRO_FORMAT_RGBA128F)
314
		unpremultiply_float (float_line, u16_line, clone->width);
315
	    else
316
		convert_float_to_u16 (float_line, u16_line, clone->width);
317

            
318
	    rows[i] = (png_byte *)u16_line;
319
	}
320
    }
321

            
322
2052
    png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status,
323
	                           png_simple_error_callback,
324
	                           png_simple_warning_callback);
325
2052
    if (unlikely (png == NULL)) {
326
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
327
	goto BAIL3;
328
    }
329

            
330
2052
    info = png_create_info_struct (png);
331
2052
    if (unlikely (info == NULL)) {
332
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
333
	goto BAIL4;
334
    }
335

            
336
#ifdef PNG_SETJMP_SUPPORTED
337
2052
    if (setjmp (png_jmpbuf (png)))
338
2
	goto BAIL4;
339
#endif
340

            
341
2052
    png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn);
342

            
343
2052
    switch (clone->format) {
344
931
    case CAIRO_FORMAT_ARGB32:
345
931
	bpc = 8;
346
931
	if (_cairo_image_analyze_transparency (clone) == CAIRO_IMAGE_IS_OPAQUE)
347
457
	    png_color_type = PNG_COLOR_TYPE_RGB;
348
	else
349
474
	    png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
350
931
	break;
351
    case CAIRO_FORMAT_RGB30:
352
	bpc = 10;
353
	png_color_type = PNG_COLOR_TYPE_RGB;
354
	break;
355
1121
    case CAIRO_FORMAT_RGB24:
356
1121
	bpc = 8;
357
1121
	png_color_type = PNG_COLOR_TYPE_RGB;
358
1121
	break;
359
    case CAIRO_FORMAT_A8:
360
	bpc = 8;
361
	png_color_type = PNG_COLOR_TYPE_GRAY;
362
	break;
363
    case CAIRO_FORMAT_A1:
364
	bpc = 1;
365
	png_color_type = PNG_COLOR_TYPE_GRAY;
366
#ifndef WORDS_BIGENDIAN
367
	png_set_packswap (png);
368
#endif
369
	break;
370
    case CAIRO_FORMAT_RGB96F:
371
	bpc = 16;
372
	png_color_type = PNG_COLOR_TYPE_RGB;
373
	break;
374
    case CAIRO_FORMAT_RGBA128F:
375
	bpc = 16;
376
	png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
377
	break;
378
    case CAIRO_FORMAT_INVALID:
379
    case CAIRO_FORMAT_RGB16_565:
380
    default:
381
	status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
382
	goto BAIL4;
383
    }
384

            
385
2052
    png_set_IHDR (png, info,
386
2052
		  clone->width,
387
2052
		  clone->height, bpc,
388
		  png_color_type,
389
		  PNG_INTERLACE_NONE,
390
		  PNG_COMPRESSION_TYPE_DEFAULT,
391
		  PNG_FILTER_TYPE_DEFAULT);
392

            
393
2052
    white.gray = (1 << bpc) - 1;
394
2052
    white.red = white.blue = white.green = white.gray;
395
2052
    png_set_bKGD (png, info, &white);
396

            
397
    if (0) { /* XXX extract meta-data from surface (i.e. creation date) */
398
	png_time pt;
399

            
400
	png_convert_from_time_t (&pt, time (NULL));
401
	png_set_tIME (png, info, &pt);
402
    }
403

            
404
    /* We have to call png_write_info() before setting up the write
405
     * transformation, since it stores data internally in 'png'
406
     * that is needed for the write transformation functions to work.
407
     */
408
2052
    png_write_info (png, info);
409

            
410
#ifndef WORDS_BIGENDIAN
411
    /* libpng treats 16-bit data as big-endian by default. Swapping the
412
     * byte-order on little endian ensures the native-endian data can be
413
     * provided to png_write_image. This does not affect 8-bit data.
414
     */
415
2050
    png_set_swap (png);
416
#endif
417

            
418
2050
    if (png_color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
419
474
	if (clone->format != CAIRO_FORMAT_RGBA128F)
420
474
	    png_set_write_user_transform_fn (png, unpremultiply_data);
421
1576
    } else if (png_color_type == PNG_COLOR_TYPE_RGB) {
422
1576
	if (clone->format != CAIRO_FORMAT_RGB96F)
423
1576
	    png_set_write_user_transform_fn (png, convert_data_to_bytes);
424
1576
	png_set_filler (png, 0, PNG_FILLER_AFTER);
425
    }
426

            
427
2050
    png_write_image (png, rows);
428
2050
    png_write_end (png, info);
429

            
430
2052
BAIL4:
431
2052
    png_destroy_write_struct (&png, &info);
432
2052
BAIL3:
433
2052
    free (rows);
434
2052
BAIL2:
435
2052
    cairo_surface_destroy (&clone->base);
436
2052
    free (u16_copy);
437
2052
BAIL1:
438
2052
    _cairo_surface_release_source_image (surface, image, image_extra);
439

            
440
2052
    return status;
441
}
442

            
443
static void
444
29391
stdio_write_func (png_structp png, png_bytep data, png_size_t size)
445
{
446
    FILE *fp;
447

            
448
29391
    fp = png_get_io_ptr (png);
449
58782
    while (size) {
450
29391
	size_t ret = fwrite (data, 1, size, fp);
451
29391
	size -= ret;
452
29391
	data += ret;
453
29391
	if (size && ferror (fp)) {
454
	    cairo_status_t *error = png_get_error_ptr (png);
455
	    if (*error == CAIRO_STATUS_SUCCESS)
456
		*error = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
457
	    png_error (png, NULL);
458
	}
459
    }
460
29391
}
461

            
462
/**
463
 * cairo_surface_write_to_png:
464
 * @surface: a #cairo_surface_t with pixel contents
465
 * @filename: the name of a file to write to; on Windows this filename
466
 *   is encoded in UTF-8.
467
 *
468
 * Writes the contents of @surface to a new file @filename as a PNG
469
 * image.
470
 *
471
 * Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
472
 * successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY if memory could not
473
 * be allocated for the operation or
474
 * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
475
 * pixel contents, or %CAIRO_STATUS_WRITE_ERROR if an I/O error occurs
476
 * while attempting to write the file, or %CAIRO_STATUS_PNG_ERROR if libpng
477
 * returned an error.
478
 *
479
 * Since: 1.0
480
 **/
481
cairo_status_t
482
2049
cairo_surface_write_to_png (cairo_surface_t	*surface,
483
			    const char		*filename)
484
{
485
    FILE *fp;
486
    cairo_status_t status;
487

            
488
2049
    if (surface->status)
489
1
	return surface->status;
490

            
491
2048
    if (surface->finished)
492
3
	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
493

            
494
2045
    status = _cairo_fopen (filename, "wb", &fp);
495

            
496
2045
    if (status != CAIRO_STATUS_SUCCESS)
497
	return _cairo_error (status);
498

            
499
2045
    if (fp == NULL) {
500
	switch (errno) {
501
	case ENOMEM:
502
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
503
	default:
504
	    return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
505
	}
506
    }
507

            
508
2045
    status = write_png (surface, stdio_write_func, fp);
509

            
510
2045
    if (fclose (fp) && status == CAIRO_STATUS_SUCCESS)
511
	status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
512

            
513
2045
    return status;
514
}
515

            
516
struct png_write_closure_t {
517
    cairo_write_func_t		 write_func;
518
    void			*closure;
519
};
520

            
521
static void
522
62
stream_write_func (png_structp png, png_bytep data, png_size_t size)
523
{
524
    cairo_status_t status;
525
    struct png_write_closure_t *png_closure;
526

            
527
62
    png_closure = png_get_io_ptr (png);
528
62
    status = png_closure->write_func (png_closure->closure, data, size);
529
62
    if (unlikely (status)) {
530
2
	cairo_status_t *error = png_get_error_ptr (png);
531
2
	if (*error == CAIRO_STATUS_SUCCESS)
532
2
	    *error = status;
533
2
	png_error (png, NULL);
534
    }
535
60
}
536

            
537
/**
538
 * cairo_surface_write_to_png_stream:
539
 * @surface: a #cairo_surface_t with pixel contents
540
 * @write_func: a #cairo_write_func_t
541
 * @closure: closure data for the write function
542
 *
543
 * Writes the image surface to the write function.
544
 *
545
 * Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
546
 * successfully.  Otherwise, %CAIRO_STATUS_NO_MEMORY is returned if
547
 * memory could not be allocated for the operation,
548
 * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
549
 * pixel contents, or %CAIRO_STATUS_PNG_ERROR if libpng
550
 * returned an error.
551
 *
552
 * Since: 1.0
553
 **/
554
cairo_status_t
555
11
cairo_surface_write_to_png_stream (cairo_surface_t	*surface,
556
				   cairo_write_func_t	write_func,
557
				   void			*closure)
558
{
559
    struct png_write_closure_t png_closure;
560

            
561
11
    if (surface->status)
562
1
	return surface->status;
563

            
564
10
    if (surface->finished)
565
3
	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
566

            
567
7
    png_closure.write_func = write_func;
568
7
    png_closure.closure = closure;
569

            
570
7
    return write_png (surface, stream_write_func, &png_closure);
571
}
572

            
573
static inline int
574
5187711
multiply_alpha (int alpha, int color)
575
{
576
5187711
    int temp = (alpha * color) + 0x80;
577
5187711
    return ((temp + (temp >> 8)) >> 8);
578
}
579

            
580
/* Premultiplies data and converts RGBA bytes => native endian */
581
static void
582
32223
premultiply_data (png_structp   png,
583
                  png_row_infop row_info,
584
                  png_bytep     data)
585
{
586
    unsigned int i;
587

            
588
10531268
    for (i = 0; i < row_info->rowbytes; i += 4) {
589
10499045
	uint8_t *base  = &data[i];
590
10499045
	uint8_t  alpha = base[3];
591
	uint32_t p;
592

            
593
10499045
	if (alpha == 0) {
594
2439085
	    p = 0;
595
	} else {
596
8059960
	    uint8_t  red   = base[0];
597
8059960
	    uint8_t  green = base[1];
598
8059960
	    uint8_t  blue  = base[2];
599

            
600
8059960
	    if (alpha != 0xff) {
601
1729237
		red   = multiply_alpha (alpha, red);
602
1729237
		green = multiply_alpha (alpha, green);
603
1729237
		blue  = multiply_alpha (alpha, blue);
604
	    }
605
8059960
	    p = ((uint32_t)alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
606
	}
607
10499045
	memcpy (base, &p, sizeof (uint32_t));
608
    }
609
32223
}
610

            
611
/* Converts RGBx bytes to native endian xRGB */
612
static void
613
212262
convert_bytes_to_data (png_structp png, png_row_infop row_info, png_bytep data)
614
{
615
    unsigned int i;
616

            
617
85929883
    for (i = 0; i < row_info->rowbytes; i += 4) {
618
85717621
	uint8_t *base  = &data[i];
619
85717621
	uint8_t  red   = base[0];
620
85717621
	uint8_t  green = base[1];
621
85717621
	uint8_t  blue  = base[2];
622
	uint32_t pixel;
623

            
624
85717621
	pixel = (0xffu << 24) | (red << 16) | (green << 8) | (blue << 0);
625
85717621
	memcpy (base, &pixel, sizeof (uint32_t));
626
    }
627
212262
}
628

            
629
static cairo_status_t
630
29778
stdio_read_func (void *closure, unsigned char *data, unsigned int size)
631
{
632
29778
    FILE *file = closure;
633

            
634
59556
    while (size) {
635
	size_t ret;
636

            
637
29778
	ret = fread (data, 1, size, file);
638
29778
	size -= ret;
639
29778
	data += ret;
640

            
641
29778
	if (size && (feof (file) || ferror (file)))
642
	    return _cairo_error (CAIRO_STATUS_READ_ERROR);
643
    }
644

            
645
29778
    return CAIRO_STATUS_SUCCESS;
646
}
647

            
648
static void
649
30006
stream_read_func (png_structp png, png_bytep data, png_size_t size)
650
{
651
    cairo_status_t status;
652
    struct png_read_closure_t *png_closure;
653

            
654
30006
    png_closure = png_get_io_ptr (png);
655
30006
    status = png_closure->read_func (png_closure->closure, data, size);
656
30006
    if (unlikely (status)) {
657
2
	cairo_status_t *error = png_get_error_ptr (png);
658
2
	if (*error == CAIRO_STATUS_SUCCESS)
659
2
	    *error = status;
660
2
	png_error (png, NULL);
661
    }
662

            
663
30004
    _cairo_output_stream_write (png_closure->png_data, data, size);
664
30004
}
665

            
666
static cairo_surface_t *
667
1740
read_png (struct png_read_closure_t *png_closure)
668
{
669
    cairo_surface_t * volatile surface;
670
1740
    png_struct *png = NULL;
671
    png_info *info;
672
1740
    png_byte * volatile data = NULL;
673
1740
    png_byte ** volatile row_pointers = NULL;
674
    png_uint_32 png_width, png_height;
675
    int depth, color_type, interlace, stride;
676
    unsigned int i;
677
    cairo_format_t format;
678
    cairo_status_t status;
679
    unsigned char *mime_data;
680
    unsigned long mime_data_length;
681

            
682
1740
    png_closure->png_data = _cairo_memory_stream_create ();
683

            
684
    /* XXX: Perhaps we'll want some other error handlers? */
685
1740
    png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
686
                                  &status,
687
	                          png_simple_error_callback,
688
	                          png_simple_warning_callback);
689
1740
    if (unlikely (png == NULL)) {
690
	surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
691
	goto BAIL;
692
    }
693

            
694
1740
    info = png_create_info_struct (png);
695
1740
    if (unlikely (info == NULL)) {
696
	surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
697
	goto BAIL;
698
    }
699

            
700
1740
    png_set_read_fn (png, png_closure, stream_read_func);
701

            
702
1740
    status = CAIRO_STATUS_SUCCESS;
703
#ifdef PNG_SETJMP_SUPPORTED
704
1740
    if (setjmp (png_jmpbuf (png))) {
705
3
	surface = _cairo_surface_create_in_error (status);
706
3
	goto BAIL;
707
    }
708
#endif
709

            
710
1740
    png_read_info (png, info);
711

            
712
#ifndef WORDS_BIGENDIAN
713
    /* libpng treats 16-bit data as big-endian by default. Swapping the
714
     * byte-order on little endian ensures the native-endian data can be
715
     * provided to png_read_image. This does not affect 8-bit data.
716
     */
717
1737
    png_set_swap (png);
718
#endif
719

            
720
1737
    png_get_IHDR (png, info,
721
                  &png_width, &png_height, &depth,
722
                  &color_type, &interlace, NULL, NULL);
723
1737
    if (unlikely (status)) { /* catch any early warnings */
724
	surface = _cairo_surface_create_in_error (status);
725
	goto BAIL;
726
    }
727

            
728
    /* convert palette/gray image to rgb */
729
1737
    if (color_type == PNG_COLOR_TYPE_PALETTE)
730
2
        png_set_palette_to_rgb (png);
731

            
732
    /* expand gray bit depth if needed */
733
1737
    if (color_type == PNG_COLOR_TYPE_GRAY)
734
1
        png_set_expand_gray_1_2_4_to_8 (png);
735

            
736
    /* transform transparency to alpha */
737
1737
    if (png_get_valid (png, info, PNG_INFO_tRNS))
738
1
        png_set_tRNS_to_alpha (png);
739

            
740
1737
    if (depth < 8)
741
2
        png_set_packing (png);
742

            
743
    /* convert grayscale to RGB */
744
1737
    if (color_type == PNG_COLOR_TYPE_GRAY ||
745
1736
	color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
746
    {
747
2
	png_set_gray_to_rgb (png);
748
    }
749

            
750
1737
    if (interlace != PNG_INTERLACE_NONE)
751
        png_set_interlace_handling (png);
752

            
753
1737
    png_set_filler (png, 0xff, PNG_FILLER_AFTER);
754

            
755
    /* recheck header after setting EXPAND options */
756
1737
    png_read_update_info (png, info);
757
1737
    png_get_IHDR (png, info,
758
                  &png_width, &png_height, &depth,
759
                  &color_type, &interlace, NULL, NULL);
760
1737
    if ((depth != 8 && depth != 16) ||
761
1737
	! (color_type == PNG_COLOR_TYPE_RGB ||
762
384
	   color_type == PNG_COLOR_TYPE_RGB_ALPHA))
763
    {
764
	surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_READ_ERROR));
765
	goto BAIL;
766
    }
767

            
768
1737
    switch (color_type) {
769
	default:
770
	    ASSERT_NOT_REACHED;
771
	    /* fall-through just in case ;-) */
772

            
773
	case PNG_COLOR_TYPE_RGB_ALPHA:
774
384
	    if (depth == 8) {
775
381
		format = CAIRO_FORMAT_ARGB32;
776
381
		png_set_read_user_transform_fn (png, premultiply_data);
777
	    } else {
778
3
		format = CAIRO_FORMAT_RGBA128F;
779
	    }
780
384
	    break;
781

            
782
1353
	case PNG_COLOR_TYPE_RGB:
783
1353
	    if (depth == 8) {
784
1353
		format = CAIRO_FORMAT_RGB24;
785
1353
		png_set_read_user_transform_fn (png, convert_bytes_to_data);
786
	    } else {
787
		format = CAIRO_FORMAT_RGB96F;
788
	    }
789
1353
	    break;
790
    }
791

            
792
1737
    stride = cairo_format_stride_for_width (format, png_width);
793
1737
    if (stride < 0) {
794
	surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
795
	goto BAIL;
796
    }
797

            
798
1737
    data = _cairo_malloc_ab (png_height, stride);
799
1737
    if (unlikely (data == NULL)) {
800
	surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
801
	goto BAIL;
802
    }
803

            
804
1737
    row_pointers = _cairo_malloc_ab (png_height, sizeof (char *));
805
1737
    if (unlikely (row_pointers == NULL)) {
806
	surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
807
	goto BAIL;
808
    }
809

            
810
246228
    for (i = 0; i < png_height; i++)
811
244491
        row_pointers[i] = &data[i * (ptrdiff_t)stride];
812

            
813
1737
    png_read_image (png, row_pointers);
814
1737
    png_read_end (png, info);
815

            
816
1737
    if (unlikely (status)) { /* catch any late warnings - probably hit an error already */
817
	surface = _cairo_surface_create_in_error (status);
818
	goto BAIL;
819
    }
820

            
821
1737
    if (format == CAIRO_FORMAT_RGBA128F) {
822
3
	i = png_height;
823

            
824
9
	while (i--) {
825
6
	    float *float_line = (float *)row_pointers[i];
826
6
	    uint16_t *u16_line = (uint16_t *)row_pointers[i];
827

            
828
6
	    premultiply_float (float_line, u16_line, png_width);
829
	}
830
1734
    } else if (format == CAIRO_FORMAT_RGB96F) {
831
	i = png_height;
832

            
833
	while (i--) {
834
	    float *float_line = (float *)row_pointers[i];
835
	    uint16_t *u16_line = (uint16_t *)row_pointers[i];
836

            
837
	    convert_u16_to_float (float_line, u16_line, png_width);
838
	}
839
    }
840

            
841
1737
    surface = cairo_image_surface_create_for_data (data, format,
842
						   png_width, png_height,
843
						   stride);
844
1737
    if (surface->status)
845
	goto BAIL;
846

            
847
1737
    _cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface);
848
1737
    data = NULL;
849

            
850
    _cairo_debug_check_image_surface_is_defined (surface);
851

            
852
1737
    status = _cairo_memory_stream_destroy (png_closure->png_data,
853
					   &mime_data,
854
					   &mime_data_length);
855
1737
    png_closure->png_data = NULL;
856
1737
    if (unlikely (status)) {
857
	cairo_surface_destroy (surface);
858
	surface = _cairo_surface_create_in_error (status);
859
	goto BAIL;
860
    }
861

            
862
1737
    status = cairo_surface_set_mime_data (surface,
863
					  CAIRO_MIME_TYPE_PNG,
864
					  mime_data,
865
					  mime_data_length,
866
					  free,
867
					  mime_data);
868
1737
    if (unlikely (status)) {
869
	free (mime_data);
870
	cairo_surface_destroy (surface);
871
	surface = _cairo_surface_create_in_error (status);
872
	goto BAIL;
873
    }
874

            
875
1737
 BAIL:
876
1740
    free (row_pointers);
877
1740
    free (data);
878
1740
    if (png != NULL)
879
1740
	png_destroy_read_struct (&png, &info, NULL);
880
1740
    if (png_closure->png_data != NULL) {
881
	cairo_status_t status_ignored;
882

            
883
3
	status_ignored = _cairo_output_stream_destroy (png_closure->png_data);
884
    }
885

            
886
1740
    return surface;
887
}
888

            
889
/**
890
 * cairo_image_surface_create_from_png:
891
 * @filename: name of PNG file to load. On Windows this filename
892
 *   is encoded in UTF-8.
893
 *
894
 * Creates a new image surface and initializes the contents to the
895
 * given PNG file.
896
 *
897
 * Return value: a new #cairo_surface_t initialized with the contents
898
 * of the PNG file, or a "nil" surface if any error occurred. A nil
899
 * surface can be checked for with cairo_surface_status(surface) which
900
 * may return one of the following values:
901
 *
902
 *	%CAIRO_STATUS_NO_MEMORY
903
 *	%CAIRO_STATUS_FILE_NOT_FOUND
904
 *	%CAIRO_STATUS_READ_ERROR
905
 *	%CAIRO_STATUS_PNG_ERROR
906
 *
907
 * Alternatively, you can allow errors to propagate through the drawing
908
 * operations and check the status on the context upon completion
909
 * using cairo_status().
910
 *
911
 * Since: 1.0
912
 **/
913
cairo_surface_t *
914
1852
cairo_image_surface_create_from_png (const char *filename)
915
{
916
    struct png_read_closure_t png_closure;
917
    cairo_surface_t *surface;
918
    cairo_status_t status;
919

            
920
1852
    status = _cairo_fopen (filename, "rb", (FILE **) &png_closure.closure);
921

            
922
1852
    if (status != CAIRO_STATUS_SUCCESS)
923
	return _cairo_surface_create_in_error (status);
924

            
925
1852
    if (png_closure.closure == NULL) {
926
127
	switch (errno) {
927
	case ENOMEM:
928
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
929
	    break;
930
127
	case ENOENT:
931
127
	    status = _cairo_error (CAIRO_STATUS_FILE_NOT_FOUND);
932
127
	    break;
933
	default:
934
	    status = _cairo_error (CAIRO_STATUS_READ_ERROR);
935
	    break;
936
	}
937
127
	return _cairo_surface_create_in_error (status);
938
    }
939

            
940
1725
    png_closure.read_func = stdio_read_func;
941

            
942
1725
    surface = read_png (&png_closure);
943

            
944
1725
    fclose (png_closure.closure);
945

            
946
1725
    return surface;
947
}
948

            
949
/**
950
 * cairo_image_surface_create_from_png_stream:
951
 * @read_func: function called to read the data of the file
952
 * @closure: data to pass to @read_func.
953
 *
954
 * Creates a new image surface from PNG data read incrementally
955
 * via the @read_func function.
956
 *
957
 * Return value: a new #cairo_surface_t initialized with the contents
958
 * of the PNG file or a "nil" surface if the data read is not a valid PNG image
959
 * or memory could not be allocated for the operation.  A nil
960
 * surface can be checked for with cairo_surface_status(surface) which
961
 * may return one of the following values:
962
 *
963
 *	%CAIRO_STATUS_NO_MEMORY
964
 *	%CAIRO_STATUS_READ_ERROR
965
 *	%CAIRO_STATUS_PNG_ERROR
966
 *
967
 * Alternatively, you can allow errors to propagate through the drawing
968
 * operations and check the status on the context upon completion
969
 * using cairo_status().
970
 *
971
 * Since: 1.0
972
 **/
973
cairo_surface_t *
974
15
cairo_image_surface_create_from_png_stream (cairo_read_func_t	read_func,
975
					    void		*closure)
976
{
977
    struct png_read_closure_t png_closure;
978

            
979
15
    png_closure.read_func = read_func;
980
15
    png_closure.closure = closure;
981

            
982
15
    return read_png (&png_closure);
983
}