NCEPLIBS-g2c  1.7.0
enc_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 
21 typedef struct png_stream png_stream;
23 void user_write_data(png_structp, png_bytep, png_uint_32);
24 void user_flush_data(png_structp);
25 
36 void
37 user_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
38 {
39  unsigned char *ptr;
40  g2int offset;
41  png_stream *mem;
42 
43  mem = (png_stream *)png_get_io_ptr(png_ptr);
44  ptr = mem->stream_ptr;
45  offset = mem->stream_len;
46  memcpy(ptr + offset, data, length);
47  mem->stream_len += length;
48 }
49 
57 void user_flush_data(png_structp png_ptr)
58 {
59 }
60 
74 int
75 enc_png(unsigned char *data, g2int width, g2int height, g2int nbits,
76  unsigned char *pngbuf)
77 {
78  int color_type;
79  g2int j, bytes, pnglen, bit_depth;
80  png_structp png_ptr;
81  png_infop info_ptr;
82  png_bytep **row_pointers;
83  png_stream write_io_ptr;
84 
85  /* Create and initialize png_structs. */
86  if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
87  return -1;
88 
89  if (!(info_ptr = png_create_info_struct(png_ptr)))
90  {
91  png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
92  return -2;
93  }
94 
95  /* Set Error callback. */
96  if (setjmp(png_jmpbuf(png_ptr)))
97  {
98  png_destroy_write_struct(&png_ptr, &info_ptr);
99  return -3;
100  }
101 
102  /* Initialize info for writing PNG stream to memory. */
103  write_io_ptr.stream_ptr = (png_voidp)pngbuf;
104  write_io_ptr.stream_len = 0;
105 
106  /* Set new custom write functions. */
107  png_set_write_fn(png_ptr, (png_voidp)&write_io_ptr, (png_rw_ptr)user_write_data,
108  (png_flush_ptr)user_flush_data);
109 
110  /* Set the image size, colortype, filter type, etc... */
111  bit_depth = nbits;
112  color_type = PNG_COLOR_TYPE_GRAY;
113  if (nbits == 24)
114  {
115  bit_depth = 8;
116  color_type = PNG_COLOR_TYPE_RGB;
117  }
118  else if (nbits == 32)
119  {
120  bit_depth = 8;
121  color_type = PNG_COLOR_TYPE_RGB_ALPHA;
122  }
123  png_set_IHDR(png_ptr, info_ptr, width, height,
124  bit_depth, color_type, PNG_INTERLACE_NONE,
125  PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
126 
127  /* Put image data into the PNG info structure. */
128  bytes = nbits / 8;
129  row_pointers = malloc(height * sizeof(png_bytep));
130  for (j = 0; j < height; j++)
131  row_pointers[j] = (png_bytep *)(data + (j * width * bytes));
132  png_set_rows(png_ptr, info_ptr, (png_bytepp)row_pointers);
133 
134  /* Do the PNG encoding, and write out PNG stream. */
135  png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
136 
137  /* Clean up. */
138  png_destroy_write_struct(&png_ptr, &info_ptr);
139  free(row_pointers);
140  pnglen = write_io_ptr.stream_len;
141  return pnglen;
142 }
enc_png
int enc_png(unsigned char *data, g2int width, g2int height, g2int nbits, unsigned char *pngbuf)
Encode PNG.
Definition: enc_png.c:75
grib2_int.h
Header file with internal function prototypes NCEPLIBS-g2c library.
png_stream
struct png_stream png_stream
Typedef for PNG stream.
Definition: enc_png.c:21
user_write_data
void user_write_data(png_structp, png_bytep, png_uint_32)
Custom write function used to that libpng will write to memory location instead of a file on disk.
Definition: enc_png.c:37
g2int
int64_t g2int
Long integer type.
Definition: grib2.h:28
user_flush_data
void user_flush_data(png_structp)
Dummy Custom flush function.
Definition: enc_png.c:57