idf.c 7.15 KB
 /************************************************************************\
 *                                                                        *
 *               Copyright (C) 1994, Silicon Graphics, Inc.               *
 *                                                                        *
 *  These coded instructions, statements, and computer programs  contain  *
 *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
 *  are protected by Federal copyright  law.  They  may not be disclosed  *
 *  to  third  parties  or copied or duplicated in any form, in whole or  *
 *  in part, without the prior written consent of Silicon Graphics, Inc.  *
 *                                                                        *
 \************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include <PRimage.h>

#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))

/* GLOBAL VARIABLES */

int rednull=0,greennull=0,bluenull=0;	/* background color */
int nodither=1;
int no32=1;

/* COLOR TABLE */

short ctred[10] = {
	0xff,	/* yellow	not equal */
	0x1f,	/* grey		equal     */
	0x00,	/* green        f2 black  */
	0xff,   /* white        error     */
	0xff,   /* red          f1 black  */
	0xff,   /* white        error     */
	0xff,   /* white        error     */
	0x00,   /* black        both black*/
	0x00,	/* blue		dithered  */
	0x00,	/* cyan		32/16 bit equal */
};
short ctgreen[10] = {
	0xff,	/* yellow	not equal */
	0x1f,	/* grey		equal     */
	0xff,	/* green        f2 black  */
	0xff,   /* white        error     */
	0x00,   /* red          f1 black  */
	0xff,   /* white        error     */
	0xff,   /* white        error     */
	0x00,   /* black        both black*/
	0x00,	/* blue		dithered  */
	0xff,	/* cyan		32/16 bit equal */
};
short ctblue[10] = {
	0x00,	/* yellow	not equal */
	0x1f,	/* grey		equal     */
	0x00,	/* green        f2 black  */
	0xff,   /* white        error     */
	0x00,   /* red          f1 black  */
	0xff,   /* white        error     */
	0xff,   /* white        error     */
	0x00,   /* black        both black*/
	0xff,	/* blue		dithered  */
	0xff,	/* cyan		32/16 bit equal */
};

/* CODE */

void badfile(char *fn)
{
	fprintf(stderr, "had trouble opening file %s\n",fn);
	exit(1);
}

