GRASS 8 Programmer's Manual 8.6.0dev(2026)-c83afef6d3
Loading...
Searching...
No Matches
pngdriver/raster.c
Go to the documentation of this file.
1/*!
2 \file lib/pngdriver/raster.c
3
4 \brief GRASS png display driver - draw raster
5
6 SPDX-FileCopyrightText: 2003-2014 Per Henrik Johansen
7 SPDX-FileCopyrightText: GRASS Development Team
8 SPDX-License-Identifier: GPL-2.0-or-later
9
10 \author Per Henrik Johansen (original contributor)
11 \author Glynn Clements
12 */
13
14#include <string.h>
15#include <math.h>
16#include <grass/gis.h>
17#include "driver.h"
18#include "pngdriver.h"
19
20#ifndef min
21#define min(a, b) ((a) < (b) ? (a) : (b))
22#endif
23#ifndef max
24#define max(a, b) ((a) > (b) ? (a) : (b))
25#endif
26
27static int *trans;
28static int ncols;
29static int nalloc;
30static int masked;
31static int src[2][2];
32static int dst[2][2];
33
34static double scale(double k, const int src[2], const int dst[2])
35{
36 return dst[0] +
37 (double)(k - src[0]) * (dst[1] - dst[0]) / (src[1] - src[0]);
38}
39
40static int scale_fwd_y(int sy)
41{
42 return (int)floor(scale(sy, src[1], dst[1]) + 0.5);
43}
44
45static int scale_rev_x(int dx)
46{
47 return (int)floor(scale(dx + 0.5, dst[0], src[0]));
48}
49
50static int next_row(int sy, int dy)
51{
52 sy++;
53
54 for (;;) {
55 int y = scale_fwd_y(sy);
56
57 if (y > dy)
58 return sy - 1;
59 sy++;
60 }
61}
62
63static void alloc_buffers(void)
64{
65 if (nalloc >= ncols)
66 return;
67
68 nalloc = ncols;
69 trans = G_realloc(trans, nalloc * sizeof(int));
70}
71
72/*!
73 \brief Start drawing raster
74
75 \param mask non-zero int for mask
76 \param s source (map) extent (left, right, top, bottom)
77 \param fd destination (image) extent (left, right, top, bottom)
78 */
79void PNG_begin_raster(int mask, int s[2][2], double fd[2][2])
80{
81 int d[2][2];
82 int i;
83
84 d[0][0] = (int)floor(fd[0][0] + 0.5);
85 d[0][1] = (int)floor(fd[0][1] + 0.5);
86 d[1][0] = (int)floor(fd[1][0] + 0.5);
87 d[1][1] = (int)floor(fd[1][1] + 0.5);
88
89 ncols = d[0][1] - d[0][0];
90
91 memcpy(src, s, sizeof(src));
92 memcpy(dst, d, sizeof(dst));
93 masked = mask;
94
95 alloc_buffers();
96
97 for (i = 0; i < ncols; i++)
98 trans[i] = scale_rev_x(d[0][0] + i);
99}
100
101/*!
102 \brief Draw raster row
103
104 \param n number of cells
105 \param row raster row (starts at 0)
106 \param red,grn,blu,nul red,green,blue and null value
107
108 \return next row
109 */
110int PNG_raster(G_UNUSED int n, int row, const unsigned char *red,
111 const unsigned char *grn, const unsigned char *blu,
112 const unsigned char *nul)
113{
114 int d_y0 = scale_fwd_y(row + 0);
115 int d_y1 = scale_fwd_y(row + 1);
116 int d_rows = d_y1 - d_y0;
117 int x0 = max(png.clip_left - dst[0][0], 0);
118 int x1 = min(png.clip_rite - dst[0][0], ncols);
119 int y0 = max(png.clip_top - d_y0, 0);
120 int y1 = min(png.clip_bot - d_y0, d_rows);
121 int x, y;
122
123 if (y1 <= y0)
124 return next_row(row, d_y1);
125
126 for (x = x0; x < x1; x++) {
127 int xx = dst[0][0] + x;
128 int j = trans[x];
129 int c;
130
131 if (masked && nul && nul[j])
132 continue;
133
134 c = png_get_color(red[j], grn[j], blu[j], 0);
135
136 for (y = y0; y < y1; y++) {
137 int yy = d_y0 + y;
138
139 png.grid[yy * png.width + xx] = c;
140 }
141 }
142
143 png.modified = 1;
144
145 return next_row(row, d_y1);
146}
unsigned int png_get_color(int r, int g, int b, int a)
#define G_realloc(p, n)
Definition defs/gis.h:138
#define G_UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:43
struct png_state png
void PNG_begin_raster(int mask, int s[2][2], double fd[2][2])
Start drawing raster.
int PNG_raster(int n, int row, const unsigned char *red, const unsigned char *grn, const unsigned char *blu, const unsigned char *nul)
Draw raster row.
#define min(a, b)
#define max(a, b)
GRASS png display driver - header file.
#define x