Initial revision
[rrdtool.git] / src / gdpng.c
1 /*****************************************************************************
2  * RRDtool 1.0.33  Copyright Tobias Oetiker, 1997 - 2000
3  *****************************************************************************
4  * gdpng.c  add PNG output routine to gd library
5  *****************************************************************************/
6
7 #include <png.h>
8 #include <gd.h>
9 #include <stdlib.h>
10
11 typedef struct _jmpbuf_wrapper {
12   jmp_buf jmpbuf;
13 } jmpbuf_wrapper;
14
15 static jmpbuf_wrapper gdPngJmpbufStruct;
16
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);
28
29     if (setjmp(gdPngJmpbufStruct.jmpbuf)) {
30       png_destroy_write_struct(&png_write_ptr, &info_ptr);
31       return;
32     }
33
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     }
40     
41     
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);
55
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 }
68
69
70
71