5
#include <grass/raster3d.h>
7
/*--------------------------------------------------------------------------*/
9
static unsigned char clearMask[9] =
10
{ 255, 128, 192, 224, 240, 248, 252, 254, 255 };
12
/*---------------------------------------------------------------------------*/
14
static void Rast3d_float2xdrFloat(const float *f, float *xdrf)
16
G_xdr_put_float(xdrf, f);
19
/*---------------------------------------------------------------------------*/
21
static void Rast3d_double2xdrDouble(const double *d, double *xdrd)
23
G_xdr_put_double(xdrd, d);
26
/*---------------------------------------------------------------------------*/
28
static void Rast3d_truncFloat(float *f, int p)
32
if ((p == -1) || (p >= 23))
35
c = (unsigned char *)f;
39
*c++ &= clearMask[(p + 1) % 8];
47
*c++ &= clearMask[(p + 1) % 8];
53
*c &= clearMask[(p + 1) % 8];
57
/*---------------------------------------------------------------------------*/
59
static void Rast3d_truncDouble(double *d, int p)
63
if ((p == -1) || (p >= 52))
66
c = (unsigned char *)d;
70
*c++ &= clearMask[(p + 4) % 8];
82
*c++ &= clearMask[(p + 4) % 8];
93
*c++ &= clearMask[(p + 4) % 8];
103
*c++ &= clearMask[(p + 4) % 8];
112
*c++ &= clearMask[(p + 4) % 8];
120
*c++ &= clearMask[(p + 4) % 8];
126
*c &= clearMask[(p + 4) % 8];
130
/*---------------------------------------------------------------------------*/
132
static void Rast3d_float2Double(float *f, double *d)
134
unsigned char *c1, *c2, sign, c;
137
c1 = (unsigned char *)f;
138
c2 = (unsigned char *)d;
140
sign = (*c1 & (unsigned char)128);
141
e = (((*c1 & (unsigned char)127) << 1) |
142
((*(c1 + 1) & (unsigned char)128) >> 7));
144
if ((*c1 != 0) || (*(c1 + 1) != 0) || (*(c1 + 2) != 0) ||
155
*c2++ |= ((*c1 & (unsigned char)127) >> 3);
157
*c2 = ((*c1++ & (unsigned char)7) << 5);
160
*c2 = ((*c1++ & (unsigned char)7) << 5);
163
*c2++ = ((*c1 & (unsigned char)7) << 5);
165
*c2++ = (unsigned char)0;
166
*c2++ = (unsigned char)0;
167
*c2 = (unsigned char)0;
170
/*---------------------------------------------------------------------------*/
172
static int Rast3d_compareFloats(float *f1, int p1, float *f2, int p2)
174
unsigned char *c1, *c2;
177
if (Rast3d_is_null_value_num(f1, FCELL_TYPE))
178
return Rast3d_is_null_value_num(f2, FCELL_TYPE);
180
Rast3d_float2xdrFloat(f1, &xdrf1);
181
Rast3d_float2xdrFloat(f2, &xdrf2);
183
c1 = (unsigned char *)&xdrf1;
184
c2 = (unsigned char *)&xdrf2;
186
/* printf ("%d %d (%d %d %d %d) (%d %d %d %d) %d\n", p1, p2, *c1, *(c1 + 1), *(c1 + 2), *(c1 + 3), *c2, *(c2 + 1), *(c2 + 2), *(c2 + 3), *f1 == *f2); */
188
if ((p1 != -1) && (p1 < 23) && ((p1 < p2) || (p2 == -1)))
189
Rast3d_truncFloat(&xdrf2, p1);
190
if ((p2 != -1) && (p2 < 23) && ((p2 < p1) || (p1 == -1)))
191
Rast3d_truncFloat(&xdrf1, p2);
193
/* printf ("%d %d (%d %d %d %d) (%d %d %d %d) %d\n", p1, p2, *c1, *(c1 + 1), *(c1 + 2), *(c1 + 3), *c2, *(c2 + 1), *(c2 + 2), *(c2 + 3), *f1 == *f2); */
195
return (*c1 == *c2) && (*(c1 + 1) == *(c2 + 1)) &&
196
(*(c1 + 2) == *(c2 + 2))
197
&& (*(c1 + 3) == *(c2 + 3));
201
/*---------------------------------------------------------------------------*/
203
static int Rast3d_compareDoubles(double *d1, int p1, double *d2, int p2)
205
unsigned char *c1, *c2;
208
if (Rast3d_is_null_value_num(d1, DCELL_TYPE))
209
return Rast3d_is_null_value_num(d2, DCELL_TYPE);
211
Rast3d_double2xdrDouble(d1, &xdrd1);
212
Rast3d_double2xdrDouble(d2, &xdrd2);
214
c1 = (unsigned char *)&xdrd1;
215
c2 = (unsigned char *)&xdrd2;
217
/* printf ("%d %d (%d %d %d %d %d %d %d %d) (%d %d %d %d %d %d %d %d)\n", p1, p2, *c1, *(c1 + 1), *(c1 + 2), *(c1 + 3), *(c1 + 4), *(c1 + 5), *(c1 + 6), *(c1 + 7), *c2, *(c2 + 1), *(c2 + 2), *(c2 + 3), *(c2 + 4), *(c2 + 5), *(c2 + 6), *(c2 + 7)); */
219
if ((p1 != -1) && (p1 < 52) && ((p1 < p2) || (p2 == -1)))
220
Rast3d_truncDouble(&xdrd2, p1);
221
if ((p2 != -1) && (p2 < 52) && ((p2 < p1) || (p1 == -1)))
222
Rast3d_truncDouble(&xdrd1, p2);
224
/* printf ("%d %d (%d %d %d %d %d %d %d %d) (%d %d %d %d %d %d %d %d)\n", p1, p2, *c1, *(c1 + 1), *(c1 + 2), *(c1 + 3), *(c1 + 4), *(c1 + 5), *(c1 + 6), *(c1 + 7), *c2, *(c2 + 1), *(c2 + 2), *(c2 + 3), *(c2 + 4), *(c2 + 5), *(c2 + 6), *(c2 + 7)); */
226
return (*c1 == *c2) && (*(c1 + 1) == *(c2 + 1)) &&
227
(*(c1 + 2) == *(c2 + 2))
228
&& (*(c1 + 3) == *(c2 + 3)) && (*(c1 + 4) == *(c2 + 4))
229
&& (*(c1 + 5) == *(c2 + 5)) && (*(c1 + 6) == *(c2 + 6))
230
&& (*(c1 + 7) == *(c2 + 7));
234
/*---------------------------------------------------------------------------*/
236
static int Rast3d_compareFloatDouble(float *f, int p1, double *d, int p2)
238
unsigned char *c1, *c2;
240
double xdrd, xdrd2, dTmp;
242
if (Rast3d_is_null_value_num(f, FCELL_TYPE))
243
return Rast3d_is_null_value_num(d, DCELL_TYPE);
245
/* need this since assigning a double to a float actually may change the */
246
/* bit pattern. an example (in xdr format) is the double */
247
/* (63 237 133 81 81 108 3 32) which truncated to 23 bits precision should */
248
/* become (63 237 133 81 64 0 0 0). however assigned to a float it becomes */
249
/* (63 237 133 81 96 0 0 0). */
253
Rast3d_float2xdrFloat(f, &xdrf);
254
Rast3d_float2Double(&xdrf, &xdrd2);
255
Rast3d_double2xdrDouble(&dTmp, &xdrd);
257
c1 = (unsigned char *)&xdrd2;
258
c2 = (unsigned char *)&xdrd;
260
/* printf ("%d %d (%d %d %d %d) (%d %d %d %d %d %d %d %d) (%d %d %d %d %d %d %d %d)\n", p1, p2, *((unsigned char *) &xdrf), *(((unsigned char *) &xdrf) + 1), *(((unsigned char *) &xdrf) + 2), *(((unsigned char *) &xdrf) + 3), *c1, *(c1 + 1), *(c1 + 2), *(c1 + 3), *(c1 + 4), *(c1 + 5), *(c1 + 6), *(c1 + 7), *c2, *(c2 + 1), *(c2 + 2), *(c2 + 3), *(c2 + 4), *(c2 + 5), *(c2 + 6), *(c2 + 7)); */
263
if (((p1 != -1) && ((p1 < p2) || (p2 == -1))) ||
264
((p1 == -1) && ((p2 > 23) || (p2 == -1))))
265
Rast3d_truncDouble(&xdrd, (p1 != -1 ? p1 : 23));
266
if ((p2 != -1) && (p2 < 23) && ((p2 < p1) || (p1 == -1)))
267
Rast3d_truncDouble(&xdrd2, p2);
269
/* printf ("%d %d (%d %d %d %d) (%d %d %d %d %d %d %d %d) (%d %d %d %d %d %d %d %d)\n", p1, p2, *((unsigned char *) &xdrf), *(((unsigned char *) &xdrf) + 1), *(((unsigned char *) &xdrf) + 2), *(((unsigned char *) &xdrf) + 3), *c1, *(c1 + 1), *(c1 + 2), *(c1 + 3), *(c1 + 4), *(c1 + 5), *(c1 + 6), *(c1 + 7), *c2, *(c2 + 1), *(c2 + 2), *(c2 + 3), *(c2 + 4), *(c2 + 5), *(c2 + 6), *(c2 + 7)); */
271
return (*c1 == *c2) && (*(c1 + 1) == *(c2 + 1)) &&
272
(*(c1 + 2) == *(c2 + 2))
273
&& (*(c1 + 3) == *(c2 + 3)) && (*(c1 + 4) == *(c2 + 4))
274
&& (*(c1 + 5) == *(c2 + 5)) && (*(c1 + 6) == *(c2 + 6))
275
&& (*(c1 + 7) == *(c2 + 7));
278
/*---------------------------------------------------------------------------*/
280
static void compareFilesNocache(void *map, void *map2)
282
double n1 = 0, n2 = 0;
285
int x, y, z, correct;
287
int tileX, tileY, tileZ, typeIntern, typeIntern2;
290
p1 = Rast3d_tile_precision_map(map);
291
p2 = Rast3d_tile_precision_map(map2);
293
Rast3d_get_tile_dimensions_map(map, &tileX, &tileY, &tileZ);
294
Rast3d_get_nof_tiles_map(map2, &nx, &ny, &nz);
295
typeIntern = Rast3d_tile_type_map(map);
296
typeIntern2 = Rast3d_tile_type_map(map2);
303
for (z = 0; z < nz * tileZ; z++) {
304
printf("comparing: z = %d\n", z);
306
for (y = 0; y < ny * tileY; y++) {
307
for (x = 0; x < nx * tileX; x++) {
309
Rast3d_get_block(map, x, y, z, 1, 1, 1, n1p, typeIntern);
310
Rast3d_get_block(map2, x, y, z, 1, 1, 1, n2p, typeIntern2);
312
if (typeIntern == FCELL_TYPE) {
313
if (typeIntern2 == FCELL_TYPE)
314
correct = Rast3d_compareFloats(f1p, p1, f2p, p2);
316
correct = Rast3d_compareFloatDouble(f1p, p1, n2p, p2);
319
if (typeIntern2 == FCELL_TYPE)
320
correct = Rast3d_compareFloatDouble(f2p, p2, n1p, p1);
322
correct = Rast3d_compareDoubles(n1p, p1, n2p, p2);
326
int xTile, yTile, zTile, xOffs, yOffs, zOffs;
328
Rast3d_coord2tile_coord(map2, x, y, z, &xTile, &yTile, &zTile,
329
&xOffs, &yOffs, &zOffs);
330
printf("(%d %d %d) (%d %d %d) (%d %d %d) %.20f %.20f\n",
331
x, y, z, xTile, yTile, zTile, xOffs, yOffs, zOffs,
334
("compareFilesNocache: files don't match\n");
340
printf("Files are identical up to precision.\n");
343
/*---------------------------------------------------------------------------*/
349
* Compares the cell-values of file <em>f1</em> in mapset
350
* <em>mapset1</em> and file <em>f2</em> in mapset <em>mapset2</em>.
351
* The values are compared up to precision.
352
* Terminates in error if the files don't match.
353
* This function uses the more advanced features of the cache.
354
* The source code can be found in <em>filecompare.c</em>.
364
Rast3d_compare_files(const char *f1, const char *mapset1, const char *f2,
368
double n1 = 0, n2 = 0;
371
int x, y, z, correct;
373
int rows, cols, depths;
374
int tileX, tileY, tileZ, typeIntern, typeIntern2, tileX2, tileY2, tileZ2;
377
printf("\nComparing %s and %s\n", f1, f2);
379
map = Rast3d_open_cell_old(f1, mapset1, RASTER3D_DEFAULT_WINDOW,
380
RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT);
382
Rast3d_fatal_error("Rast3d_compare_files: error in Rast3d_open_cell_old");
384
Rast3d_print_header(map);
386
map2 = Rast3d_open_cell_old(f2, mapset2, RASTER3D_DEFAULT_WINDOW,
387
RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT);
389
Rast3d_fatal_error("Rast3d_compare_files: error in Rast3d_open_cell_old");
391
Rast3d_print_header(map2);
393
typeIntern = Rast3d_tile_type_map(map);
394
typeIntern2 = Rast3d_tile_type_map(map2);
396
p1 = Rast3d_tile_precision_map(map);
397
p2 = Rast3d_tile_precision_map(map2);
399
Rast3d_get_tile_dimensions_map(map, &tileX, &tileY, &tileZ);
400
Rast3d_get_tile_dimensions_map(map2, &tileX2, &tileY2, &tileZ2);
401
Rast3d_get_nof_tiles_map(map2, &nx, &ny, &nz);
402
Rast3d_get_coords_map(map, &rows, &cols, &depths);
404
if ((!Rast3d_tile_use_cache_map(map)) || (!Rast3d_tile_use_cache_map(map2))) {
405
compareFilesNocache(map, map2);
416
Rast3d_autolock_on(map);
417
Rast3d_autolock_on(map2);
418
Rast3d_min_unlocked(map, cols / tileX + 1);
420
Rast3d_get_coords_map(map2, &rows, &cols, &depths);
421
Rast3d_min_unlocked(map2, cols / tileX + 1);
423
Rast3d_get_coords_map(map, &rows, &cols, &depths);
424
for (z = 0; z < depths; z++) {
425
printf("comparing: z = %d\n", z);
427
if ((z % tileZ) == 0) {
428
if (!Rast3d_unlock_all(map))
429
Rast3d_fatal_error("Rast3d_compare_files: error in Rast3d_unlock_all");
431
if ((z % tileZ2) == 0) {
432
if (!Rast3d_unlock_all(map2))
433
Rast3d_fatal_error("Rast3d_compare_files: error in Rast3d_unlock_all");
436
for (y = 0; y < rows; y++) {
437
for (x = 0; x < cols; x++) {
438
Rast3d_get_value_region(map, x, y, z, n1p, typeIntern);
439
Rast3d_get_value_region(map2, x, y, z, n2p, typeIntern2);
441
Rast3d_is_null_value_num(n1p, typeIntern);
442
Rast3d_is_null_value_num(n2p, typeIntern2);
444
if (typeIntern == FCELL_TYPE) {
445
if (typeIntern2 == FCELL_TYPE)
446
correct = Rast3d_compareFloats(f1p, p1, f2p, p2);
448
correct = Rast3d_compareFloatDouble(f1p, p1, n2p, p2);
451
if (typeIntern2 == FCELL_TYPE)
452
correct = Rast3d_compareFloatDouble(f2p, p2, n1p, p1);
454
correct = Rast3d_compareDoubles(n1p, p1, n2p, p2);
458
int xTile, yTile, zTile, xOffs, yOffs, zOffs;
460
Rast3d_coord2tile_coord(map2, x, y, z, &xTile, &yTile, &zTile,
461
&xOffs, &yOffs, &zOffs);
462
Rast3d_fatal_error("Rast3d_compare_files: files don't match\n");
468
printf("Files are identical up to precision.\n");