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