Subversion Repositories Kolibri OS

Rev

Rev 1897 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1897 Rev 3959
Line 37... Line 37...
37
 */
37
 */
Line 38... Line 38...
38
 
38
 
Line 39... Line 39...
39
#include "cairoint.h"
39
#include "cairoint.h"
-
 
40
 
40
 
41
#include "cairo-error-private.h"
Line 41... Line 42...
41
#include "cairo-error-private.h"
42
#include "cairo-image-surface-private.h"
42
#include "cairo-output-stream-private.h"
43
#include "cairo-output-stream-private.h"
43
 
44
 
Line 51... Line 52...
51
 * @Short_Description: Reading and writing PNG images
52
 * @Short_Description: Reading and writing PNG images
52
 * @See_Also: #cairo_surface_t
53
 * @See_Also: #cairo_surface_t
53
 *
54
 *
54
 * The PNG functions allow reading PNG images into image surfaces, and writing
55
 * The PNG functions allow reading PNG images into image surfaces, and writing
55
 * any surface to a PNG file.
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.
56
 */
65
 **/
Line 57... Line 66...
57
 
66
 
58
/**
67
/**
59
 * CAIRO_HAS_PNG_FUNCTIONS:
68
 * CAIRO_HAS_PNG_FUNCTIONS:
60
 *
69
 *
61
 * Defined if the PNG functions are available.
70
 * Defined if the PNG functions are available.
62
 * This macro can be used to conditionally compile code using the cairo
71
 * This macro can be used to conditionally compile code using the cairo
-
 
72
 * PNG functions.
-
 
73
 *
63
 * PNG functions.
74
 * Since: 1.0
Line 64... Line 75...
64
 */
75
 **/
65
 
76
 
