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