[brlcad-commits] CVS: brlcad/bench pixcmp.c,14.11,14.12
Open Source Solid Modeling CAD
Brought to you by:
brlcad
From: Sean M. <br...@us...> - 2007-02-15 19:41:41
|
Update of /cvsroot/brlcad/brlcad/bench In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv29988 Modified Files: pixcmp.c Log Message: major rewrite, almost from scratch. now supports all of the new options (-b, -l, -s, -i) and behaves more closely to cmp. supports processing over files byte-by-byte or pixel-by-pixel, comparing values, tabulating results, and reporting them in the format requested. Index: pixcmp.c =================================================================== RCS file: /cvsroot/brlcad/brlcad/bench/pixcmp.c,v retrieving revision 14.11 retrieving revision 14.12 diff -w -u -r14.11 -r14.12 --- pixcmp.c 14 Feb 2007 09:37:55 -0000 14.11 +++ pixcmp.c 15 Feb 2007 19:40:54 -0000 14.12 @@ -29,9 +29,9 @@ * is independent of the resolution of the image. * * Author - + * Christopher Sean Morrison * Charles M. Kennedy * Michael John Muuss - * Christopher Sean Morrison */ #ifndef lint static const char RCSid[] = "@(#)$Header$ (BRL)"; @@ -58,16 +58,22 @@ void usage(const char *name) { + const char *unknown = "pixcmp"; + if (!name) { + name = unknown; + } fprintf(stderr, "Usage: %s [OPTIONS] FILE1 [FILE2 [SKIP1 [SKIP2]]]\n%s", name, "Compare two PIX image files pixel by pixel.\n\n" " -l List pixel numbers and values for all pixels that differ.\n" + " -b Output and process by bytes instead of pixels.\n" " -i SKIP\n" " Skip the first SKIP pixels of input (for FILE1 and FILE2)\n" " -i SKIP1:SKIP2\n" " Skip the first SKIP1 pixels in FILE1 and SKIP2 pixels in FILE2.\n" " -s Silent output. Only return an exit status.\n\n" "If FILE is `-' or is missing, then input is read from standard input.\n" - "Pixel numbers are indexed linearly from zero.\n"); + "If the `-b' option is used, SKIP values are bytes instead of pixels.\n" + "Pixel numbers and bytes are indexed linearly from one.\n"); return; } @@ -76,8 +82,7 @@ handle_i_opt(const char *arg, long *skip1, long *skip2) { const char *endptr = arg; - if ((arg == NULL) || - ((skip1 == NULL) && (skip2 == NULL))){ + if ((arg == NULL) || ((skip1 == NULL) && (skip2 == NULL))){ /* nothing to do */ return; } @@ -124,19 +129,24 @@ int c; int list_pixel_values = 0; + int print_bytes = 0; int silent = 0; long f1_skip = 0; long f2_skip = 0; + long int bytes = 0; + /* process opts */ - while ((c = getopt(argc, argv, "li:s")) != EOF) { + while ((c = getopt(argc, argv, "lbi:s")) != EOF) { switch (c) { case 'l': list_pixel_values = 1; break; + case 'b': + print_bytes = 1; + break; case 'i': handle_i_opt(optarg, &f1_skip, &f2_skip); - argc--; argv++; break; case 's': silent = 1; @@ -146,110 +156,160 @@ usage(argv[0]); exit(OPTS_ERROR); } - argc--; argv++; } + argc -= optind; + argv += optind; /* validate what is left over */ - if( argc < 2 || argc > 5) { + if( argc < 1 || argc > 4) { fprintf(stderr, "ERROR: incorrect number of arguments provided\n\n"); usage(argv[0]); exit(OPTS_ERROR); } + if ((argc > 0 && !argv[0]) || (argc > 1 && !argv[1])) { + fprintf(stderr, "ERROR: bad filename\n\n"); + usage(argv[0]); + exit(OPTS_ERROR); + } + if ((argc > 2 && !argv[2]) || (argc > 3 && !argv[3])) { + fprintf(stderr, "ERROR: bad skip value\n\n"); + usage(argv[0]); + exit(OPTS_ERROR); + } /* handle optional SKIP1 and SKIP2 following filenames */ - if (argc > 3) { + if (argc > 2) { char range[64] = {0}; - snprintf(range, 64, "%s%s%s", argc>3?argv[3]:"", argc>4?":":"", argc>4?argv[4]:""); + if (argc > 3) { + snprintf(range, 64, "%s:%s", argv[2], argv[3]); + } else { + snprintf(range, 64, "%s", argv[2]); + } handle_i_opt(range, &f1_skip, &f2_skip); } /* printf("Skip from FILE1: %ld and from FILE2: %ld\n", f1_skip, f2_skip); */ - if (strcmp( argv[1], "-" ) == 0 ) { + if (strcmp(argv[0], "-") == 0 ) { f1 = stdin; - } else if ((f1 = fopen( argv[1], "r" )) == NULL) { + } else if ((f1 = fopen(argv[0], "r")) == NULL) { perror(argv[1]); exit(FILE_ERROR); } - if ((argc < 3) || (strcmp(argv[2], "-") == 0)) { + if ((argc < 2) || (strcmp(argv[1], "-") == 0)) { f2 = stdin; - } else if ((f2 = fopen( argv[2], "r" )) == NULL) { - perror(argv[2]); + } else if ((f2 = fopen(argv[1], "r")) == NULL) { + perror(argv[1]); exit(FILE_ERROR); } - /* skip requested pixels in FILE1 */ - if (fseek(f1, f1_skip * 3, SEEK_SET)) { - fprintf(stderr, "ERROR: Unable to seek %ld pixels (%ld bytes) in FILE1\n", f1_skip, f1_skip*3); + if (!print_bytes) { + f1_skip *= 3; + f2_skip *= 3; + } + + /* skip requested pixels/bytes in FILE1 */ + if (f1_skip && fseek(f1, f1_skip, SEEK_SET)) { + fprintf(stderr, + "ERROR: Unable to seek %ld %s%s in FILE1\n", + f1_skip, + print_bytes?"byte":"pixel", + f1_skip==1?"":"s"); perror("FILE1 fseek failure"); exit(FILE_ERROR); } /* skip requested pixels in FILE2 */ - if (fseek(f2, f2_skip * 3, SEEK_SET)) { - fprintf(stderr, "ERROR: Unable to seek %ld pixels (%ld bytes) in FILE2\n", f2_skip, f2_skip*3); + if (f2_skip && fseek(f2, f2_skip, SEEK_SET)) { + fprintf(stderr, + "ERROR: Unable to seek %ld %s%s in FILE2\n", + f1_skip, + print_bytes?"byte":"pixel", + f1_skip==1?"":"s"); perror("FILE2 fseek failure"); exit(FILE_ERROR); } - while(1) { - register int r1, g1, b1; - int r2, g2, b2; + /* iterate over the pixels/bytes in the files */ + while ((!feof(f1) && !feof(f2)) && + (!ferror(f1) && !ferror(f2))) { + register int r1 , r2, g1, g2, b1, b2; + r1 = r2 = g1 = g2 = b1 = b2 = -1; r1 = fgetc( f1 ); - g1 = fgetc( f1 ); - b1 = fgetc( f1 ); r2 = fgetc( f2 ); + if (feof(f1) || feof(f2)) break; + bytes++; + if (!print_bytes) { + g1 = fgetc( f1 ); g2 = fgetc( f2 ); + if (feof(f1) || feof(f2)) break; + bytes++; + b1 = fgetc( f1 ); b2 = fgetc( f2 ); if( feof(f1) || feof(f2) ) break; + bytes++; + } - if( r1 != r2 || g1 != g2 || b1 != b2 ) { - register int i; + if ((r1 == r2) && (g1 == g2) && (b1 == b2)) { + matching++; + continue; + } - /* Highlight differing channels */ + /* tabulate differing pixels */ + if (((r1 != r2) && (g1 == g2) && (b1 == b2)) || + ((r1 == r2) && (g1 != g2) && (b1 == b2)) || + ((r1 == r2) && (g1 == g2) && (b1 != b2))) { + /* off by one channel */ if( r1 != r2 ) { - if( (i = r1 - r2) < 0 ) i = -i; - if( i > 1 ) { + if ((r1 > r2 ? r1 - r2 : r2 - r1) > 1) { offmany++; } else { off1++; } - } else { - matching++; - } - if( g1 != g2 ) { - if( (i = g1 - g2) < 0 ) i = -i; - if( i > 1 ) { + } else if (g1 != g2) { + if ((g1 > g2 ? g1 - g2 : g2 - g1) > 1) { offmany++; } else { off1++; } - } else { - matching++; - } - if( b1 != b2 ) { - if( (i = b1 - b2) < 0 ) i = -i; - if( i > 1 ) { + } else if (b1 != b2) { + if ((b1 > b2 ? b1 - b2 : b2 - b1) > 1) { offmany++; } else { off1++; } + } } else { - matching++; + /* off by many */ + offmany++; } + + /* they're different, so print something */ + if (list_pixel_values) { + if (print_bytes) { + printf("%ld %3d %3d\n", bytes, r1, r2); } else { - /* Common case: equal. Give B&W NTSC average */ - matching += 3; + printf("%ld\t( %3d, %3d, %3d )\t( %3d, %3d, %3d )\n", bytes / 3, r1, g1, b1, r2, g2, b2); + } } } + + /* print summary */ if (!silent) { - fprintf(stderr, - "pixcmp pixels: %8ld matching, %8ld off by 1, %8ld off by many\n", + fprintf(stdout, + "pixcmp %s: %8ld matching, %8ld off by 1, %8ld off by many\n", + print_bytes?"bytes":"pixels", matching, off1, offmany ); } - /* If files were of different lengths, that is an error */ + /* check for errors */ + if (ferror(f1) || ferror(f2)) { + perror("pixcmp file error"); + return FILE_ERROR; + } + + /* if files were of different lengths, consider it an error */ if (feof(f1) != feof(f2)) { return FILE_ERROR; } |