66
struct png_read_closure_t {
77
struct png_read_closure_t {
67
    cairo_read_func_t		 read_func;
78
    cairo_read_func_t		 read_func;
Line 136... Line 147...
136
 
147
 
137
static void
148
static void
138
png_simple_warning_callback (png_structp png,
149
png_simple_warning_callback (png_structp png,
139
	                     png_const_charp error_msg)
150
	                     png_const_charp error_msg)
140
{
151
{
141
    cairo_status_t *error = png_get_error_ptr (png);
-
 
142
 
152
    /* png does not expect to abort and will try to tidy up and continue
143
    /* default to the most likely error */
153
     * loading the image after a warning. So we also want to return the
-
 
154
     * (incorrect?) surface.
144
    if (*error == CAIRO_STATUS_SUCCESS)
155
     *
145
	*error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
 
146
 
156
     * We use our own warning callback to squelch any attempts by libpng
-
 
157
     * to write to stderr as we may not be in control of that output.
147
    /* png does not expect to abort and will try to tidy up after a warning */
158
     */
Line 148... Line 159...
148
}
159
}
149
 
160
 
Line 159... Line 170...
159
write_png (cairo_surface_t	*surface,
170
write_png (cairo_surface_t	*surface,
160
	   png_rw_ptr		write_func,
171
	   png_rw_ptr		write_func,
161
	   void			*closure)
172
	   void			*closure)
162
{
173
{
163
    int i;
174
    int i;
164
    cairo_status_t status;
175
    cairo_int_status_t status;
165
    cairo_image_surface_t *image;
176
    cairo_image_surface_t *image;
166
    cairo_image_surface_t * volatile clone;
177
    cairo_image_surface_t * volatile clone;
167
    void *image_extra;
178
    void *image_extra;
168
    png_struct *png;
179
    png_struct *png;
169
    png_info *info;
180
    png_info *info;
170
    png_byte **volatile rows = NULL;
181
    png_byte **volatile rows = NULL;
171
    png_color_16 white;
182
    png_color_16 white;
172
    int png_color_type;
183
    int png_color_type;
173
    int depth;
184
    int bpc;
Line 174... Line 185...
174
 
185
 
175
    status = _cairo_surface_acquire_source_image (surface,
186
    status = _cairo_surface_acquire_source_image (surface,
176
						  &image,
187
						  &image,
Line 225... Line 236...
225
 
236
 
Line 226... Line 237...
226
    png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn);
237
    png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn);
227
 
238
 
228
    switch (clone->format) {
239
    switch (clone->format) {
229
    case CAIRO_FORMAT_ARGB32:
240
    case CAIRO_FORMAT_ARGB32:
230
	depth = 8;
241
	bpc = 8;
231
	if (_cairo_image_analyze_transparency (clone) == CAIRO_IMAGE_IS_OPAQUE)
242
	if (_cairo_image_analyze_transparency (clone) == CAIRO_IMAGE_IS_OPAQUE)
232
	    png_color_type = PNG_COLOR_TYPE_RGB;
243
	    png_color_type = PNG_COLOR_TYPE_RGB;
233
	else
244
	else
-
 
245
	    png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
-
 
246
	break;
-
 
247
    case CAIRO_FORMAT_RGB30:
-
 
248
	bpc = 10;
234
	    png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
249
	png_color_type = PNG_COLOR_TYPE_RGB;
235
	break;
250
	break;
236
    case CAIRO_FORMAT_RGB24:
251
    case CAIRO_FORMAT_RGB24:
237
	depth = 8;
252
	bpc = 8;
238
	png_color_type = PNG_COLOR_TYPE_RGB;
253
	png_color_type = PNG_COLOR_TYPE_RGB;
239
	break;
254
	break;
240
    case CAIRO_FORMAT_A8:
255
    case CAIRO_FORMAT_A8:
241
	depth = 8;
256
	bpc = 8;
242
	png_color_type = PNG_COLOR_TYPE_GRAY;
257
	png_color_type = PNG_COLOR_TYPE_GRAY;
243
	break;
258
	break;
244
    case CAIRO_FORMAT_A1:
259
    case CAIRO_FORMAT_A1:
245
	depth = 1;
260
	bpc = 1;
246
	png_color_type = PNG_COLOR_TYPE_GRAY;
261
	png_color_type = PNG_COLOR_TYPE_GRAY;
247
#ifndef WORDS_BIGENDIAN
262
#ifndef WORDS_BIGENDIAN
248
	png_set_packswap (png);
263
	png_set_packswap (png);
Line 255... Line 270...
255
	goto BAIL4;
270
	goto BAIL4;
256
    }
271
    }
Line 257... Line 272...
257
 
272
 
258
    png_set_IHDR (png, info,
273
    png_set_IHDR (png, info,
259
		  clone->width,
274
		  clone->width,
260
		  clone->height, depth,
275
		  clone->height, bpc,
261
		  png_color_type,
276
		  png_color_type,
262
		  PNG_INTERLACE_NONE,
277
		  PNG_INTERLACE_NONE,
263
		  PNG_COMPRESSION_TYPE_DEFAULT,
278
		  PNG_COMPRESSION_TYPE_DEFAULT,
Line 264... Line 279...
264
		  PNG_FILTER_TYPE_DEFAULT);
279
		  PNG_FILTER_TYPE_DEFAULT);
265
 
280
 
266
    white.gray = (1 << depth) - 1;
281
    white.gray = (1 << bpc) - 1;
Line 267... Line 282...
267
    white.red = white.blue = white.green = white.gray;
282
    white.red = white.blue = white.green = white.gray;
268
    png_set_bKGD (png, info, &white);
283
    png_set_bKGD (png, info, &white);
Line 333... Line 348...
333
 * successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY if memory could not
348
 * successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY if memory could not
334
 * be allocated for the operation or
349
 * be allocated for the operation or
335
 * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
350
 * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
336
 * pixel contents, or %CAIRO_STATUS_WRITE_ERROR if an I/O error occurs
351
 * pixel contents, or %CAIRO_STATUS_WRITE_ERROR if an I/O error occurs
337
 * while attempting to write the file.
352
 * while attempting to write the file.
-
 
353
 *
-
 
354
 * Since: 1.0
338
 **/
355
 **/
339
cairo_status_t
356
cairo_status_t
340
cairo_surface_write_to_png (cairo_surface_t	*surface,
357
cairo_surface_write_to_png (cairo_surface_t	*surface,
341
			    const char		*filename)
358
			    const char		*filename)
342
{
359
{
Line 399... Line 416...
399
 * Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
416
 * Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written
400
 * successfully.  Otherwise, %CAIRO_STATUS_NO_MEMORY is returned if
417
 * successfully.  Otherwise, %CAIRO_STATUS_NO_MEMORY is returned if
401
 * memory could not be allocated for the operation,
418
 * memory could not be allocated for the operation,
402
 * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
419
 * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
403
 * pixel contents.
420
 * pixel contents.
-
 
421
 *
-
 
422
 * Since: 1.0
404
 **/
423
 **/
405
cairo_status_t
424
cairo_status_t
406
cairo_surface_write_to_png_stream (cairo_surface_t	*surface,
425
cairo_surface_write_to_png_stream (cairo_surface_t	*surface,
407
				   cairo_write_func_t	write_func,
426
				   cairo_write_func_t	write_func,
408
				   void			*closure)
427
				   void			*closure)
Line 695... Line 714...
695
	surface = _cairo_surface_create_in_error (status);
714
	surface = _cairo_surface_create_in_error (status);
696
	goto BAIL;
715
	goto BAIL;
697
    }
716
    }
Line 698... Line 717...
698
 
717
 
699
 BAIL:
-
 
700
    if (row_pointers != NULL)
718
 BAIL:
701
	free (row_pointers);
-
 
702
    if (data != NULL)
719
    free (row_pointers);
703
	free (data);
720
    free (data);
704
    if (png != NULL)
721
    if (png != NULL)
705
	png_destroy_read_struct (&png, &info, NULL);
722
	png_destroy_read_struct (&png, &info, NULL);
706
    if (png_closure->png_data != NULL) {
723
    if (png_closure->png_data != NULL) {
Line 729... Line 746...
729
 *	%CAIRO_STATUS_READ_ERROR
746
 *	%CAIRO_STATUS_READ_ERROR
730
 *
747
 *
731
 * Alternatively, you can allow errors to propagate through the drawing
748
 * Alternatively, you can allow errors to propagate through the drawing
732
 * operations and check the status on the context upon completion
749
 * operations and check the status on the context upon completion
733
 * using cairo_status().
750
 * using cairo_status().
-
 
751
 *
-
 
752
 * Since: 1.0
734
 **/
753
 **/
735
cairo_surface_t *
754
cairo_surface_t *
736
cairo_image_surface_create_from_png (const char *filename)
755
cairo_image_surface_create_from_png (const char *filename)
737
{
756
{
738
    struct png_read_closure_t png_closure;
757
    struct png_read_closure_t png_closure;
Line 782... Line 801...
782
 *	%CAIRO_STATUS_READ_ERROR
801
 *	%CAIRO_STATUS_READ_ERROR
783
 *
802
 *
784
 * Alternatively, you can allow errors to propagate through the drawing
803
 * Alternatively, you can allow errors to propagate through the drawing
785
 * operations and check the status on the context upon completion
804
 * operations and check the status on the context upon completion
786
 * using cairo_status().
805
 * using cairo_status().
-
 
806
 *
-
 
807
 * Since: 1.0
787
 **/
808
 **/
788
cairo_surface_t *
809
cairo_surface_t *
789
cairo_image_surface_create_from_png_stream (cairo_read_func_t	read_func,
810
cairo_image_surface_create_from_png_stream (cairo_read_func_t	read_func,
790
					    void		*closure)
811
					    void		*closure)
791
{
812
{