GRASS GIS 7 Programmer's Manual  7.0.3(2016)-r00000
read_png.c
Go to the documentation of this file.
1 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <png.h>
17 
18 #include <grass/gis.h>
19 #include "pngdriver.h"
20 
21 static void read_data(png_structp png_ptr, png_bytep data, png_size_t length)
22 {
23  png_size_t check;
24  FILE *fp;
25 
26  if (png_ptr == NULL )
27  return;
28 
29  fp = (FILE *) png_get_io_ptr(png_ptr);
30 
31  if ( fp == NULL )
32  return;
33 
34  /* fread() returns 0 on error, so it is OK to store this in a png_size_t
35  * instead of an int, which is what fread() actually returns.
36  */
37  check = fread(data, 1, length, fp);
38 
39  if (check != length)
40  G_fatal_error("PNG: Read Error");
41 }
42 
43 void read_png(void)
44 {
45  static jmp_buf jbuf;
46  static png_struct *png_ptr;
47  static png_info *info_ptr;
48  FILE *input;
49  int x, y;
50  unsigned int *p;
51  png_bytep line;
52  png_uint_32 i_width, i_height;
53  int depth, color_type;
54 
55  png_ptr =
56  png_create_read_struct(PNG_LIBPNG_VER_STRING, &jbuf, NULL, NULL);
57  if (!png_ptr)
58  G_fatal_error("PNG: couldn't allocate PNG structure");
59 
60  info_ptr = png_create_info_struct(png_ptr);
61  if (!info_ptr)
62  G_fatal_error("PNG: couldn't allocate PNG structure");
63 
64  if (setjmp(png_jmpbuf(png_ptr)))
65  G_fatal_error("error reading PNG file");
66 
67  input = fopen(png.file_name, "rb");
68  if (!input)
69  G_fatal_error("PNG: couldn't open output file %s", png.file_name);
70 
71  png_set_read_fn(png_ptr, input, read_data);
72 
73  png_read_info(png_ptr, info_ptr);
74 
75  png_get_IHDR(png_ptr, info_ptr, &i_width, &i_height,
76  &depth, &color_type, NULL, NULL, NULL);
77 
78  if (depth != 8)
79  G_fatal_error("PNG: input file is not 8-bit");
80 
81  if (i_width != png.width || i_height != png.height)
83  ("PNG: input file has incorrect dimensions: expected: %dx%d got: %lux%lu",
84  png.width, png.height, (unsigned long) i_width, (unsigned long) i_height);
85 
86  if (png.true_color) {
87  if (color_type != PNG_COLOR_TYPE_RGB_ALPHA)
88  G_fatal_error("PNG: input file is not RGBA");
89  }
90  else {
91  if (color_type != PNG_COLOR_TYPE_PALETTE)
92  G_fatal_error("PNG: input file is not indexed color");
93  }
94 
95  if (!png.true_color && png.has_alpha) {
96  png_bytep trans;
97  int num_trans;
98 
99  png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
100 
101  if (num_trans != 1 || trans[0] != 0)
102  G_fatal_error("PNG: input file has invalid palette");
103  }
104 
105  if (png.true_color)
106  png_set_invert_alpha(png_ptr);
107  else {
108  png_colorp png_pal;
109  int num_palette;
110  int i;
111 
112  png_get_PLTE(png_ptr, info_ptr, &png_pal, &num_palette);
113 
114  if (num_palette > 256)
115  num_palette = 256;
116 
117  for (i = 0; i < num_palette; i++) {
118  png.palette[i][0] = png_pal[i].red;
119  png.palette[i][1] = png_pal[i].green;
120  png.palette[i][2] = png_pal[i].blue;
121  }
122  }
123 
124  line = G_malloc(png.width * 4);
125 
126  for (y = 0, p = png.grid; y < png.height; y++) {
127  png_bytep q = line;
128 
129  png_read_row(png_ptr, q, NULL);
130 
131  if (png.true_color)
132  for (x = 0; x < png.width; x++, p++) {
133  int r = *q++;
134  int g = *q++;
135  int b = *q++;
136  int a = *q++;
137  unsigned int c = png_get_color(r, g, b, a);
138 
139  *p = c;
140  }
141  else
142  for (x = 0; x < png.width; x++, p++, q++)
143  *p = (png_byte) * q;
144  }
145 
146  G_free(line);
147 
148  png_read_end(png_ptr, NULL);
149 
150  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
151 
152  fclose(input);
153 }
int width
Definition: pngdriver.h:43
GRASS png display driver - header file.
unsigned char palette[256][4]
Definition: pngdriver.h:45
int height
Definition: pngdriver.h:43
#define NULL
Definition: ccmath.h:32
struct png_state png
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:159
unsigned int png_get_color(int r, int g, int b, int a)
Definition: color_table.c:120
double b
void read_png(void)
Definition: read_png.c:43
char * file_name
Definition: pngdriver.h:33
unsigned int * grid
Definition: pngdriver.h:44
float g
Definition: named_colr.c:8
int has_alpha
Definition: pngdriver.h:36
int true_color
Definition: pngdriver.h:35
double r
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149