1 /*****************************************************************************
2 * RRDtool 1.2.23 Copyright by Tobi Oetiker, 1997-2007
3 *****************************************************************************
4 * gdpng.c add PNG output routine to gd library
5 *****************************************************************************/
7 #include <png.h>
8 #include <gd.h>
9 #include <stdlib.h>
11 typedef struct _jmpbuf_wrapper {
12 jmp_buf jmpbuf;
13 } jmpbuf_wrapper;
15 static jmpbuf_wrapper gdPngJmpbufStruct;
17 void gdImagePng(
18 gdImagePtr im,
19 FILE * out)
20 {
21 int i;
22 png_colorp palette;
23 png_structp png_write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
24 (png_voidp) NULL,
25 /* we would need to point to error handlers
26 here to do it properly */
27 (png_error_ptr) NULL,
28 (png_error_ptr) NULL);
29 png_infop info_ptr = png_create_info_struct(png_write_ptr);
31 if (setjmp(gdPngJmpbufStruct.jmpbuf)) {
32 png_destroy_write_struct(&png_write_ptr, &info_ptr);
33 return;
34 }
36 palette = (png_colorp) png_malloc(png_write_ptr,
37 im->colorsTotal * sizeof(png_color));
38 if (palette == NULL) {
39 png_destroy_write_struct(&png_write_ptr, &info_ptr);
40 return;
41 }
44 png_init_io(png_write_ptr, out);
45 png_set_write_status_fn(png_write_ptr, NULL);
46 png_set_IHDR(png_write_ptr, info_ptr,
47 im->sx, im->sy, im->colorsTotal > 16 ? 8 : 4,
48 PNG_COLOR_TYPE_PALETTE,
49 im->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE,
50 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
51 for (i = 0; i < im->colorsTotal; i++) {
52 palette[i].red = im->red[i];
53 palette[i].green = im->green[i];
54 palette[i].blue = im->blue[i];
55 }
56 png_set_PLTE(png_write_ptr, info_ptr, palette, im->colorsTotal);
58 /* choose between speed (1) and space (9) optimisation */
59 /* we want to be fast ... */
60 png_set_compression_level(png_write_ptr, 1);
61 png_set_filter(png_write_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS);
62 /* store file info */
63 png_write_info(png_write_ptr, info_ptr);
64 png_set_packing(png_write_ptr);
65 png_write_image(png_write_ptr, im->pixels);
66 png_write_end(png_write_ptr, info_ptr);
67 png_free(png_write_ptr, palette);
68 png_destroy_write_struct(&png_write_ptr, &info_ptr);
69 }