GRASS GIS 8 Programmer's Manual 8.2.1RC1(2022)-exported
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
23static 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
45void 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 to 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: alloc.c:149
#define NULL
Definition: ccmath.h:32
unsigned int png_get_color(int r, int g, int b, int a)
Definition: color_table.c:120
double b
double r
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:160
float g
Definition: named_colr.c:8
struct png_state png
GRASS png display driver - header file.
void read_png(void)
Definition: read_png.c:45
char * file_name
Definition: pngdriver.h:33
int has_alpha
Definition: pngdriver.h:36
int true_color
Definition: pngdriver.h:35
int height
Definition: pngdriver.h:43
unsigned int * grid
Definition: pngdriver.h:44
unsigned char palette[256][4]
Definition: pngdriver.h:45
int width
Definition: pngdriver.h:43
#define x