1 /*****************************************************************************
2 * RRDtool 1.0.33 Copyright Tobias Oetiker, 1997 - 2000
3 *****************************************************************************
4 * gdpng.c add PNG output routine to gd library
5 *****************************************************************************/
11 typedef struct _jmpbuf_wrapper {
15 static jmpbuf_wrapper gdPngJmpbufStruct;
17 void gdImagePng(gdImagePtr im, FILE *out)
21 png_structp png_write_ptr =
22 png_create_write_struct(PNG_LIBPNG_VER_STRING,
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);
34 palette = (png_colorp)png_malloc (png_write_ptr,
35 im->colorsTotal*sizeof(png_color));
37 png_destroy_write_struct(&png_write_ptr, &info_ptr);
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];
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);
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);