NCEPLIBS-g2  3.4.7
dec_png.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;
33 static void
34 user_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
35 {
36  char *ptr;
37  g2int offset;
38  png_stream *mem;
39 
40  mem = (png_stream *)png_get_io_ptr(png_ptr);
41  ptr = (void *)mem->stream_ptr;
42  offset = mem->stream_len;
43  memcpy(data, ptr + offset, length);
44  mem->stream_len += length;
45 }
46 
63 int
64 dec_png(unsigned char *pngbuf, g2int *width, g2int *height, char *cout)
65 {
66  int interlace, color, compres, filter, bit_depth;
67  g2int j, k, n, bytes, clen;
68  png_structp png_ptr;
69  png_infop info_ptr, end_info;
70  png_bytepp row_pointers;
71  png_stream read_io_ptr;
72  png_uint_32 h32, w32;
73 
74  /* Check if stream is a valid PNG format. */
75  if (png_sig_cmp(pngbuf, 0, 8) != 0)
76  return -3;
77 
78  /* Create and initialize png_structs. */
79  if (!(png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
80  NULL, NULL)))
81  return -1;
82 
83  if (!(info_ptr = png_create_info_struct(png_ptr)))
84  {
85  png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
86  return -2;
87  }
88 
89  if (!(end_info = png_create_info_struct(png_ptr)))
90  {
91  png_destroy_read_struct(&png_ptr, (png_infopp)info_ptr, (png_infopp)NULL);
92  return -2;
93  }
94 
95  /* Set Error callback. */
96  if (setjmp(png_jmpbuf(png_ptr)))
97  {
98  png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
99  return -3;
100  }
101 
102  /* Initialize info for reading PNG stream from memory. */
103  read_io_ptr.stream_ptr = (png_voidp)pngbuf;
104  read_io_ptr.stream_len = 0;
105 
106  /* Set new custom read function. */
107  png_set_read_fn(png_ptr, (png_voidp)&read_io_ptr, (png_rw_ptr)user_read_data);
108 
109  /* Read and decode PNG stream. */
110  png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
111 
112  /* Get pointer to each row of image data. */
113  row_pointers = png_get_rows(png_ptr, info_ptr);
114 
115  /* Get image info, such as size, depth, colortype, etc... */
116  (void)png_get_IHDR(png_ptr, info_ptr, &w32, &h32,
117  &bit_depth, &color, &interlace, &compres, &filter);
118 
119  *height = h32;
120  *width = w32;
121 
122  /* Check if image was grayscale. */
123  if ( color == PNG_COLOR_TYPE_RGB ) {
124  bit_depth = 24;
125  }
126  else if ( color == PNG_COLOR_TYPE_RGB_ALPHA ) {
127  bit_depth = 32;
128  }
129 
130  /* Copy image data to output string */
131  n = 0;
132  bytes = bit_depth / 8;
133  clen = *width * bytes;
134  for (j = 0; j < *height; j++) {
135  for (k = 0; k < clen; k++) {
136  cout[n] = *(row_pointers[j]+k);
137  n++;
138  }
139  }
140 
141  /* Clean up. */
142  png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
143  return 0;
144 }
int dec_png(unsigned char *pngbuf, g2int *width, g2int *height, char *cout)
Decode some PNG compressed data.
Definition: dec_png.c:64
struct png_stream png_stream
location to write PNG stream
Definition: dec_png.c:21
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: dec_png.c:34
int g2int
Integer type.
Definition: dec_png.c:12
integer j
loop iterator