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