1 #include <grass/gis.h>
2 #include <grass/raster.h>
3 #include <grass/vector.h>
4 #include "local.h"
5
6
7 struct Cell_head region, page;
8
9 static union
10 {
11 CELL **cell;
12 DCELL **dcell;
13 } raster;
14
15 static int max_rows;
16 static int at_row;
17 static CELL cat;
18 static DCELL dcat;
19 static int cur_x, cur_y;
20 static int format;
21 static int dense;
22 static CELL *cell;
23 static DCELL *dcell;
24 static char **null_flags;
25 static char isnull;
26
27 /* function prototypes */
28 static int configure_plot(void);
29 static int cell_dot(int, int);
30 static int dcell_dot(int, int);
31 static int cont(int, int);
32 static int move(int, int);
33 static int (*dot) (int, int);
34
35
begin_rasterization(int cache_mb,int f,int do_dense)36 int begin_rasterization(int cache_mb, int f, int do_dense)
37 {
38 int i;
39 double row_mb;
40 int pages;
41 size_t size;
42
43 dense = (do_dense != 0);
44
45 /* otherwise get complaints about window changes */
46 G_suppress_warnings(1);
47
48 format = f;
49
50 G_get_set_window(®ion);
51 G_get_set_window(&page);
52
53 row_mb = (double) region.cols * (sizeof(char) + Rast_cell_size(f)) /
54 (1 << 20);
55
56 max_rows = cache_mb / row_mb;
57 if (max_rows < 1)
58 max_rows = 4;
59
60 pages = (region.rows + max_rows - 1) / max_rows;
61
62 if (max_rows > region.rows)
63 max_rows = region.rows;
64
65 G_debug(1, "%d of %d rows are cached", max_rows, region.rows);
66
67 size = (size_t) max_rows * region.cols;
68 switch (format) {
69 case CELL_TYPE:
70 raster.cell =
71 (CELL **) G_calloc(max_rows * sizeof(char), sizeof(CELL *));
72 raster.cell[0] = (CELL *) G_calloc(size * sizeof(char), sizeof(CELL));
73 for (i = 1; i < max_rows; i++)
74 raster.cell[i] = raster.cell[i - 1] + region.cols;
75 dot = cell_dot;
76 break;
77
78 case DCELL_TYPE:
79 raster.dcell =
80 (DCELL **) G_calloc(max_rows * sizeof(char), sizeof(DCELL *));
81 raster.dcell[0] =
82 (DCELL *) G_calloc(size * sizeof(char), sizeof(DCELL));
83 for (i = 1; i < max_rows; i++)
84 raster.dcell[i] = raster.dcell[i - 1] + region.cols;
85 dot = dcell_dot;
86 break;
87 }
88
89 null_flags = (char **)G_calloc(max_rows * sizeof(char), sizeof(char *));
90 null_flags[0] = (char *)G_calloc(size * sizeof(char), sizeof(char));
91 for (i = 1; i < max_rows; i++)
92 null_flags[i] = null_flags[i - 1] + region.cols;
93
94 at_row = 0;
95 configure_plot();
96
97 return pages;
98 }
99
100
configure_plot(void)101 static int configure_plot(void)
102 {
103 int i, j;
104 int nrows;
105 int ncols;
106
107 nrows = region.rows - at_row;
108 if (nrows <= 0)
109 return 1;
110
111 if (nrows > max_rows)
112 nrows = max_rows;
113
114 ncols = region.cols;
115
116 /* zero the raster */
117 switch (format) {
118 case CELL_TYPE:
119 for (i = 0; i < nrows; i++)
120 for (j = 0; j < ncols; j++)
121 raster.cell[i][j] = 0;
122 break;
123 case DCELL_TYPE:
124 for (i = 0; i < nrows; i++)
125 for (j = 0; j < ncols; j++)
126 raster.dcell[i][j] = 0;
127 break;
128 }
129
130 for (i = 0; i < nrows; i++)
131 for (j = 0; j < ncols; j++)
132 null_flags[i][j] = 1;
133
134 /* change the region */
135 page.north = region.north - at_row * region.ns_res;
136 page.south = page.north - nrows * region.ns_res;
137 G_set_window(&page);
138
139 /* configure the plot routines */
140 if (dense)
141 setup_plot(0, page.rows, 0, page.cols, dot);
142 else
143 G_setup_plot(-0.5, page.rows - 0.5, -0.5, page.cols - 0.5, move, cont);
144
145 return 0;
146 }
147
148
output_raster(int fd)149 int output_raster(int fd)
150 {
151 int i;
152
153 for (i = 0; i < page.rows; i++, at_row++) {
154 G_percent(i, page.rows, 2);
155 switch (format) {
156 case CELL_TYPE:
157 cell = raster.cell[i];
158
159 /* insert the NULL values */
160 Rast_insert_c_null_values(cell, null_flags[i], page.cols);
161 Rast_put_c_row(fd, cell);
162 break;
163 case DCELL_TYPE:
164 dcell = raster.dcell[i];
165
166 /* insert the NULL values */
167 Rast_insert_d_null_values(dcell, null_flags[i], page.cols);
168 Rast_put_d_row(fd, dcell);
169 break;
170 }
171 }
172 G_percent(1, 1, 1);
173
174 return configure_plot();
175 }
176
set_cat(CELL x)177 int set_cat(CELL x)
178 {
179 cat = x;
180 if ((isnull = ISNULL(&cat)))
181 cat = 0;
182
183 return 0;
184 }
185
set_dcat(DCELL x)186 int set_dcat(DCELL x)
187 {
188 dcat = x;
189 if ((isnull = ISDNULL(&dcat)))
190 dcat = 0;
191
192 return 0;
193 }
194
move(int x,int y)195 static int move(int x, int y)
196 {
197 cur_x = x;
198 cur_y = y;
199
200 return 0;
201 }
202
cont(int x,int y)203 static int cont(int x, int y)
204 {
205 if (cur_x < 0 && x < 0) {
206 move(x, y);
207 return 0;
208 }
209 if (cur_y < 0 && y < 0) {
210 move(x, y);
211 return 0;
212 }
213 if (cur_x >= page.cols && x >= page.cols) {
214 move(x, y);
215 return 0;
216 }
217 if (cur_y >= page.rows && y >= page.rows) {
218 move(x, y);
219 return 0;
220 }
221
222 G_bresenham_line(cur_x, cur_y, x, y, dot);
223 move(x, y);
224
225 return 0;
226 }
227
cell_dot(int x,int y)228 static int cell_dot(int x, int y)
229 {
230 if (x >= 0 && x < page.cols && y >= 0 && y < page.rows) {
231 raster.cell[y][x] = cat;
232 null_flags[y][x] = isnull;
233 }
234
235 return 0;
236 }
237
dcell_dot(int x,int y)238 static int dcell_dot(int x, int y)
239 {
240 if (x >= 0 && x < page.cols && y >= 0 && y < page.rows) {
241 raster.dcell[y][x] = dcat;
242 null_flags[y][x] = isnull;
243 }
244
245 return 0;
246 }
247