NCEPLIBS-g2c  1.8.0
dec_png.c
Go to the documentation of this file.
1 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <png.h>
10 #include "grib2_int.h"
11 
15 struct png_stream
16 {
17  unsigned char *stream_ptr;
18  g2int stream_len;
19 };
20 typedef struct png_stream png_stream;
22 void user_read_data(png_structp, png_bytep, png_uint_32);
23 
34 void
35 user_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
36 {
37  char *ptr;
38  g2int offset;
39  png_stream *mem;
40 
41  mem = (png_stream *)png_get_io_ptr(png_ptr);
42  ptr = (void *)mem->stream_ptr;
43  offset = mem->stream_len;
44  memcpy(data, ptr + offset, length);
45  mem->stream_len += length;
46 }
47 
60 int
61 dec_png(unsigned char *pngbuf, g2int *width, g2int *height,
62  unsigned char *cout)
63 {
64  int interlace, color, compres, filter, bit_depth;
65  g2int j, k, n, bytes, clen;
66  png_structp png_ptr;
67  png_infop info_ptr, end_info;
68  png_bytepp row_pointers;
69  png_stream read_io_ptr;
70  png_uint_32 h32, w32;
71 
72  /* Check if stream is a valid PNG format. */
73  if (png_sig_cmp(pngbuf, 0, 8) != 0)
74  return -3;
75 
76  /* Create and initialize png_structs. */
77  if (!(png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
78  NULL, NULL)))
79  return -1;
80 
81  if (!(info_ptr = png_create_info_struct(png_ptr)))
82  {
83  png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
84  return -2;
85  }
86 
87  if (!(end_info = png_create_info_struct(png_ptr)))
88  {
89  png_destroy_read_struct(&png_ptr, (png_infopp)info_ptr, (png_infopp)NULL);
90  return -2;
91  }
92 
93  /* Set Error callback. */
94  if (setjmp(png_jmpbuf(png_ptr)))
95  {
96  png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
97  return -3;
98  }
99 
100  /* Initialize info for reading PNG stream from memory. */
101  read_io_ptr.stream_ptr = (png_voidp)pngbuf;
102  read_io_ptr.stream_len = 0;
103 
104  /* Set new custom read function. */
105  png_set_read_fn(png_ptr, (png_voidp)&read_io_ptr, (png_rw_ptr)user_read_data);
106 
107  /* Read and decode PNG stream. */
108  png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
109 
110  /* Get pointer to each row of image data. */
111  row_pointers = png_get_rows(png_ptr, info_ptr);
112 
113  /* Get image info, such as size, depth, colortype, etc... */
114  /*printf("SAGT:png %d %d %d\n", info_ptr->width, info_ptr->height, info_ptr->bit_depth);*/
115  // (void)png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *)width, (png_uint_32 *)height,
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  /*
124  if (color != PNG_COLOR_TYPE_GRAY) {
125  fprintf(stderr, "dec_png: Grayscale image was expected. \n");
126  }
127  */
128  if (color == PNG_COLOR_TYPE_RGB)
129  bit_depth = 24;
130  else if (color == PNG_COLOR_TYPE_RGB_ALPHA)
131  bit_depth = 32;
132 
133  /* Copy image data to output string */
134  n = 0;
135  bytes = bit_depth / 8;
136  clen = (*width) * bytes;
137  for (j = 0; j < *height; j++)
138  {
139  for (k = 0; k < clen; k++)
140  {
141  cout[n] = *(row_pointers[j] + k);
142  n++;
143  }
144  }
145 
146  /* Clean up. */
147  png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
148  return 0;
149 }
int dec_png(unsigned char *pngbuf, g2int *width, g2int *height, unsigned char *cout)
Decode PNG.
Definition: dec_png.c:61
struct png_stream png_stream
Typedef for PNG stream.
Definition: dec_png.c:20
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:35
int64_t g2int
Long integer type.
Definition: grib2.h:33
Header file with internal function prototypes NCEPLIBS-g2c library.