NCEPLIBS-g2 3.5.1
Loading...
Searching...
No Matches
g2cpng.c
Go to the documentation of this file.
1
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <png.h>
11
12typedef int g2int;
15struct png_stream
16{
17 unsigned char *stream_ptr;
18 g2int stream_len;
19};
20
21typedef struct png_stream png_stream;
34static void
35user_write_data(png_structp png_ptr,png_bytep data, png_uint_32 length)
36{
37 unsigned char *ptr;
38 g2int offset;
39 png_stream *mem;
40
41 mem = (png_stream *)png_get_io_ptr(png_ptr);
42 ptr = mem->stream_ptr;
43 offset = mem->stream_len;
44 memcpy(ptr + offset, data, length);
45 mem->stream_len += length;
46}
47
56static void
57user_flush_data(png_structp png_ptr)
58{
59}
60
73int
74enc_png(char *data, g2int *width, g2int *height, g2int *nbits, char *pngbuf)
75{
76
77 int color_type;
78 g2int j, bytes, pnglen, bit_depth;
79 png_structp png_ptr;
80 png_infop info_ptr;
81 png_bytep **row_pointers;
82 png_stream write_io_ptr;
83
84 /* create and initialize png_structs. */
85 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
86 NULL, NULL);
87 if (!png_ptr)
88 return -1;
89
90 info_ptr = png_create_info_struct(png_ptr);
91 if (!info_ptr)
92 {
93 png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
94 return -2;
95 }
96
97 /* Set Error callback. */
98 if (setjmp(png_jmpbuf(png_ptr)))
99 {
100 png_destroy_write_struct(&png_ptr, &info_ptr);
101 return -3;
102 }
103
104 /* Initialize info for writing PNG stream to memory. */
105 write_io_ptr.stream_ptr = (png_voidp)pngbuf;
106 write_io_ptr.stream_len = 0;
107
108 /* Set new custom write functions. */
109 png_set_write_fn(png_ptr, (png_voidp)&write_io_ptr, (png_rw_ptr)user_write_data,
110 (png_flush_ptr)user_flush_data);
111
112 /* Set the image size, colortype, filter type, etc... */
113 bit_depth = *nbits;
114 color_type = PNG_COLOR_TYPE_GRAY;
115 if (*nbits == 24)
116 {
117 bit_depth = 8;
118 color_type = PNG_COLOR_TYPE_RGB;
119 }
120 else if (*nbits == 32)
121 {
122 bit_depth = 8;
123 color_type = PNG_COLOR_TYPE_RGB_ALPHA;
124 }
125 png_set_IHDR(png_ptr, info_ptr, *width, *height,
126 bit_depth, color_type, PNG_INTERLACE_NONE,
127 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
128
129 /* Put image data into the PNG info structure. */
130 bytes = *nbits / 8;
131 row_pointers = malloc((*height) * sizeof(png_bytep));
132 for (j = 0; j < *height; j++)
133 row_pointers[j] = (png_bytep *)(data+(j * (*width) * bytes));
134 png_set_rows(png_ptr, info_ptr, (png_bytepp)row_pointers);
135
136 /* Do the PNG encoding, and write out PNG stream. */
137 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
138
139 /* Clean up. */
140 png_destroy_write_struct(&png_ptr, &info_ptr);
141 free(row_pointers);
142 pnglen = write_io_ptr.stream_len;
143 return pnglen;
144
145}
146
157static void
158user_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
159{
160 char *ptr;
161 g2int offset;
162 png_stream *mem;
163
164 mem = (png_stream *)png_get_io_ptr(png_ptr);
165 ptr = (void *)mem->stream_ptr;
166 offset = mem->stream_len;
167 memcpy(data, ptr + offset, length);
168 mem->stream_len += length;
169}
170
187int
188dec_png(unsigned char *pngbuf, g2int *width, g2int *height, char *cout)
189{
190 int interlace, color, compres, filter, bit_depth;
191 g2int j, k, n, bytes, clen;
192 png_structp png_ptr;
193 png_infop info_ptr, end_info;
194 png_bytepp row_pointers;
195 png_stream read_io_ptr;
196 png_uint_32 h32, w32;
197
198 /* Check if stream is a valid PNG format. */
199 if (png_sig_cmp(pngbuf, 0, 8) != 0)
200 return -3;
201
202 /* Create and initialize png_structs. */
203 if (!(png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
204 NULL, NULL)))
205 return -1;
206
207 if (!(info_ptr = png_create_info_struct(png_ptr)))
208 {
209 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
210 return -2;
211 }
212
213 if (!(end_info = png_create_info_struct(png_ptr)))
214 {
215 png_destroy_read_struct(&png_ptr, (png_infopp)info_ptr, (png_infopp)NULL);
216 return -2;
217 }
218
219 /* Set Error callback. */
220 if (setjmp(png_jmpbuf(png_ptr)))
221 {
222 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
223 return -3;
224 }
225
226 /* Initialize info for reading PNG stream from memory. */
227 read_io_ptr.stream_ptr = (png_voidp)pngbuf;
228 read_io_ptr.stream_len = 0;
229
230 /* Set new custom read function. */
231 png_set_read_fn(png_ptr, (png_voidp)&read_io_ptr, (png_rw_ptr)user_read_data);
232
233 /* Read and decode PNG stream. */
234 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
235
236 /* Get pointer to each row of image data. */
237 row_pointers = png_get_rows(png_ptr, info_ptr);
238
239 /* Get image info, such as size, depth, colortype, etc... */
240 (void)png_get_IHDR(png_ptr, info_ptr, &w32, &h32,
241 &bit_depth, &color, &interlace, &compres, &filter);
242
243 *height = h32;
244 *width = w32;
245
246 /* Check if image was grayscale. */
247 if ( color == PNG_COLOR_TYPE_RGB ) {
248 bit_depth = 24;
249 }
250 else if ( color == PNG_COLOR_TYPE_RGB_ALPHA ) {
251 bit_depth = 32;
252 }
253
254 /* Copy image data to output string */
255 n = 0;
256 bytes = bit_depth / 8;
257 clen = *width * bytes;
258 for (j = 0; j < *height; j++) {
259 for (k = 0; k < clen; k++) {
260 cout[n] = *(row_pointers[j]+k);
261 n++;
262 }
263 }
264
265 /* Clean up. */
266 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
267 return 0;
268}
int enc_png(char *data, g2int *width, g2int *height, g2int *nbits, char *pngbuf)
create png_structs to write png stream into memory.
Definition g2cpng.c:74
int dec_png(unsigned char *pngbuf, g2int *width, g2int *height, char *cout)
Decode some PNG compressed data.
Definition g2cpng.c:188
struct png_stream png_stream
location to write PNG stream
Definition g2cpng.c:21
static void user_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
Custom write function used to that libpng will write to memory location instead of a file on disk.
Definition g2cpng.c:35
static void user_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
Custom read function used so that libpng will read a PNG stream from memory instead of a file on disk...
Definition g2cpng.c:158
int g2int
Integer type.
Definition g2cpng.c:12
static void user_flush_data(png_structp png_ptr)
Dummy Custom flush function.
Definition g2cpng.c:57