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