ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/radcompare.c
Revision: 2.9
Committed: Tue Oct 16 16:52:05 2018 UTC (5 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.8: +6 -6 lines
Log Message:
Made exit value more consistent -- 1 for difference, 2 for error

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: radcompare.c,v 2.8 2018/10/16 16:23:17 greg Exp $";
3 #endif
4 /*
5 * Compare Radiance files for significant differences
6 *
7 * G. Ward
8 */
9
10 #include <stdlib.h>
11 #include <math.h>
12 #include <ctype.h>
13 #include "platform.h"
14 #include "rtio.h"
15 #include "resolu.h"
16 #include "color.h"
17 #include "lookup.h"
18 /* Reporting levels */
19 #define REP_QUIET 0 /* no reporting */
20 #define REP_ERROR 1 /* report errors only */
21 #define REP_WARN 2 /* report warnings as well */
22 #define REP_VERBOSE 3 /* verbose reporting */
23
24 int report = REP_WARN; /* reporting level */
25
26 int ign_header = 0; /* ignore header differences? */
27
28 double rel_min = 1e-5; /* positive for relative comparisons */
29
30 double rms_lim = 0.01; /* RMS difference limit */
31
32 double max_lim = 0.25; /* difference limit if non-negative */
33
34 int lin1cnt=0, lin2cnt=0; /* file line position */
35
36 const char nsuffix[10][3] = { /* 1st, 2nd, 3rd, etc. */
37 "th","st","nd","rd","th","th","th","th","th","th"
38 };
39 #define num_sfx(n) nsuffix[(n)%10]
40
41 /* file types */
42 const char *file_type[] = {
43 "Unrecognized",
44 "TEXT_generic",
45 "ascii",
46 COLRFMT,
47 CIEFMT,
48 "float",
49 "double",
50 "BSDF_RBFmesh",
51 "Radiance_octree",
52 "Radiance_tmesh",
53 "BINARY_unknown",
54 NULL /* terminator */
55 };
56 /* keep consistent with above */
57 enum {TYP_UNKNOWN, TYP_TEXT, TYP_ASCII, TYP_RGBE, TYP_XYZE, TYP_FLOAT,
58 TYP_DOUBLE, TYP_RBFMESH, TYP_OCTREE, TYP_TMESH, TYP_BINARY};
59
60 #define has_header(t) (!( 1L<<(t) & (1L<<TYP_TEXT | 1L<<TYP_BINARY) ))
61
62 /* header variables to always ignore */
63 const char *hdr_ignkey[] = {
64 "SOFTWARE",
65 "CAPDATE",
66 "GMT",
67 NULL /* terminator */
68 };
69 /* header variable settings */
70 LUTAB hdr1 = LU_SINIT(free,free);
71 LUTAB hdr2 = LU_SINIT(free,free);
72
73 /* advance appropriate file line count */
74 #define adv_linecnt(htp) (lin1cnt += (htp == &hdr1), \
75 lin2cnt += (htp == &hdr2))
76
77 /* input files */
78 char *progname = NULL;
79 const char stdin_name[] = "<stdin>";
80 const char *f1name=NULL, *f2name=NULL;
81 FILE *f1in=NULL, *f2in=NULL;
82
83 /* running real differences */
84 double diff2sum = 0;
85 long nsum = 0;
86
87 /* Report usage and exit */
88 static void
89 usage()
90 {
91 fputs("Usage: ", stderr);
92 fputs(progname, stderr);
93 fputs(" [-h][-s|-w|-v][-rel min_test][-rms epsilon][-max epsilon] reference test\n",
94 stderr);
95 exit(2);
96 }
97
98 /* Get type ID from name (or 0 if not found) */
99 static int
100 xlate_type(const char *nm)
101 {
102 int i;
103
104 if (!nm || !*nm)
105 return(TYP_UNKNOWN);
106 for (i = 1; file_type[i]; i++)
107 if (!strcmp(nm, file_type[i]))
108 return(i);
109 return(TYP_UNKNOWN);
110 }
111
112 /* Compare real values and keep track of differences */
113 static int
114 real_check(double r1, double r2)
115 {
116 double diff2 = (r1 - r2)*(r1 - r2);
117
118 if (rel_min > 0) { /* doing relative differences? */
119 double av2 = .25*(r1*r1 + 2.*fabs(r1*r2) + r2*r2);
120 if (av2 > rel_min*rel_min)
121 diff2 /= av2;
122 }
123 if (max_lim >= 0 && diff2 > max_lim*max_lim) {
124 if (report != REP_QUIET)
125 printf(
126 "%s: %sdifference between %.8g and %.8g exceeds epsilon of %.8g\n",
127 progname,
128 (rel_min > 0) ? "relative " : "",
129 r1, r2, max_lim);
130 return(0);
131 }
132 diff2sum += diff2;
133 nsum++;
134 return(1);
135 }
136
137 /* Compare two color values for equivalence */
138 static int
139 color_check(COLOR c1, COLOR c2)
140 {
141 int p;
142
143 if (!real_check(colval(c1,RED)+colval(c1,GRN)+colval(c1,BLU)*(1./3.),
144 colval(c2,RED)+colval(c2,GRN)+colval(c2,BLU))*(1./3.))
145 return(0);
146
147 p = (colval(c1,GRN) > colval(c1,RED)) ? GRN : RED;
148 if (colval(c1,BLU) > colval(c1,p)) p = BLU;
149
150 return(real_check(colval(c1,p), colval(c2,p)));
151 }
152
153 /* Compare two strings for equivalence */
154 static int
155 equiv_string(char *s1, char *s2)
156 {
157 #define CLS_STR 0
158 #define CLS_INT 1
159 #define CLS_FLT 2
160 /* skip whitespace at beginning */
161 while (isspace(*s1)) s1++;
162 while (isspace(*s2)) s2++;
163 while (*s1) { /* check each word */
164 int inquote;
165 if (!*s2) /* unexpected EOL in s2? */
166 return(0);
167 inquote = *s1;
168 if ((inquote != '\'') & (inquote != '"'))
169 inquote = 0;
170 if (inquote) { /* quoted text must match exactly */
171 if (*s1++ != *s2++)
172 return(0);
173 while (*s1 != inquote) {
174 if (!*s1)
175 return(0);
176 if (*s1++ != *s2++)
177 return(0);
178 }
179 s1++;
180 if (*s2++ != inquote)
181 return(0);
182 } else { /* else classify word type */
183 char *s1s = s1;
184 char *s2s = s2;
185 int cls = CLS_STR;
186 s1 = sskip(s1);
187 s2 = sskip(s2);
188 if (iskip(s1s) == s1) {
189 if (iskip(s2s) == s2)
190 cls = CLS_INT;
191 else if (fskip(s2s) == s2)
192 cls = CLS_FLT;
193 } else if (fskip(s1s) == s1) {
194 if (fskip(s2s) != s2)
195 return(0);
196 cls = CLS_FLT;
197 }
198 switch (cls) {
199 case CLS_INT: /* strncmp() faster */
200 case CLS_STR:
201 if (s1 - s1s != s2 - s2s)
202 return(0);
203 if (strncmp(s1s, s2s, s1 - s1s))
204 return(0);
205 break;
206 case CLS_FLT:
207 if (!real_check(atof(s1s), atof(s2s)))
208 return(0);
209 break;
210 }
211 }
212 while (isspace(*s1)) s1++;
213 while (isspace(*s2)) s2++;
214 }
215 return(!*s2); /* match if we reached the end of s2, too */
216 #undef CLS_STR
217 #undef CLS_INT
218 #undef CLS_FLT
219 }
220
221 /* Check if string is var=value pair and set if not in ignore list */
222 static int
223 setheadvar(char *val, void *p)
224 {
225 LUTAB *htp = (LUTAB *)p;
226 LUENT *tep;
227 char *key;
228 int kln, vln;
229 int n;
230
231 adv_linecnt(htp); /* side-effect is to count lines */
232 if (!isalpha(*val)) /* key must start line */
233 return(0);
234 key = val++;
235 while (*val && !isspace(*val) & (*val != '='))
236 val++;
237 kln = val - key;
238 while (isspace(*val)) /* check for value */
239 *val++ = '\0';
240 if (*val != '=')
241 return(0);
242 *val++ = '\0';
243 while (isspace(*val))
244 val++;
245 if (!*val) /* nothing set? */
246 return(0);
247 /* check if key to ignore */
248 for (n = 0; hdr_ignkey[n]; n++)
249 if (!strcmp(key, hdr_ignkey[n]))
250 return(0);
251 vln = strlen(val); /* eliminate space and newline at end */
252 while (isspace(val[--vln]))
253 ;
254 val[++vln] = '\0';
255 if (!(tep = lu_find(htp, key)))
256 return(-1); /* memory allocation error */
257 if (!tep->key)
258 tep->key = strcpy(malloc(kln+1), key);
259 if (tep->data)
260 free(tep->data);
261 tep->data = strcpy(malloc(vln+1), val);
262 return(1);
263 }
264
265 /* Lookup correspondent in other header */
266 static int
267 match_val(const LUENT *ep1, void *p2)
268 {
269 const LUENT *ep2 = lu_find((LUTAB *)p2, ep1->key);
270 if (!ep2 || !ep2->data) {
271 if (report != REP_QUIET)
272 printf("%s: variable '%s' missing in '%s'\n",
273 progname, ep1->key, f2name);
274 return(-1);
275 }
276 if (!equiv_string((char *)ep1->data, (char *)ep2->data)) {
277 if (report != REP_QUIET) {
278 printf("%s: header variable '%s' has different values\n",
279 progname, ep1->key);
280 if (report >= REP_VERBOSE) {
281 printf("%s: %s=%s\n", f1name,
282 ep1->key, (char *)ep1->data);
283 printf("%s: %s=%s\n", f2name,
284 ep2->key, (char *)ep2->data);
285 }
286 }
287 return(-1);
288 }
289 return(1); /* good match */
290 }
291
292 /* Compare two sets of header variables */
293 static int
294 headers_match(LUTAB *hp1, LUTAB *hp2)
295 {
296 int ne = lu_doall(hp1, match_val, hp2);
297 if (ne < 0)
298 return(0); /* something didn't match! */
299 /* non-fatal if second header has extra */
300 if (report >= REP_WARN && (ne = lu_doall(hp2, NULL, NULL) - ne))
301 printf("%s: warning - '%s' has %d extra header setting(s)\n",
302 progname, f2name, ne);
303 return(1); /* good match */
304 }
305
306 /* Check generic input to determine if it is binary, -1 on error */
307 static int
308 input_is_binary(FILE *fin)
309 {
310 int n = 0;
311 int c = 0;
312
313 while ((c = getc(fin)) != EOF) {
314 ++n;
315 if (!c | (c > 127))
316 break; /* non-ascii character */
317 if (n >= 10240)
318 break; /* enough to be confident */
319 }
320 if (!n)
321 return(-1); /* first read failed */
322 if (fseek(fin, 0L, 0) < 0)
323 return(-1); /* rewind failed */
324 return(!c | (c > 127));
325 }
326
327 /* Identify and return data type from header (if one) */
328 static int
329 identify_type(const char *name, FILE *fin, LUTAB *htp)
330 {
331 extern const char HDRSTR[];
332 int c;
333 /* check magic header start */
334 if ((c = getc(fin)) != HDRSTR[0]) {
335 if (c == EOF) goto badeof;
336 ungetc(c, fin);
337 c = 0;
338 } else if ((c = getc(fin)) != HDRSTR[1]) {
339 if (c == EOF) goto badeof;
340 ungetc(c, fin); ungetc(HDRSTR[0], fin);
341 c = 0;
342 }
343 if (c) { /* appears to have a header */
344 char sbuf[32];
345 if (!fgets(sbuf, sizeof(sbuf), fin))
346 goto badeof;
347 adv_linecnt(htp); /* for #?ID string */
348 if (report >= REP_WARN && strncmp(sbuf, "RADIANCE", 8)) {
349 fputs(name, stdout);
350 fputs(": warning - unexpected header ID: ", stdout);
351 fputs(sbuf, stdout);
352 }
353 if (getheader(fin, setheadvar, htp) < 0) {
354 fputs(name, stderr);
355 fputs(": unknown error reading header\n", stderr);
356 return(-1);
357 }
358 adv_linecnt(htp); /* for trailing emtpy line */
359 return(xlate_type((const char *)lu_find(htp,"FORMAT")->data));
360 }
361 c = input_is_binary(fin); /* else peek to see if binary */
362 if (c < 0) {
363 fputs(name, stderr);
364 fputs(": read/seek error\n", stderr);
365 return(-1);
366 }
367 if (c)
368 return(TYP_BINARY);
369 SET_FILE_TEXT(fin); /* originally set to binary */
370 return(TYP_TEXT);
371 badeof:
372 if (report != REP_QUIET) {
373 fputs(name, stdout);
374 fputs(": unexpected end-of-file\n", stdout);
375 }
376 return(-1);
377 }
378
379 /* Check that overall RMS error is below threshold */
380 static int
381 good_RMS()
382 {
383 if (!nsum)
384 return(1);
385 if (diff2sum/(double)nsum > rms_lim*rms_lim) {
386 if (report != REP_QUIET)
387 printf(
388 "%s: %sRMS difference between '%s' and '%s' of %.5g exceeds limit of %.5g\n",
389 progname,
390 (rel_min > 0) ? "relative " : "",
391 f1name, f2name,
392 sqrt(diff2sum/(double)nsum), rms_lim);
393 return(0);
394 }
395 if (report >= REP_VERBOSE)
396 printf("%s: %sRMS difference of reals in '%s' and '%s' is %.5g\n",
397 progname, (rel_min > 0) ? "relative " : "",
398 f1name, f2name, sqrt(diff2sum/(double)nsum));
399 return(1);
400 }
401
402 /* Compare two inputs as generic binary files */
403 static int
404 compare_binary()
405 {
406 int c1=0, c2=0;
407
408 if (report >= REP_VERBOSE) {
409 fputs(progname, stdout);
410 fputs(": comparing inputs as binary\n", stdout);
411 }
412 for ( ; ; ) { /* exact byte matching */
413 c1 = getc(f1in);
414 c2 = getc(f2in);
415 if (c1 == EOF) {
416 if (c2 == EOF)
417 return(1); /* success! */
418 if (report != REP_QUIET) {
419 fputs(f1name, stdout);
420 fputs(": unexpected end-of-file\n", stdout);
421 }
422 return(0);
423 }
424 if (c2 == EOF) {
425 if (report != REP_QUIET) {
426 fputs(f2name, stdout);
427 fputs(": unexpected end-of-file\n", stdout);
428 }
429 return(0);
430 }
431 if (c1 != c2)
432 break; /* quit and report difference */
433 }
434 if (report == REP_QUIET)
435 return(0);
436 printf("%s: binary files '%s' and '%s' differ at byte offset %ld|%ld\n",
437 progname, f1name, f2name, ftell(f1in), ftell(f2in));
438 if (report >= REP_VERBOSE)
439 printf("%s: byte in '%s' is 0x%X, byte in '%s' is 0x%X\n",
440 progname, f1name, c1, f2name, c2);
441 return(0);
442 }
443
444 /* Compare two inputs as generic text files */
445 static int
446 compare_text()
447 {
448 char l1buf[4096], l2buf[4096];
449
450 if (report >= REP_VERBOSE) {
451 fputs(progname, stdout);
452 fputs(": comparing inputs as ASCII text\n", stdout);
453 }
454 /* compare a line at a time */
455 while (fgets(l1buf, sizeof(l1buf), f1in)) {
456 lin1cnt++;
457 if (!*sskip2(l1buf,0))
458 continue; /* ignore empty lines */
459 while (fgets(l2buf, sizeof(l2buf), f2in)) {
460 lin2cnt++;
461 if (*sskip2(l2buf,0))
462 break; /* found other non-empty line */
463 }
464 if (feof(f2in)) {
465 if (report != REP_QUIET) {
466 fputs(f2name, stdout);
467 fputs(": unexpected end-of-file\n", stdout);
468 }
469 return(0);
470 }
471 /* compare non-empty lines */
472 if (!equiv_string(l1buf, l2buf)) {
473 if (report != REP_QUIET) {
474 printf("%s: inputs '%s' and '%s' differ at line %d|%d\n",
475 progname, f1name, f2name,
476 lin1cnt, lin2cnt);
477 if (report >= REP_VERBOSE) {
478 fputs("------------- Mismatch -------------\n", stdout);
479 printf("%s@%d:\t%s", f1name,
480 lin1cnt, l1buf);
481 printf("%s@%d:\t%s", f2name,
482 lin2cnt, l2buf);
483 }
484 }
485 return(0);
486 }
487 }
488 /* check for EOF on input 2 */
489 while (fgets(l2buf, sizeof(l2buf), f2in)) {
490 if (!*sskip2(l2buf,0))
491 continue;
492 if (report != REP_QUIET) {
493 fputs(f1name, stdout);
494 fputs(": unexpected end-of-file\n", stdout);
495 }
496 return(0);
497 }
498 return(good_RMS()); /* final check for reals */
499 }
500
501 /* Compare two inputs that are known to be RGBE or XYZE images */
502 static int
503 compare_hdr()
504 {
505 RESOLU rs1, rs2;
506 COLOR *scan1, *scan2;
507 int x, y;
508
509 if (report >= REP_VERBOSE) {
510 fputs(progname, stdout);
511 fputs(": comparing inputs as HDR images\n", stdout);
512 }
513 fgetsresolu(&rs1, f1in);
514 fgetsresolu(&rs2, f2in);
515 if (rs1.rt != rs2.rt) {
516 if (report != REP_QUIET)
517 printf(
518 "%s: Images '%s' and '%s' have different pixel ordering\n",
519 progname, f1name, f2name);
520 return(0);
521 }
522 if ((rs1.xr != rs2.xr) | (rs1.yr != rs2.yr)) {
523 if (report != REP_QUIET)
524 printf(
525 "%s: Images '%s' and '%s' are different sizes\n",
526 progname, f1name, f2name);
527 return(0);
528 }
529 scan1 = (COLOR *)malloc(scanlen(&rs1)*sizeof(COLOR));
530 scan2 = (COLOR *)malloc(scanlen(&rs2)*sizeof(COLOR));
531 if (!scan1 | !scan2) {
532 fprintf(stderr, "%s: out of memory in compare_hdr()\n", progname);
533 exit(2);
534 }
535 for (y = 0; y < numscans(&rs1); y++) {
536 if ((freadscan(scan1, scanlen(&rs1), f1in) < 0) |
537 (freadscan(scan2, scanlen(&rs2), f2in) < 0)) {
538 if (report != REP_QUIET)
539 printf("%s: unexpected end-of-file\n",
540 progname);
541 free(scan1);
542 free(scan2);
543 return(0);
544 }
545 for (x = 0; x < scanlen(&rs1); x++) {
546 if (color_check(scan1[x], scan2[x]))
547 continue;
548 if (report != REP_QUIET) {
549 printf(
550 "%s: pixels at scanline %d offset %d differ\n",
551 progname, y, x);
552 if (report >= REP_VERBOSE) {
553 printf("%s: (R,G,B)=(%g,%g,%g)\n",
554 f1name, colval(scan1[x],RED),
555 colval(scan1[x],GRN),
556 colval(scan1[x],BLU));
557 printf("%s: (R,G,B)=(%g,%g,%g)\n",
558 f2name, colval(scan2[x],RED),
559 colval(scan2[x],GRN),
560 colval(scan2[x],BLU));
561 }
562 }
563 free(scan1);
564 free(scan2);
565 return(0);
566 }
567 }
568 free(scan1);
569 free(scan2);
570 return(good_RMS()); /* final check of RMS */
571 }
572
573 /* Compare two inputs that are known to be 32-bit floating-point data */
574 static int
575 compare_float()
576 {
577 long nread = 0;
578 float f1, f2;
579
580 if (report >= REP_VERBOSE) {
581 fputs(progname, stdout);
582 fputs(": comparing inputs as 32-bit IEEE floats\n", stdout);
583 }
584 while (getbinary(&f1, sizeof(f1), 1, f1in)) {
585 if (!getbinary(&f2, sizeof(f2), 1, f2in))
586 goto badeof;
587 ++nread;
588 if (real_check(f1, f2))
589 continue;
590 if (report != REP_QUIET)
591 printf("%s: %ld%s float values differ\n",
592 progname, nread, num_sfx(nread));
593 return(0);
594 }
595 if (!getbinary(&f2, sizeof(f2), 1, f2in))
596 return(good_RMS()); /* final check of RMS */
597 badeof:
598 if (report != REP_QUIET)
599 printf("%s: unexpected end-of-file\n", progname);
600 return(0);
601 }
602
603 /* Compare two inputs that are known to be 64-bit floating-point data */
604 static int
605 compare_double()
606 {
607 long nread = 0;
608 double f1, f2;
609
610 if (report >= REP_VERBOSE) {
611 fputs(progname, stdout);
612 fputs(": comparing inputs as 64-bit IEEE doubles\n", stdout);
613 }
614 while (getbinary(&f1, sizeof(f1), 1, f1in)) {
615 if (!getbinary(&f2, sizeof(f2), 1, f2in))
616 goto badeof;
617 ++nread;
618 if (real_check(f1, f2))
619 continue;
620 if (report != REP_QUIET)
621 printf("%s: %ld%s double values differ\n",
622 progname, nread, num_sfx(nread));
623 return(0);
624 }
625 if (!getbinary(&f2, sizeof(f2), 1, f2in))
626 return(good_RMS()); /* final check of RMS */
627 badeof:
628 if (report != REP_QUIET)
629 printf("%s: unexpected end-of-file\n", progname);
630 return(0);
631 }
632
633 /* Compare two Radiance files for equivalence */
634 int
635 main(int argc, char *argv[])
636 {
637 int typ1, typ2;
638 int a;
639
640 progname = argv[0];
641 for (a = 1; a < argc && argv[a][0] == '-'; a++) {
642 switch (argv[a][1]) {
643 case 'h': /* ignore header info. */
644 ign_header = !ign_header;
645 continue;
646 case 's': /* silent operation */
647 report = REP_QUIET;
648 continue;
649 case 'w': /* turn off warnings */
650 if (report > REP_ERROR)
651 report = REP_ERROR;
652 continue;
653 case 'v': /* turn on verbose mode */
654 report = REP_VERBOSE;
655 continue;
656 case 'm': /* maximum epsilon */
657 max_lim = atof(argv[++a]);
658 continue;
659 case 'r':
660 if (argv[a][2] == 'e') /* relative difference */
661 rel_min = atof(argv[++a]);
662 else if (argv[a][2] == 'm') /* RMS limit */
663 rms_lim = atof(argv[++a]);
664 else
665 usage();
666 continue;
667 case '\0': /* first file from stdin */
668 f1in = stdin;
669 f1name = stdin_name;
670 break;
671 default:
672 usage();
673 }
674 break;
675 }
676 if (a != argc-2) /* make sure of two inputs */
677 usage();
678 if (!strcmp(argv[a], argv[a+1])) { /* inputs are same? */
679 if (report >= REP_WARN)
680 printf("%s: warning - identical inputs given\n",
681 progname);
682 return(0);
683 }
684 if (!f1name) f1name = argv[a];
685 if (!f2name) f2name = argv[a+1];
686 /* open inputs */
687 SET_FILE_BINARY(stdin); /* in case we're using it */
688 if (!f1in && !(f1in = fopen(f1name, "rb"))) {
689 fprintf(stderr, "%s: cannot open for reading\n", f1name);
690 return(2);
691 }
692 if (!strcmp(f2name, "-")) {
693 f2in = stdin;
694 f2name = stdin_name;
695 } else if (!(f2in = fopen(f2name, "rb"))) {
696 fprintf(stderr, "%s: cannot open for reading\n", f2name);
697 return(2);
698 }
699 /* load headers */
700 if ((typ1 = identify_type(f1name, f1in, &hdr1)) < 0)
701 return(2);
702 if ((typ2 = identify_type(f2name, f2in, &hdr2)) < 0)
703 return(2);
704 if (typ1 != typ2) {
705 if (report != REP_QUIET)
706 printf("%s: '%s' is %s and '%s' is %s\n",
707 progname, f1name, file_type[typ1],
708 f2name, file_type[typ2]);
709 return(1);
710 }
711 ign_header |= !has_header(typ1); /* check headers if indicated */
712 if (!ign_header && !headers_match(&hdr1, &hdr2))
713 return(1);
714 lu_done(&hdr1); lu_done(&hdr2);
715 if (!ign_header & (report >= REP_WARN)) {
716 if (typ1 == TYP_UNKNOWN)
717 printf("%s: warning - unrecognized format, comparing as binary\n",
718 progname);
719 if (lin1cnt != lin2cnt)
720 printf("%s: warning - headers are different lengths\n",
721 progname);
722 }
723 if (report >= REP_VERBOSE)
724 printf("%s: input file type is %s\n",
725 progname, file_type[typ1]);
726
727 switch (typ1) { /* compare based on type */
728 case TYP_BINARY:
729 case TYP_TMESH:
730 case TYP_OCTREE:
731 case TYP_RBFMESH:
732 case TYP_UNKNOWN:
733 return( !compare_binary() );
734 case TYP_TEXT:
735 case TYP_ASCII:
736 return( !compare_text() );
737 case TYP_RGBE:
738 case TYP_XYZE:
739 return( !compare_hdr() );
740 case TYP_FLOAT:
741 return( !compare_float() );
742 case TYP_DOUBLE:
743 return( !compare_double() );
744 }
745 return(1);
746 }