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(&region);
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