int docompare(char *f1, char *f2, char *fout)
{
    	IMAGE *i1, *i2, *iout;
    	int i,j,cmp,dith,b32;
	int w,h,wx,hx;
	unsigned short *f1red, *f1green, *f1blue;
	unsigned short *f2red, *f2green, *f2blue;
	unsigned short *fored, *fogreen, *foblue;
	int rval=0;

    	if ((i1 = iopen(f1, "r")) == NULL)
		badfile(f1);

    	if ((i2 = iopen(f2, "r")) == NULL) {
		iclose(i1);
		badfile(f2);
	}

	w=MIN(i1->xsize,i2->xsize);
	wx=MAX(i1->xsize,i2->xsize);
	h=MIN(i1->ysize,i2->ysize);
	hx=MAX(i1->ysize,i2->ysize);
	if (w != wx || h != hx)
		fprintf(stderr, "input images are different sizes. Comparing corner.\n");

    	if ((iout = iopen(fout, "w", RLE(1), 3, w, h, 3)) == NULL){
		iclose(i2);
		iclose(i1);
		badfile(fout);
	}

    	f1red = (unsigned short *) malloc(i1->xsize * sizeof(unsigned short));
    	f1green = (unsigned short *) malloc(i1->xsize * sizeof(unsigned short));
    	f1blue = (unsigned short *) malloc(i1->xsize * sizeof(unsigned short));
    	f2red = (unsigned short *) malloc(i2->xsize * sizeof(unsigned short));
    	f2green = (unsigned short *) malloc(i2->xsize * sizeof(unsigned short));
    	f2blue = (unsigned short *) malloc(i2->xsize * sizeof(unsigned short));
    	fored = (unsigned short *) malloc(w * sizeof(unsigned short));
    	fogreen = (unsigned short *) malloc(w * sizeof(unsigned short));
    	foblue = (unsigned short *) malloc(w * sizeof(unsigned short));

    	for (i = 0; i < h ; i++) {
	    getrow(i1, f1red,   h - 1 - i, 0);
	    getrow(i1, f1green,   h - 1 - i, 1);
	    getrow(i1, f1blue,   h - 1 - i, 2);
	    getrow(i2, f2red,   h - 1 - i, 0);
	    getrow(i2, f2green,   h - 1 - i, 1);
	    getrow(i2, f2blue,   h - 1 - i, 2);

	    for (j=0;j<w;j++) {
		cmp=0;
		dith=0;
		b32=0;
		if ((0xff&f1red[j])==rednull &&
			(0xff&f1green[j])==greennull &&
			(0xff&f1blue[j])==bluenull)
		    cmp |= 4;
		if ((0xff&f2red[j])==rednull &&
			(0xff&f2green[j])==greennull &&
			(0xff&f2blue[j])==bluenull)
		    cmp |= 2;
		if ( (0xff&f1red[j])==(0xff&f2red[j]) &&
			(0xff&f1green[j])==(0xff&f2green[j]) &&
			(0xff&f1blue[j])==(0xff&f2blue[j])) 
		    cmp |= 1;
		else if (( (0xff&f1red[j]+0x8)>=(0xff&f2red[j]) &&
                        (0xff&f1green[j]+0x8)>=(0xff&f2green[j]) &&
                        (0xff&f1blue[j]+0x8)>=(0xff&f2blue[j]))     &&
		         ( (0xff&f1red[j]-0x8)<=(0xff&f2red[j]) &&
                        (0xff&f1green[j]-0x8)<=(0xff&f2green[j]) &&
                        (0xff&f1blue[j]-0x8)<=(0xff&f2blue[j]))  )
		    dith=1;
		else if ( (0xf8&f1red[j])==(0xf8&f2red[j]) &&
			(0xf8&f1green[j])==(0xf8&f2green[j]) &&
			(0xf8&f1blue[j])==(0xf8&f2blue[j])) 
		    b32=1;
		else
		    rval=1;
		fored[j]=ctred[cmp];
		fogreen[j]=ctgreen[cmp];
		foblue[j]=ctblue[cmp];
		if (dith) {
			fored[j]=ctred[8];
			fogreen[j]=ctgreen[8];
			foblue[j]=ctblue[8];
			rval |= nodither;
		} else if (b32) {
			fored[j]=ctred[9];
			fogreen[j]=ctgreen[9];
			foblue[j]=ctblue[9];
			rval |= no32;
		}
		if (cmp==3) fprintf(stderr, "equal, f2 black error\n");
		if (cmp==5) fprintf(stderr, "equal, f1 black error\n");
		if (cmp==6) fprintf(stderr, "not equal, both black error\n");
            }

	    putrow(iout, fored,   h - 1 - i, 0);
	    putrow(iout, fogreen,   h - 1 - i, 1);
	    putrow(iout, foblue,   h - 1 - i, 2);
	}
	
	iclose(iout);
	iclose(i2);
	iclose(i1);

	return rval;
}

void usage(void) 
{
	fprintf(stderr, "usage:\nidf  [-z] infile1 file2 outputfile\n");
	fprintf(stderr, "Options:\n");
	fprintf(stderr, "   -z    compare z files\n");
	fprintf(stderr, "   -c    compare coverage (.cov) files (background=white)\n");
	fprintf(stderr, "   -r##  set background color red to 0x##\n");
	fprintf(stderr, "   -g##  set background color green to 0x##\n");
	fprintf(stderr, "   -b##  set background color blue to 0x##\n");
	fprintf(stderr, "   -d    enable dithering compare\n");
	fprintf(stderr, "   -3    enable 32/16 bit compare\n");
	exit(1);
}

int main(int argc, char **argv)
{
    	int i=1,j=0,c;
	char *fn[3];
	int rval;

	rednull=0x00;	/* default background color is cyan */
	greennull=0xc8;
	bluenull=0xc8;
	while (i<argc) {
		if (argv[i][0]=='-') switch (argv[i][1]) {
			case 'z' : 
				rednull=0xff;
				greennull=0xff;
				bluenull=0x03;
				break;
			case 'c' : 
				rednull=0xff;
				greennull=0xff;
				bluenull=0xff;
				break;
			case 'r' :
				rednull=(argv[i][2]-'0')*0x10 +
					(argv[i][3]-'0');
				if (rednull>255 || rednull<0) usage();
				break;
			case 'g' :
				greennull=(argv[i][2]-'0')*0x10 +
					(argv[i][3]-'0');
				if (greennull>255 || greennull<0) usage();
				break;
			case 'b' :
				bluenull=(argv[i][2]-'0')*0x10 +
					(argv[i][3]-'0');
				if (bluenull>255 || bluenull<0) usage();
				break;
			case 'd' :
				nodither=0;
				break;
			case '3' :
				no32=0;
				break;
		} else {
			if (j<3)
				fn[j++]=argv[i];
			else {
				usage();
			}
		}
		i++;
	}

	if (j!=3) usage();

	rval = docompare(fn[0],fn[1],fn[2]);
	return(rval);
}