GRASS Programmer's Manual  6.4.4(2014)-r
read_png.c
Go to the documentation of this file.
1 
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <png.h>
5 
6 #include <grass/gis.h>
7 #include "pngdriver.h"
8 
9 void read_png(void)
10 {
11  static jmp_buf jbuf;
12  static png_struct *png_ptr;
13  static png_info *info_ptr;
14  FILE *input;
15  int x, y;
16  unsigned int *p;
17  png_bytep line;
18  png_uint_32 i_width, i_height;
19  int depth, color_type;
20 
21  png_ptr =
22  png_create_read_struct(PNG_LIBPNG_VER_STRING, &jbuf, NULL, NULL);
23  if (!png_ptr)
24  G_fatal_error("PNG: couldn't allocate PNG structure");
25 
26  info_ptr = png_create_info_struct(png_ptr);
27  if (!info_ptr)
28  G_fatal_error("PNG: couldn't allocate PNG structure");
29 
30  if (setjmp(png_jmpbuf(png_ptr)))
31  G_fatal_error("error reading PNG file");
32 
33  input = fopen(file_name, "rb");
34  if (!input)
35  G_fatal_error("PNG: couldn't open output file %s", file_name);
36 
37  png_init_io(png_ptr, input);
38 
39  png_read_info(png_ptr, info_ptr);
40 
41  png_get_IHDR(png_ptr, info_ptr, &i_width, &i_height,
42  &depth, &color_type, NULL, NULL, NULL);
43 
44  if (depth != 8)
45  G_fatal_error("PNG: input file is not 8-bit");
46 
47  if (i_width != width || i_height != height)
49  ("PNG: input file has incorrect dimensions: expected: %dx%d got: %lux%lu",
50  width, height, (unsigned long) i_width, (unsigned long) i_height);
51 
52  if (true_color) {
53  if (color_type != PNG_COLOR_TYPE_RGB_ALPHA)
54  G_fatal_error("PNG: input file is not RGBA");
55  }
56  else {
57  if (color_type != PNG_COLOR_TYPE_PALETTE)
58  G_fatal_error("PNG: input file is not indexed color");
59  }
60 
61  if (!true_color && has_alpha) {
62  png_bytep trans;
63  int num_trans;
64 
65  png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
66 
67  if (num_trans != 1 || trans[0] != 0)
68  G_fatal_error("PNG: input file has invalid palette");
69  }
70 
71  if (true_color)
72  png_set_invert_alpha(png_ptr);
73  else {
74  png_colorp png_pal;
75  int num_palette;
76  int i;
77 
78  png_get_PLTE(png_ptr, info_ptr, &png_pal, &num_palette);
79 
80  if (num_palette > 256)
81  num_palette = 256;
82 
83  for (i = 0; i < num_palette; i++) {
84  png_palette[i][0] = png_pal[i].red;
85  png_palette[i][1] = png_pal[i].green;
86  png_palette[i][2] = png_pal[i].blue;
87  }
88  }
89 
90  line = G_malloc(width * 4);
91 
92  for (y = 0, p = grid; y < height; y++) {
93  png_bytep q = line;
94 
95  png_read_row(png_ptr, q, NULL);
96 
97  if (true_color)
98  for (x = 0; x < width; x++, p++) {
99  int r = *q++;
100  int g = *q++;
101  int b = *q++;
102  int a = *q++;
103  unsigned int c = get_color(r, g, b, a);
104 
105  *p = c;
106  }
107  else
108  for (x = 0; x < width; x++, p++, q++)
109  *p = (png_byte) * q;
110  }
111 
112  G_free(line);
113 
114  png_read_end(png_ptr, NULL);
115 
116  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
117 
118  fclose(input);
119 }
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
float b
Definition: named_colr.c:8
#define NULL
Definition: strings.c:26
int has_alpha
tuple q
Definition: forms.py:2018
float r
Definition: named_colr.c:8
tuple width
const struct transport * trans
Definition: com_io.c:143
unsigned char * grid
int y
Definition: plot.c:34
int true_color
char * file_name
void read_png(void)
Definition: read_png.c:9
float g
Definition: named_colr.c:8
unsigned char png_palette[256][4]
unsigned int get_color(int r, int g, int b, int a)
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int height