1 #include "grib2.h"
2 #ifndef USE_PNG
enc_png(char * data,g2int width,g2int height,g2int nbits,char * pngbuf)3 int enc_png(char *data,g2int width,g2int height,g2int nbits,char *pngbuf){return 0;}
4 #else   /* USE_PNG */
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <png.h>
10 
11 
12 struct png_stream {
13    unsigned char *stream_ptr;     /*  location to write PNG stream  */
14    g2int stream_len;               /*  number of bytes written       */
15 };
16 typedef struct png_stream png_stream;
17 
18 void user_write_data(png_structp ,png_bytep , png_uint_32 );
19 void user_flush_data(png_structp );
20 
user_write_data(png_structp png_ptr,png_bytep data,png_uint_32 length)21 void user_write_data(png_structp png_ptr,png_bytep data, png_uint_32 length)
22 /*
23         Custom write function used to that libpng will write
24         to memory location instead of a file on disk
25 */
26 {
27      unsigned char *ptr;
28      g2int offset;
29      png_stream *mem;
30 
31      mem=(png_stream *)png_get_io_ptr(png_ptr);
32      ptr=mem->stream_ptr;
33      offset=mem->stream_len;
34 /*     printf("SAGwr %ld %ld %x\n",offset,length,ptr);    */
35      /*for (j=offset,k=0;k<length;j++,k++) ptr[j]=data[k];*/
36      memcpy(ptr+offset,data,length);
37      mem->stream_len += length;
38 }
39 
40 
user_flush_data(png_structp png_ptr)41 void user_flush_data(png_structp png_ptr)
42 /*
43         Dummy Custom flush function
44 */
45 {
46    (void)png_ptr;
47 }
48 
49 
enc_png(char * data,g2int width,g2int height,g2int nbits,char * pngbuf)50 int enc_png(char *data,g2int width,g2int height,g2int nbits,char *pngbuf)
51 {
52 
53     int color_type;
54     g2int j,bytes,pnglen,bit_depth;
55     png_structp png_ptr;
56     png_infop info_ptr;
57 //    png_bytep *row_pointers[height];
58     png_bytep **row_pointers;
59     png_stream write_io_ptr;
60 
61 /* create and initialize png_structs  */
62 
63     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
64                                       NULL, NULL);
65     if (!png_ptr)
66        return (-1);
67 
68     info_ptr = png_create_info_struct(png_ptr);
69     if (!info_ptr)
70     {
71        png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
72        return (-2);
73     }
74 
75 /*     Set Error callback   */
76 
77     if (setjmp(png_jmpbuf(png_ptr)))
78     {
79        png_destroy_write_struct(&png_ptr, &info_ptr);
80        return (-3);
81     }
82 
83 /*    Initialize info for writing PNG stream to memory   */
84 
85     write_io_ptr.stream_ptr=(png_voidp)pngbuf;
86     write_io_ptr.stream_len=0;
87 
88 /*    Set new custom write functions    */
89 
90     png_set_write_fn(png_ptr,(png_voidp)&write_io_ptr,(png_rw_ptr)user_write_data,
91                     (png_flush_ptr)user_flush_data);
92 /*    png_init_io(png_ptr, fptr);   */
93 /*    png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);  */
94 
95 /*     Set the image size, colortype, filter type, etc...      */
96 
97 /*    printf("SAGTsettingIHDR %d %d %d\n",width,height,bit_depth); */
98     bit_depth=nbits;
99     color_type=PNG_COLOR_TYPE_GRAY;
100     if (nbits == 24 ) {
101         bit_depth=8;
102         color_type=PNG_COLOR_TYPE_RGB;
103     }
104     else if (nbits == 32 ) {
105         bit_depth=8;
106         color_type=PNG_COLOR_TYPE_RGB_ALPHA;
107     }
108     png_set_IHDR(png_ptr, info_ptr, width, height,
109        bit_depth, color_type, PNG_INTERLACE_NONE,
110        PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
111 
112 /*     Put image data into the PNG info structure    */
113 
114     /*bytes=bit_depth/8;*/
115     bytes=nbits/8;
116     row_pointers=malloc(height*sizeof(png_bytep*));
117     for (j=0;j<height;j++) row_pointers[j]=(png_bytep *)(data+(j*width*bytes));
118     png_set_rows(png_ptr, info_ptr, (png_bytepp)row_pointers);
119 
120 /*     Do the PNG encoding, and write out PNG stream  */
121 
122     png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
123 
124 /*     Clean up   */
125 
126     png_destroy_write_struct(&png_ptr, &info_ptr);
127     free(row_pointers);
128     pnglen=write_io_ptr.stream_len;
129     return pnglen;
130 
131 }
132 
133 #endif   /* USE_PNG */
134