NCEPLIBS-g2  3.5.0
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 
12 typedef int g2int;
15 struct png_stream
16 {
17  unsigned char *stream_ptr;
18  g2int stream_len;
19 };
20 
21 typedef struct png_stream png_stream;
34 static void
35 user_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 
56 static void
57 user_flush_data(png_structp png_ptr)
58 {
59 }
60 
73 int
74 enc_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 
157 static void
158 user_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 
187 int
188 dec_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
integer j
loop iterator