/src/gdal/frmts/pcraster/libcsf/putsomec.c
Line | Count | Source |
1 | | #include "csf.h" |
2 | | #include "csfimpl.h" |
3 | | |
4 | | typedef void (*DF)(void *min, void *max, size_t n, const void *buf); |
5 | | |
6 | | /* DET: |
7 | | * while (min is MV) && (i != nrCells) |
8 | | * min = max = buf[i++]; |
9 | | * while (i != nrCells) |
10 | | * if (buf[i] is not MV) |
11 | | * if (buf[i] < min) min = buf[i]; |
12 | | * if (buf[i] > max) max = buf[i]; |
13 | | * i++ |
14 | | */ |
15 | | #define DET(min, max, nrCells, buf, type) \ |
16 | 0 | {\ |
17 | 0 | size_t i=0;\ |
18 | 0 | while (((*(type *)min) == MV_##type) && (i != nrCells))\ |
19 | 0 | (*(type *)max) = (*(type *)min) =\ |
20 | 0 | ((const type *)buf)[i++];\ |
21 | 0 | while (i != nrCells) \ |
22 | 0 | {\ |
23 | 0 | if (((const type *)buf)[i] != MV_##type)\ |
24 | 0 | {\ |
25 | 0 | if (((const type *)buf)[i] < (*(type *)min) )\ |
26 | 0 | (*(type *)min) = ((const type *)buf)[i];\ |
27 | 0 | if (((const type *)buf)[i] > (*(type *)max) )\ |
28 | 0 | (*(type *)max) = ((const type *)buf)[i];\ |
29 | 0 | }\ |
30 | 0 | i++;\ |
31 | 0 | }\ |
32 | 0 | } |
33 | | |
34 | | |
35 | | /* determines new minimum and new maximum |
36 | | * DetMinMax({U}INT[124]|REAL[48]) analyzes |
37 | | * an array of cells and adjust the min and max argument |
38 | | * if necessary. If min and max are not yet set then they |
39 | | * must be MV both. The function |
40 | | * assumes that both min and max are MV if min is MV. |
41 | | */ |
42 | | static void DetMinMaxINT1( |
43 | | void *minIn, /* read-write. adjusted minimum */ |
44 | | void *maxIn, /* read-write. adjusted maximum */ |
45 | | size_t nrCells,/* number of cells in buf */ |
46 | | const void *bufIn) /* cell values to be examined */ |
47 | 0 | { |
48 | 0 | INT1 *min = (INT1 *)minIn; |
49 | 0 | INT1 *max = (INT1 *)maxIn; |
50 | 0 | const INT1 *buf = (const INT1 *)bufIn; |
51 | 0 | DET(min, max, nrCells, buf, INT1); |
52 | 0 | } |
53 | | |
54 | | /* determines new minimum and new maximum |
55 | | * DetMinMax* (* = all cell representation) analyzes |
56 | | * an array of cells and adjust the min and max argument |
57 | | * if necessary. If min and max are not yet set then they |
58 | | * must be MV both. The function |
59 | | * assumes that both min and max are MV if min is MV. |
60 | | */ |
61 | | static void DetMinMaxINT2( |
62 | | void *minIn, /* read-write. adjusted minimum */ |
63 | | void *maxIn, /* read-write. adjusted maximum */ |
64 | | size_t nrCells,/* number of cells in buf */ |
65 | | const void *bufIn) /* cell values to be examined */ |
66 | 0 | { |
67 | 0 | INT2 *min = (INT2 *)minIn; |
68 | 0 | INT2 *max = (INT2 *)maxIn; |
69 | 0 | const INT2 *buf = (const INT2 *)bufIn; |
70 | 0 | DET(min, max, nrCells, buf, INT2); |
71 | 0 | } |
72 | | |
73 | | /* determines new minimum and new maximum |
74 | | * DetMinMax* (* = all cell representation) analyzes |
75 | | * an array of cells and adjust the min and max argument |
76 | | * if necessary. If min and max are not yet set then they |
77 | | * must be MV both. The function |
78 | | * assumes that both min and max are MV if min is MV. |
79 | | */ |
80 | | static void DetMinMaxINT4( |
81 | | void *minIn, /* read-write. adjusted minimum */ |
82 | | void *maxIn, /* read-write. adjusted maximum */ |
83 | | size_t nrCells,/* number of cells in buf */ |
84 | | const void *bufIn) /* cell values to be examined */ |
85 | 0 | { |
86 | 0 | INT4 *min = (INT4 *)minIn; |
87 | 0 | INT4 *max = (INT4 *)maxIn; |
88 | 0 | const INT4 *buf = (const INT4 *)bufIn; |
89 | 0 | DET(min, max, nrCells, buf, INT4); |
90 | 0 | } |
91 | | |
92 | | |
93 | | /* determines new minimum and new maximum |
94 | | * DetMinMax* (* = all cell representation) analyzes |
95 | | * an array of cells and adjust the min and max argument |
96 | | * if necessary. If min and max are not yet set then they |
97 | | * must be MV both. The function |
98 | | * assumes that both min and max are MV if min is MV. |
99 | | */ |
100 | | static void DetMinMaxUINT1( |
101 | | void *minIn, /* read-write. adjusted minimum */ |
102 | | void *maxIn, /* read-write. adjusted maximum */ |
103 | | size_t nrCells,/* number of cells in buf */ |
104 | | const void *bufIn) /* cell values to be examined */ |
105 | 0 | { |
106 | 0 | UINT1 *min = (UINT1 *)minIn; |
107 | 0 | UINT1 *max = (UINT1 *)maxIn; |
108 | 0 | const UINT1 *buf = (const UINT1 *)bufIn; |
109 | 0 | DET(min, max, nrCells, buf, UINT1); |
110 | 0 | } |
111 | | |
112 | | /* determines new minimum and new maximum |
113 | | * DetMinMax* (* = all cell representation) analyzes |
114 | | * an array of cells and adjust the min and max argument |
115 | | * if necessary. If min and max are not yet set then they |
116 | | * must be MV both. The function |
117 | | * assumes that both min and max are MV if min is MV. |
118 | | */ |
119 | | static void DetMinMaxUINT2( |
120 | | void *minIn, /* read-write. adjusted minimum */ |
121 | | void *maxIn, /* read-write. adjusted maximum */ |
122 | | size_t nrCells,/* number of cells in buf */ |
123 | | const void *bufIn) /* cell values to be examined */ |
124 | 0 | { |
125 | 0 | UINT2 *min = (UINT2 *)minIn; |
126 | 0 | UINT2 *max = (UINT2 *)maxIn; |
127 | 0 | const UINT2 *buf = (const UINT2 *)bufIn; |
128 | 0 | DET(min, max, nrCells, buf, UINT2); |
129 | 0 | } |
130 | | |
131 | | /* determines new minimum and new maximum |
132 | | * DetMinMax* (* = all cell representation) analyzes |
133 | | * an array of cells and adjust the min and max argument |
134 | | * if necessary. If min and max are not yet set then they |
135 | | * must be MV both. The function |
136 | | * assumes that both min and max are MV if min is MV. |
137 | | */ |
138 | | static void DetMinMaxUINT4( |
139 | | void *minIn, /* read-write. adjusted minimum */ |
140 | | void *maxIn, /* read-write. adjusted maximum */ |
141 | | size_t nrCells,/* number of cells in buf */ |
142 | | const void *bufIn) /* cell values to be examined */ |
143 | 0 | { |
144 | 0 | UINT4 *min = (UINT4 *)minIn; |
145 | 0 | UINT4 *max = (UINT4 *)maxIn; |
146 | 0 | const UINT4 *buf = (const UINT4 *)bufIn; |
147 | 0 | DET(min, max, nrCells, buf, UINT4); |
148 | 0 | } |
149 | | |
150 | | |
151 | | /* determines new minimum and new maximum |
152 | | * DetMinMax* (* = all cell representation) analyzes |
153 | | * an array of cells and adjust the min and max argument |
154 | | * if necessary. If min and max are not yet set then they |
155 | | * must be MV both. The function |
156 | | * assumes that both min and max are MV if min is MV. |
157 | | */ |
158 | | static void DetMinMaxREAL4( |
159 | | void *minIn, /* read-write. adjusted minimum */ |
160 | | void *maxIn, /* read-write. adjusted maximum */ |
161 | | size_t nrCells,/* number of cells in buf */ |
162 | | const void *bufIn) /* cell values to be examined */ |
163 | 0 | { |
164 | 0 | REAL4 *min = (REAL4 *)minIn; |
165 | 0 | REAL4 *max = (REAL4 *)maxIn; |
166 | 0 | const REAL4 *buf = (const REAL4 *)bufIn; |
167 | 0 | size_t i = 0; |
168 | |
|
169 | 0 | if ( IS_MV_REAL4(min)) |
170 | 0 | { |
171 | 0 | while ( IS_MV_REAL4(min) && (i != nrCells)) |
172 | 0 | *((UINT4 *)min) = ((const UINT4 *)buf)[i++]; |
173 | 0 | *max = *min; |
174 | 0 | } |
175 | 0 | while (i != nrCells) |
176 | 0 | { |
177 | 0 | if (! IS_MV_REAL4(buf+i)) |
178 | 0 | { |
179 | 0 | if (buf[i] < *min ) |
180 | 0 | *min = buf[i]; |
181 | 0 | if (buf[i] > *max) |
182 | 0 | *max = buf[i]; |
183 | 0 | } |
184 | 0 | i++; |
185 | 0 | } |
186 | 0 | } |
187 | | |
188 | | |
189 | | |
190 | | /* determines new minimum and new maximum |
191 | | * DetMinMax* (* = all cell representation) analyzes |
192 | | * an array of cells and adjust the min and max argument |
193 | | * if necessary. If min and max are not yet set then they |
194 | | * must be MV both. The function |
195 | | * assumes that both min and max are MV if min is MV. |
196 | | */ |
197 | | static void DetMinMaxREAL8( |
198 | | void *minIn, /* read-write. adjusted minimum */ |
199 | | void *maxIn, /* read-write. adjusted maximum */ |
200 | | size_t nrCells,/* number of cells in buf */ |
201 | | const void *bufIn) /* cell values to be examined */ |
202 | 0 | { |
203 | 0 | REAL8 *min = (REAL8 *)minIn; |
204 | 0 | REAL8 *max = (REAL8 *)maxIn; |
205 | 0 | const REAL8 *buf = (const REAL8 *)bufIn; |
206 | 0 | size_t i = 0; |
207 | |
|
208 | 0 | if ( IS_MV_REAL8(min)) |
209 | 0 | { |
210 | 0 | while ( IS_MV_REAL8(min) && (i != nrCells)) |
211 | 0 | { |
212 | 0 | ((UINT4 *)min)[0] = ((const UINT4 *)buf)[2*i]; |
213 | 0 | ((UINT4 *)min)[1] = ((const UINT4 *)buf)[(2*i++)+1]; |
214 | 0 | } |
215 | 0 | *max = *min; |
216 | 0 | } |
217 | 0 | while (i != nrCells) |
218 | 0 | { |
219 | 0 | if (! IS_MV_REAL8(buf+i)) |
220 | 0 | { |
221 | 0 | if (buf[i] < *min ) |
222 | 0 | *min = buf[i]; |
223 | 0 | if (buf[i] > *max) |
224 | 0 | *max = buf[i]; |
225 | 0 | } |
226 | 0 | i++; |
227 | 0 | } |
228 | 0 | } |
229 | | |
230 | | |
231 | | /* write a stream of cells |
232 | | * RputSomeCells views a raster as one linear stream of |
233 | | * cells, with row i+1 placed after row i. |
234 | | * In this stream any sequence can be written by specifying an |
235 | | * offset and the number of cells to be written |
236 | | * returns the number of cells written, just as fwrite |
237 | | * |
238 | | * example |
239 | | * .so examples/somecell.tr |
240 | | */ |
241 | | size_t RputSomeCells( |
242 | | MAP *map, /* map handle */ |
243 | | size_t offset, /* offset from pixel (row,col) = (0,0) */ |
244 | | size_t nrCells, /* number of cells to be read */ |
245 | | void *buf)/* read-write. Buffer large enough to |
246 | | * hold nrCells cells in the in-file cell representation |
247 | | * or the in-app cell representation. |
248 | | * If these types are not equal then the buffer is |
249 | | * converted from the in-app to the in-file |
250 | | * cell representation. |
251 | | */ |
252 | 0 | { |
253 | 0 | CSF_FADDR writeAt; |
254 | 0 | CSF_CR cr = map->raster.cellRepr; |
255 | | |
256 | | /* convert */ |
257 | 0 | map->app2file(nrCells, buf); |
258 | | |
259 | |
|
260 | 0 | if (map->minMaxStatus == MM_KEEPTRACK) |
261 | 0 | { |
262 | 0 | const DF detMinMaxFunc[12] = { |
263 | 0 | DetMinMaxUINT1, DetMinMaxUINT2, |
264 | 0 | DetMinMaxUINT4, NULL /* 0x03 */ , |
265 | 0 | DetMinMaxINT1 , DetMinMaxINT2 , |
266 | 0 | DetMinMaxINT4 , NULL /* 0x07 */ , |
267 | 0 | NULL /* 0x08 */ , NULL /* 0x09 */ , |
268 | 0 | DetMinMaxREAL4, DetMinMaxREAL8 }; |
269 | |
|
270 | 0 | void *min = &(map->raster.minVal); |
271 | 0 | void *max = &(map->raster.maxVal); |
272 | |
|
273 | 0 | PRECOND(CSF_UNIQ_CR_MASK(cr) < 12); |
274 | 0 | PRECOND(detMinMaxFunc[CSF_UNIQ_CR_MASK(cr)] != NULL); |
275 | |
|
276 | 0 | detMinMaxFunc[CSF_UNIQ_CR_MASK(cr)](min, max, nrCells, buf); |
277 | |
|
278 | 0 | } |
279 | 0 | else |
280 | 0 | map->minMaxStatus = MM_WRONGVALUE; |
281 | |
|
282 | 0 | writeAt = ((CSF_FADDR)offset) << LOG_CELLSIZE(cr); |
283 | 0 | writeAt += ADDR_DATA; |
284 | 0 | if( csf_fseek(map->fp, writeAt, SEEK_SET) != 0 ) |
285 | 0 | return 0; |
286 | 0 | return(map->write(buf, (size_t)CELLSIZE(cr), (size_t)nrCells, map->fp)); |
287 | 0 | } |