GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
filecompare.c
Go to the documentation of this file.
1 #include <rpc/types.h>
2 #include <rpc/xdr.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <sys/types.h>
6 #include <unistd.h>
7 #include <grass/G3d.h>
8 
9 /*--------------------------------------------------------------------------*/
10 
11 static unsigned char clearMask[9] =
12  { 255, 128, 192, 224, 240, 248, 252, 254, 255 };
13 
14 /*---------------------------------------------------------------------------*/
15 
16 static void G3d_float2xdrFloat(float *f, float *xdrf)
17 {
18  XDR xdrEncodeStream;
19 
20  xdrmem_create(&xdrEncodeStream, (caddr_t) xdrf, 4, XDR_ENCODE);
21 
22  if (!xdr_setpos(&xdrEncodeStream, 0))
23  G3d_fatalError("G3d_float2xdrFloat: positioning xdr failed");
24 
25  if (!xdr_float(&xdrEncodeStream, f))
26  G3d_fatalError("G3d_float2xdrFloat: writing xdr failed");
27 
28  xdr_destroy(&xdrEncodeStream);
29 }
30 
31 /*---------------------------------------------------------------------------*/
32 
33 static void G3d_double2xdrDouble(double *d, double *xdrd)
34 {
35  XDR xdrEncodeStream;
36 
37  xdrmem_create(&xdrEncodeStream, (caddr_t) xdrd, 8, XDR_ENCODE);
38 
39  if (!xdr_setpos(&xdrEncodeStream, 0))
40  G3d_fatalError("G3d_double2xdrDouble: positioning xdr failed");
41 
42  if (!xdr_double(&xdrEncodeStream, d))
43  G3d_fatalError("G3d_double2xdrDouble: writing xdr failed");
44 
45  xdr_destroy(&xdrEncodeStream);
46 }
47 
48 /*---------------------------------------------------------------------------*/
49 
50 static void G3d_truncFloat(float *f, int p)
51 {
52  unsigned char *c;
53 
54  if ((p == -1) || (p >= 23))
55  return;
56 
57  c = (unsigned char *)f;
58 
59  c++;
60  if (p <= 7) {
61  *c++ &= clearMask[(p + 1) % 8];
62  *c++ = 0;
63  *c = 0;
64  return;
65  }
66 
67  c++;
68  if (p <= 15) {
69  *c++ &= clearMask[(p + 1) % 8];
70  *c = 0;
71  return;
72  }
73 
74  c++;
75  *c &= clearMask[(p + 1) % 8];
76  return;
77 }
78 
79 /*---------------------------------------------------------------------------*/
80 
81 static void G3d_truncDouble(double *d, int p)
82 {
83  unsigned char *c;
84 
85  if ((p == -1) || (p >= 52))
86  return;
87 
88  c = (unsigned char *)d;
89 
90  c++;
91  if (p <= 4) {
92  *c++ &= clearMask[(p + 4) % 8];
93  *c++ = 0;
94  *c++ = 0;
95  *c++ = 0;
96  *c++ = 0;
97  *c++ = 0;
98  *c = 0;
99  return;
100  }
101 
102  c++;
103  if (p <= 12) {
104  *c++ &= clearMask[(p + 4) % 8];
105  *c++ = 0;
106  *c++ = 0;
107  *c++ = 0;
108  *c++ = 0;
109  *c = 0;
110  return;
111  }
112 
113  c++;
114  if (p <= 20) {
115  *c++ &= clearMask[(p + 4) % 8];
116  *c++ = 0;
117  *c++ = 0;
118  *c++ = 0;
119  *c = 0;
120  return;
121  }
122 
123  c++;
124  if (p <= 28) {
125  *c++ &= clearMask[(p + 4) % 8];
126  *c++ = 0;
127  *c++ = 0;
128  *c = 0;
129  return;
130  }
131 
132  c++;
133  if (p <= 36) {
134  *c++ &= clearMask[(p + 4) % 8];
135  *c++ = 0;
136  *c = 0;
137  return;
138  }
139 
140  c++;
141  if (p <= 44) {
142  *c++ &= clearMask[(p + 4) % 8];
143  *c = 0;
144  return;
145  }
146 
147  c++;
148  *c &= clearMask[(p + 4) % 8];
149  return;
150 }
151 
152 /*---------------------------------------------------------------------------*/
153 
154 static void G3d_float2Double(float *f, double *d)
155 {
156  unsigned char *c1, *c2, sign, c;
157  int e;
158 
159  c1 = (unsigned char *)f;
160  c2 = (unsigned char *)d;
161 
162  sign = (*c1 & (unsigned char)128);
163  e = (((*c1 & (unsigned char)127) << 1) |
164  ((*(c1 + 1) & (unsigned char)128) >> 7));
165 
166  if ((*c1 != 0) || (*(c1 + 1) != 0) || (*(c1 + 2) != 0) ||
167  (*(c1 + 3) != 0))
168  e += 1023 - 127;
169  c = e / 16;
170 
171  *c2++ = (sign | c);
172 
173  c1++;
174 
175  c = e % 16;
176  *c2 = (c << 4);
177  *c2++ |= ((*c1 & (unsigned char)127) >> 3);
178 
179  *c2 = ((*c1++ & (unsigned char)7) << 5);
180  *c2++ |= (*c1 >> 3);
181 
182  *c2 = ((*c1++ & (unsigned char)7) << 5);
183  *c2++ |= (*c1 >> 3);
184 
185  *c2++ = ((*c1 & (unsigned char)7) << 5);
186 
187  *c2++ = (unsigned char)0;
188  *c2++ = (unsigned char)0;
189  *c2 = (unsigned char)0;
190 }
191 
192 /*---------------------------------------------------------------------------*/
193 
194 static int G3d_compareFloats(float *f1, int p1, float *f2, int p2)
195 {
196  unsigned char *c1, *c2;
197  float xdrf1, xdrf2;
198 
199  if (G3d_isNullValueNum(f1, FCELL_TYPE))
200  return G3d_isNullValueNum(f2, FCELL_TYPE);
201 
202  G3d_float2xdrFloat(f1, &xdrf1);
203  G3d_float2xdrFloat(f2, &xdrf2);
204 
205  c1 = (unsigned char *)&xdrf1;
206  c2 = (unsigned char *)&xdrf2;
207 
208  /* 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); */
209 
210  if ((p1 != -1) && (p1 < 23) && ((p1 < p2) || (p2 == -1)))
211  G3d_truncFloat(&xdrf2, p1);
212  if ((p2 != -1) && (p2 < 23) && ((p2 < p1) || (p1 == -1)))
213  G3d_truncFloat(&xdrf1, p2);
214 
215  /* 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); */
216 
217  return (*c1 == *c2) && (*(c1 + 1) == *(c2 + 1)) &&
218  (*(c1 + 2) == *(c2 + 2))
219  && (*(c1 + 3) == *(c2 + 3));
220 }
221 
222 
223 /*---------------------------------------------------------------------------*/
224 
225 static int G3d_compareDoubles(double *d1, int p1, double *d2, int p2)
226 {
227  unsigned char *c1, *c2;
228  double xdrd1, xdrd2;
229 
230  if (G3d_isNullValueNum(d1, DCELL_TYPE))
231  return G3d_isNullValueNum(d2, DCELL_TYPE);
232 
233  G3d_double2xdrDouble(d1, &xdrd1);
234  G3d_double2xdrDouble(d2, &xdrd2);
235 
236  c1 = (unsigned char *)&xdrd1;
237  c2 = (unsigned char *)&xdrd2;
238 
239  /* 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)); */
240 
241  if ((p1 != -1) && (p1 < 52) && ((p1 < p2) || (p2 == -1)))
242  G3d_truncDouble(&xdrd2, p1);
243  if ((p2 != -1) && (p2 < 52) && ((p2 < p1) || (p1 == -1)))
244  G3d_truncDouble(&xdrd1, p2);
245 
246  /* 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)); */
247 
248  return (*c1 == *c2) && (*(c1 + 1) == *(c2 + 1)) &&
249  (*(c1 + 2) == *(c2 + 2))
250  && (*(c1 + 3) == *(c2 + 3)) && (*(c1 + 4) == *(c2 + 4))
251  && (*(c1 + 5) == *(c2 + 5)) && (*(c1 + 6) == *(c2 + 6))
252  && (*(c1 + 7) == *(c2 + 7));
253 }
254 
255 
256 /*---------------------------------------------------------------------------*/
257 
258 static int G3d_compareFloatDouble(float *f, int p1, double *d, int p2)
259 {
260  unsigned char *c1, *c2;
261  float xdrf, fTmp;
262  double xdrd, xdrd2, dTmp;
263 
264  if (G3d_isNullValueNum(f, FCELL_TYPE))
265  return G3d_isNullValueNum(d, DCELL_TYPE);
266 
267  /* need this since assigning a double to a float actually may change the */
268  /* bit pattern. an example (in xdr format) is the double */
269  /* (63 237 133 81 81 108 3 32) which truncated to 23 bits precision should */
270  /* become (63 237 133 81 64 0 0 0). however assigned to a float it becomes */
271  /* (63 237 133 81 96 0 0 0). */
272  fTmp = *d;
273  dTmp = fTmp;
274 
275  G3d_float2xdrFloat(f, &xdrf);
276  G3d_float2Double(&xdrf, &xdrd2);
277  G3d_double2xdrDouble(&dTmp, &xdrd);
278 
279  c1 = (unsigned char *)&xdrd2;
280  c2 = (unsigned char *)&xdrd;
281 
282  /* 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)); */
283 
284 
285  if (((p1 != -1) && ((p1 < p2) || (p2 == -1))) ||
286  ((p1 == -1) && ((p2 > 23) || (p2 == -1))))
287  G3d_truncDouble(&xdrd, (p1 != -1 ? p1 : 23));
288  if ((p2 != -1) && (p2 < 23) && ((p2 < p1) || (p1 == -1)))
289  G3d_truncDouble(&xdrd2, p2);
290 
291  /* 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)); */
292 
293  return (*c1 == *c2) && (*(c1 + 1) == *(c2 + 1)) &&
294  (*(c1 + 2) == *(c2 + 2))
295  && (*(c1 + 3) == *(c2 + 3)) && (*(c1 + 4) == *(c2 + 4))
296  && (*(c1 + 5) == *(c2 + 5)) && (*(c1 + 6) == *(c2 + 6))
297  && (*(c1 + 7) == *(c2 + 7));
298 }
299 
300 /*---------------------------------------------------------------------------*/
301 
302 static void compareFilesNocache(void *map, void *map2)
303 {
304  double n1 = 0, n2 = 0;
305  double *n1p, *n2p;
306  float *f1p, *f2p;
307  int x, y, z, correct;
308  int p1, p2;
309  int tileX, tileY, tileZ, typeIntern, typeIntern2;
310  int nx, ny, nz;
311 
312  p1 = G3d_tilePrecisionMap(map);
313  p2 = G3d_tilePrecisionMap(map2);
314 
315  G3d_getTileDimensionsMap(map, &tileX, &tileY, &tileZ);
316  G3d_getNofTilesMap(map2, &nx, &ny, &nz);
317  typeIntern = G3d_tileTypeMap(map);
318  typeIntern2 = G3d_tileTypeMap(map2);
319 
320  n1p = &n1;
321  f1p = (float *)&n1;
322  n2p = &n2;
323  f2p = (float *)&n2;
324 
325  for (z = 0; z < nz * tileZ; z++) {
326  printf("comparing: z = %d\n", z);
327 
328  for (y = 0; y < ny * tileY; y++) {
329  for (x = 0; x < nx * tileX; x++) {
330 
331  G3d_getBlock(map, x, y, z, 1, 1, 1, n1p, typeIntern);
332  G3d_getBlock(map2, x, y, z, 1, 1, 1, n2p, typeIntern2);
333 
334  if (typeIntern == FCELL_TYPE) {
335  if (typeIntern2 == FCELL_TYPE)
336  correct = G3d_compareFloats(f1p, p1, f2p, p2);
337  else
338  correct = G3d_compareFloatDouble(f1p, p1, n2p, p2);
339  }
340  else {
341  if (typeIntern2 == FCELL_TYPE)
342  correct = G3d_compareFloatDouble(f2p, p2, n1p, p1);
343  else
344  correct = G3d_compareDoubles(n1p, p1, n2p, p2);
345  }
346 
347  if (!correct) {
348  int xTile, yTile, zTile, xOffs, yOffs, zOffs;
349 
350  G3d_coord2tileCoord(map2, x, y, z, &xTile, &yTile, &zTile,
351  &xOffs, &yOffs, &zOffs);
352  printf("(%d %d %d) (%d %d %d) (%d %d %d) %.20f %.20f\n",
353  x, y, z, xTile, yTile, zTile, xOffs, yOffs, zOffs,
354  *n1p, *n2p);
356  ("compareFilesNocache: files don't match\n");
357  }
358  }
359  }
360  }
361 
362  printf("Files are identical up to precision.\n");
363 }
364 
365 /*---------------------------------------------------------------------------*/
366 
367 
385 void
386 G3d_compareFiles(const char *f1, const char *mapset1, const char *f2,
387  const char *mapset2)
388 {
389  void *map, *map2;
390  double n1 = 0, n2 = 0;
391  double *n1p, *n2p;
392  float *f1p, *f2p;
393  int x, y, z, correct;
394  int p1, p2;
395  int rows, cols, depths;
396  int tileX, tileY, tileZ, typeIntern, typeIntern2, tileX2, tileY2, tileZ2;
397  int nx, ny, nz;
398 
399  printf("\nComparing %s and %s\n", f1, f2);
400 
401  map = G3d_openCellOld(f1, mapset1, G3D_DEFAULT_WINDOW,
402  G3D_TILE_SAME_AS_FILE, G3D_USE_CACHE_DEFAULT);
403  if (map == NULL)
404  G3d_fatalError("G3d_compareFiles: error in G3d_openCellOld");
405 
406  G3d_printHeader(map);
407 
408  map2 = G3d_openCellOld(f2, mapset2, G3D_DEFAULT_WINDOW,
409  G3D_TILE_SAME_AS_FILE, G3D_USE_CACHE_DEFAULT);
410  if (map2 == NULL)
411  G3d_fatalError("G3d_compareFiles: error in G3d_openCellOld");
412 
413  G3d_printHeader(map2);
414 
415  typeIntern = G3d_tileTypeMap(map);
416  typeIntern2 = G3d_tileTypeMap(map2);
417 
418  p1 = G3d_tilePrecisionMap(map);
419  p2 = G3d_tilePrecisionMap(map2);
420 
421  G3d_getTileDimensionsMap(map, &tileX, &tileY, &tileZ);
422  G3d_getTileDimensionsMap(map2, &tileX2, &tileY2, &tileZ2);
423  G3d_getNofTilesMap(map2, &nx, &ny, &nz);
424  G3d_getCoordsMap(map, &rows, &cols, &depths);
425 
426  if ((!G3d_tileUseCacheMap(map)) || (!G3d_tileUseCacheMap(map2))) {
427  compareFilesNocache(map, map2);
428  G3d_closeCell(map);
429  G3d_closeCell(map2);
430  return;
431  }
432 
433  n1p = &n1;
434  f1p = (float *)&n1;
435  n2p = &n2;
436  f2p = (float *)&n2;
437 
438  G3d_autolockOn(map);
439  G3d_autolockOn(map2);
440  G3d_minUnlocked(map, cols / tileX + 1);
441 
442  G3d_getCoordsMap(map2, &rows, &cols, &depths);
443  G3d_minUnlocked(map2, cols / tileX + 1);
444 
445  G3d_getCoordsMap(map, &rows, &cols, &depths);
446  for (z = 0; z < depths; z++) {
447  printf("comparing: z = %d\n", z);
448 
449  if ((z % tileZ) == 0) {
450  if (!G3d_unlockAll(map))
451  G3d_fatalError("G3d_compareFiles: error in G3d_unlockAll");
452  }
453  if ((z % tileZ2) == 0) {
454  if (!G3d_unlockAll(map2))
455  G3d_fatalError("G3d_compareFiles: error in G3d_unlockAll");
456  }
457 
458  for (y = 0; y < rows; y++) {
459  for (x = 0; x < cols; x++) {
460  G3d_getValueRegion(map, x, y, z, n1p, typeIntern);
461  G3d_getValueRegion(map2, x, y, z, n2p, typeIntern2);
462 
463  G3d_isNullValueNum(n1p, typeIntern);
464  G3d_isNullValueNum(n2p, typeIntern2);
465 
466  if (typeIntern == FCELL_TYPE) {
467  if (typeIntern2 == FCELL_TYPE)
468  correct = G3d_compareFloats(f1p, p1, f2p, p2);
469  else
470  correct = G3d_compareFloatDouble(f1p, p1, n2p, p2);
471  }
472  else {
473  if (typeIntern2 == FCELL_TYPE)
474  correct = G3d_compareFloatDouble(f2p, p2, n1p, p1);
475  else
476  correct = G3d_compareDoubles(n1p, p1, n2p, p2);
477  }
478 
479  if (!correct) {
480  int xTile, yTile, zTile, xOffs, yOffs, zOffs;
481 
482  G3d_coord2tileCoord(map2, x, y, z, &xTile, &yTile, &zTile,
483  &xOffs, &yOffs, &zOffs);
484  G3d_fatalError("G3d_compareFiles: files don't match\n");
485  }
486  }
487  }
488  }
489 
490  printf("Files are identical up to precision.\n");
491  G3d_closeCell(map);
492  G3d_closeCell(map2);
493 }
XDR xdrEncodeStream
Definition: g3dfpxdr.c:62
void G3d_getValueRegion(G3D_Map *map, int x, int y, int z, void *value, int type)
Returns in *value the cell-value of the cell with region-coordinate (x, y, z). The value returned is ...
Definition: tileio.c:244
void G3d_printHeader(G3D_Map *map)
Prints the header information of map.
Definition: headerinfo.c:228
void G3d_getTileDimensionsMap(G3D_Map *map, int *x, int *y, int *z)
Returns the tile dimensions used for map.
Definition: headerinfo.c:142
int G3d_isNullValueNum(const void *n, int type)
Definition: g3dnull.c:9
int y
Definition: plot.c:34
void G3d_getNofTilesMap(G3D_Map *map, int *nx, int *ny, int *nz)
Returns the dimensions of the tile-cube used to tile the region of map. These numbers include partial...
Definition: headerinfo.c:51
void G3d_compareFiles(const char *f1, const char *mapset1, const char *f2, const char *mapset2)
Compares the cell-values of file f1 in mapset mapset1 and file f2 in mapset mapset2. The values are compared up to precision. Terminates in error if the files don&#39;t match. This function uses the more advanced features of the cache. The source code can be found in filecompare.c.
Definition: filecompare.c:386
int G3d_tileUseCacheMap(G3D_Map *map)
Returns 1 if map uses cache, returns 0 otherwise.
Definition: headerinfo.c:212
int G3d_closeCell(G3D_Map *map)
Closes g3d-file. If map is new and cache-mode is used for map then every tile which is not flushed be...
Definition: g3dclose.c:144
int G3d_unlockAll(G3D_Map *map)
Unlocks every tile in cache of map.
Definition: tileread.c:312
int G3d_tilePrecisionMap(G3D_Map *map)
Returns the precision used to store map.
Definition: headerinfo.c:195
return NULL
Definition: dbfopen.c:1394
void * G3d_openCellOld(const char *name, const char *mapset, G3D_Region *window, int typeIntern, int cache)
Opens existing g3d-file name in mapset. Tiles are stored in memory with type which must be any of FCE...
Definition: g3dopen.c:85
tuple cols
void G3d_minUnlocked(G3D_Map *map, int minUnlocked)
Sets the minimum number of unlocked tiles to minUnlocked. This function should be used in combination...
Definition: tileread.c:386
dglInt32_t sign(dglInt32_t x)
Definition: flow.c:25
void G3d_coord2tileCoord(G3D_Map *map, int x, int y, int z, int *xTile, int *yTile, int *zTile, int *xOffs, int *yOffs, int *zOffs)
Converts cell-coordinates (x, y, z) into tile-coordinates (xTile, yTile, zTile) and the coordinate of...
Definition: tilemath.c:136
void G3d_autolockOn(G3D_Map *map)
Turns autolock mode on.
Definition: tileread.c:337
void G3d_getBlock(G3D_Map *map, int x0, int y0, int z0, int nx, int ny, int nz, void *block, int type)
Copies the cells contained in the block (cube) with vertices (x0, y0, z0) and (x0 + nx - 1...
Definition: getblock.c:103
int G3d_tileTypeMap(G3D_Map *map)
Returns the type in which tiles of map are stored in memory.
Definition: headerinfo.c:161
void G3d_fatalError(const char *,...)
This function prints the error message msg, and terminates the program with an error status...
Definition: g3derror.c:58
void G3d_getCoordsMap(G3D_Map *map, int *rows, int *cols, int *depths)
Returns the size of the region of map in cells.
Definition: headerinfo.c:19