1 /*****************************************************************************
2 * RRDtool 1.2.12 Copyright by Tobi Oetiker, 1997-2005
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(gdImagePtr im, FILE *out)
18 {
19 int i;
20 png_colorp palette;
21 png_structp png_write_ptr =
22 png_create_write_struct(PNG_LIBPNG_VER_STRING,
23 (png_voidp)NULL,
24 /* we would need to point to error handlers
25 here to do it properly */
26 (png_error_ptr)NULL, (png_error_ptr)NULL);
27 png_infop info_ptr = png_create_info_struct(png_write_ptr);
29 if (setjmp(gdPngJmpbufStruct.jmpbuf)) {
30 png_destroy_write_struct(&png_write_ptr, &info_ptr);
31 return;
32 }
34 palette = (png_colorp)png_malloc (png_write_ptr,
35 im->colorsTotal*sizeof(png_color));
36 if (palette == NULL){
37 png_destroy_write_struct(&png_write_ptr, &info_ptr);
38 return;
39 }
42 png_init_io(png_write_ptr, out);
43 png_set_write_status_fn(png_write_ptr, NULL);
44 png_set_IHDR(png_write_ptr,info_ptr,
45 im->sx,im->sy,im->colorsTotal > 16 ? 8:4,
46 PNG_COLOR_TYPE_PALETTE,
47 im->interlace ? PNG_INTERLACE_ADAM7: PNG_INTERLACE_NONE ,
48 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
49 for(i=0;i<im->colorsTotal;i++){
50 palette[i].red = im->red[i];
51 palette[i].green = im->green[i];
52 palette[i].blue = im->blue[i];
53 }
54 png_set_PLTE(png_write_ptr, info_ptr, palette, im->colorsTotal);
56 /* choose between speed (1) and space (9) optimisation */
57 /* we want to be fast ... */
58 png_set_compression_level(png_write_ptr,1);
59 png_set_filter(png_write_ptr,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
60 /* store file info */
61 png_write_info(png_write_ptr, info_ptr);
62 png_set_packing(png_write_ptr);
63 png_write_image(png_write_ptr, im->pixels);
64 png_write_end(png_write_ptr, info_ptr);
65 png_free(png_write_ptr, palette);
66 png_destroy_write_struct(&png_write_ptr, &info_ptr);
67 }