GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
Loading...
Searching...
No Matches
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 = png_create_read_struct(PNG_LIBPNG_VER_STRING, &jbuf, NULL, NULL);
58 if (!png_ptr)
59 G_fatal_error(_("Unable to allocate PNG structure"));
60
61 info_ptr = png_create_info_struct(png_ptr);
62 if (!info_ptr)
63 G_fatal_error(_("Unable to allocate PNG structure"));
64
65 if (setjmp(png_jmpbuf(png_ptr)))
66 G_fatal_error(_("Unable to read PNG file"));
67
68 input = fopen(png.file_name, "rb");
69 if (!input)
70 G_fatal_error(_("Unable to open output file <%s>"), png.file_name);
71
72 png_set_read_fn(png_ptr, input, read_data);
73
74 png_read_info(png_ptr, info_ptr);
75
76 png_get_IHDR(png_ptr, info_ptr, &i_width, &i_height, &depth, &color_type,
77 NULL, NULL, NULL);
78
79 if (depth != 8)
80 G_fatal_error(_("Input PNG file is not 8-bit"));
81
82 if (i_width != (unsigned long)png.width ||
83 i_height != (unsigned long)png.height)
84 G_fatal_error(_("Input PNG file has incorrect dimensions: expected: "
85 "%dx%d got: %lux%lu"),
86 png.width, png.height, (unsigned long)i_width,
87 (unsigned long)i_height);
88
89 if (png.true_color) {
90 if (color_type != PNG_COLOR_TYPE_RGB_ALPHA)
91 G_fatal_error(_("Input PNG file is not RGBA"));
92 }
93 else {
94 if (color_type != PNG_COLOR_TYPE_PALETTE)
95 G_fatal_error(_("Input PNG file is not indexed color"));
96 }
97
98 if (!png.true_color && png.has_alpha) {
99 png_bytep trans;
100 int num_trans;
101
102 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
103
104 if (num_trans != 1 || trans[0] != 0)
105 G_fatal_error(_("Input PNG file has invalid palette"));
106 }
107
108 if (png.true_color)
109 png_set_invert_alpha(png_ptr);
110 else {
111 png_colorp png_pal;
112 int num_palette;
113 int i;
114
115 png_get_PLTE(png_ptr, info_ptr, &png_pal, &num_palette);
116
117 if (num_palette > 256)
118 num_palette = 256;
119
120 for (i = 0; i < num_palette; i++) {
121 png.palette[i][0] = png_pal[i].red;
122 png.palette[i][1] = png_pal[i].green;
123 png.palette[i][2] = png_pal[i].blue;
124 }
125 }
126
127 line = G_malloc(png.width * 4);
128
129 for (y = 0, p = png.grid; y < png.height; y++) {
130 png_bytep q = line;
131
132 png_read_row(png_ptr, q, NULL);
133
134 if (png.true_color)
135 for (x = 0; x < png.width; x++, p++) {
136 int r = *q++;
137 int g = *q++;
138 int b = *q++;
139 int a = *q++;
140 unsigned int c = png_get_color(r, g, b, a);
141
142 *p = c;
143 }
144 else
145 for (x = 0; x < png.width; x++, p++, q++)
146 *p = (png_byte)*q;
147 }
148
149 G_free(line);
150
151 png_read_end(png_ptr, NULL);
152
153 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
154
155 fclose(input);
156}
void G_free(void *buf)
Free allocated memory.
Definition alloc.c:150
#define NULL
Definition ccmath.h:32
unsigned int png_get_color(int r, int g, int b, int a)
double b
double r
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition gis/error.c:159
float g
Definition named_colr.c:7
struct png_state png
GRASS png display driver - header file.
void read_png(void)
Definition read_png.c:45
#define x