1 /*****************************************************************************
2 * RRDtool 1.2.23 Copyright by Tobi Oetiker, 1997-2007
3 *****************************************************************************
4 * gdpng.c add PNG output routine to gd library
5 *****************************************************************************/
11 typedef struct _jmpbuf_wrapper {
15 static jmpbuf_wrapper gdPngJmpbufStruct;
23 png_structp png_write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
25 /* we would need to point to error handlers
26 here to do it properly */
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);
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);
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];
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);
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);