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