NCEPLIBS-g2c  1.6.4
dec_png.c
Go to the documentation of this file.
1 
6 #ifndef USE_PNG
12 void dummy(void) {}
13 #else /* USE_PNG */
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <png.h>
19 #include "grib2.h"
20 
24 struct png_stream
25 {
26  unsigned char *stream_ptr;
27  g2int stream_len;
28 };
29 typedef struct png_stream png_stream;
31 void user_read_data(png_structp, png_bytep, png_uint_32);
32 
43 void
44 user_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
45 {
46  char *ptr;
47  g2int offset;
48  png_stream *mem;
49 
50  mem = (png_stream *)png_get_io_ptr(png_ptr);
51  ptr = (void *)mem->stream_ptr;
52  offset = mem->stream_len;
53 /* printf("SAGrd %ld %ld %x\n",offset,length,ptr); */
54  memcpy(data, ptr + offset, length);
55  mem->stream_len += length;
56 }
57 
70 int
71 dec_png(unsigned char *pngbuf, g2int *width, g2int *height, char *cout)
72 {
73  int interlace, color, compres, filter, bit_depth;
74  g2int j, k, n, bytes, clen;
75  png_structp png_ptr;
76  png_infop info_ptr, end_info;
77  png_bytepp row_pointers;
78  png_stream read_io_ptr;
79  png_uint_32 h32, w32;
80 
81  /* Check if stream is a valid PNG format. */
82  if (png_sig_cmp(pngbuf, 0, 8) != 0)
83  return (-3);
84 
85  /* Create and initialize png_structs. */
86  if (!(png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
87  NULL, NULL)))
88  return (-1);
89 
90  if (!(info_ptr = png_create_info_struct(png_ptr)))
91  {
92  png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
93  return (-2);
94  }
95 
96  if (!(end_info = png_create_info_struct(png_ptr)))
97  {
98  png_destroy_read_struct(&png_ptr, (png_infopp)info_ptr, (png_infopp)NULL);
99  return (-2);
100  }
101 
102  /* Set Error callback. */
103  if (setjmp(png_jmpbuf(png_ptr)))
104  {
105  png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
106  return (-3);
107  }
108 
109  /* Initialize info for reading PNG stream from memory. */
110  read_io_ptr.stream_ptr = (png_voidp)pngbuf;
111  read_io_ptr.stream_len = 0;
112 
113  /* Set new custom read function. */
114  png_set_read_fn(png_ptr, (png_voidp)&read_io_ptr, (png_rw_ptr)user_read_data);
115 
116  /* Read and decode PNG stream. */
117  png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
118 
119  /* Get pointer to each row of image data. */
120  row_pointers = png_get_rows(png_ptr, info_ptr);
121 
122  /* Get image info, such as size, depth, colortype, etc... */
123  /*printf("SAGT:png %d %d %d\n", info_ptr->width, info_ptr->height, info_ptr->bit_depth);*/
124  // (void)png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *)width, (png_uint_32 *)height,
125  (void)png_get_IHDR(png_ptr, info_ptr, &w32, &h32,
126  &bit_depth, &color, &interlace, &compres, &filter);
127 
128  *height = h32;
129  *width = w32;
130 
131  /* Check if image was grayscale. */
132  /*
133  if (color != PNG_COLOR_TYPE_GRAY) {
134  fprintf(stderr, "dec_png: Grayscale image was expected. \n");
135  }
136  */
137  if (color == PNG_COLOR_TYPE_RGB)
138  bit_depth = 24;
139  else if (color == PNG_COLOR_TYPE_RGB_ALPHA)
140  bit_depth = 32;
141 
142  /* Copy image data to output string */
143  n = 0;
144  bytes = bit_depth / 8;
145  clen = (*width) * bytes;
146  for (j = 0; j < *height; j++)
147  {
148  for (k = 0; k < clen; k++)
149  {
150  cout[n] = *(row_pointers[j] + k);
151  n++;
152  }
153  }
154 
155  /* Clean up. */
156  png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
157  return 0;
158 }
159 
160 #endif /* USE_PNG */
int dec_png(unsigned char *pngbuf, g2int *width, g2int *height, char *cout)
Decode PNG.
Definition: dec_png.c:71
struct png_stream png_stream
Typedef for PNG stream.
Definition: dec_png.c:29
void user_read_data(png_structp, png_bytep, png_uint_32)
Custom read function used so that libpng will read a PNG stream from memory instead of a file on disk...
Definition: dec_png.c:44
Header file for NCEPLIBS-g2c library.
int64_t g2int
Long integer type.
Definition: grib2.h:20