예제 #1
0
int
main(
	int argc,
	char *argv[]
) {
	int fa,nfa;				/* argument we're looking at */
	int verb = 0;
	int chan = 0;			/* Chosen channel to plot against */
	char in_name[100];

	char *buf, *outc;
	int ti;
	cgats *cgf = NULL;			/* cgats file data */
	int isLab = 0;				/* cgats output is Lab, else XYZ */
	char *xyzfname[3] = { "XYZ_X", "XYZ_Y", "XYZ_Z" };
	char *labfname[3] = { "LAB_L", "LAB_A", "LAB_B" };
	int npat;					/* Number of patches */ 
	inkmask nmask;				/* Device inkmask */
	int nchan;					/* Number of input chanels */
	char *bident;				/* Base ident */
	int chix[ICX_MXINKS];	/* Device chanel indexes */
	int pcsix[3];	/* Device chanel indexes */
	pval *pat;					/* patch values */
	int i, j;
	
	error_program = argv[0];

	if (argc < 2)
		usage();

	/* Process the arguments */
	for(fa = 1;fa < argc;fa++) {
		nfa = fa;					/* skip to nfa if next argument is used */
		if (argv[fa][0] == '-')	{	/* Look for any flags */
			char *na = NULL;		/* next argument after flag, null if none */

			if (argv[fa][2] != '\000')
				na = &argv[fa][2];		/* next is directly after flag */
			else {
				if ((fa+1) < argc) {
					if (argv[fa+1][0] != '-') {
						nfa = fa + 1;
						na = argv[nfa];		/* next is seperate non-flag argument */
					}
				}
			}

			/* Verbosity */
			if (argv[fa][1] == 'v' || argv[fa][1] == 'V') {
				verb = 1;
			}

			else if (argv[fa][1] >= '0' && argv[fa][1] <= '9') {
				chan = argv[fa][1] - '0';
			}
			else if (argv[fa][1] == '?')
				usage();
			else 
				usage();
		}
		else
			break;
	}

	if (fa >= argc || argv[fa][0] == '-') usage();
	strcpy(in_name,argv[fa]);

	/* Open CIE target values */
	cgf = new_cgats();			/* Create a CGATS structure */
	cgf->add_other(cgf, "CTI3");/* our special input type is Calibration Target Information 3 */
	if (cgf->read_name(cgf, in_name))
		error("CGATS file read error %s on file '%s'",cgf->err, in_name);

	if (cgf->ntables == 0 || cgf->t[0].tt != tt_other || cgf->t[0].oi != 0)
		error ("Profile file '%s' isn't a CTI3 format file",in_name);

	if (cgf->ntables < 1)
		error ("Input file '%s' doesn't contain at least one table",in_name);

	if ((ti = cgf->find_kword(cgf, 0, "COLOR_REP")) < 0)
		error("Input file doesn't contain keyword COLOR_REPS");
	
	if ((buf = strdup(cgf->t[0].kdata[ti])) == NULL)
		error("Malloc failed");
	
	/* Split COLOR_REP into device and PCS space */
	if ((outc = strchr(buf, '_')) == NULL)
		error("COLOR_REP '%s' invalid", cgf->t[0].kdata[ti]);
	*outc++ = '\000';
	
	if (strcmp(outc, "XYZ") == 0) {
		isLab = 0;
	} else if (strcmp(outc, "LAB") == 0) {
		isLab = 1;
	} else
		error("COLOR_REP '%s' invalid (Neither XYZ nor LAB)", cgf->t[0].kdata[ti]);

	if ((nmask = icx_char2inkmask(buf)) == 0) {
		error ("File '%s' keyword COLOR_REPS has unknown device value '%s'",in_name,buf);
	}

	free(buf);

	nchan = icx_noofinks(nmask);
	bident = icx_inkmask2char(nmask, 0);		/* Base ident (No possible 'i') */ 

	/* Find device fields */
	for (j = 0; j < nchan; j++) {
		int ii, imask;
		char fname[100];

		imask = icx_index2ink(nmask, j);
		sprintf(fname,"%s_%s",nmask == ICX_W || nmask == ICX_K ? "GRAY" : bident,
		                      icx_ink2char(imask));

		if ((ii = cgf->find_field(cgf, 0, fname)) < 0)
			error ("Input file doesn't contain field %s",fname);
		if (cgf->t[0].ftype[ii] != r_t)
			error ("Field %s is wrong type",fname);
		chix[j] = ii;
	}

	/* Find PCS fields */
	for (j = 0; j < 3; j++) {
		int ii;

		if ((ii = cgf->find_field(cgf, 0, isLab ? labfname[j] : xyzfname[j])) < 0)
			error ("Input file doesn't contain field %s",isLab ? labfname[j] : xyzfname[j]);
		if (cgf->t[0].ftype[ii] != r_t)
			error ("Field %s is wrong type",isLab ? labfname[j] : xyzfname[j]);
		pcsix[j] = ii;
	}

	npat = cgf->t[0].nsets;		/* Number of patches */

	if (npat <= 0)
		error("No sets of data in file '%s'",in_name);

	/* Allocate arrays to hold test patch input and output values */
	if ((pat = (pval *)malloc(sizeof(pval) * npat)) == NULL)
		error("Malloc failed - pat[]");

	/* Grab all the values */
	for (i = 0; i < npat; i++) {
		pat[i].v[0] = *((double *)cgf->t[0].fdata[i][pcsix[0]]);
		pat[i].v[1] = *((double *)cgf->t[0].fdata[i][pcsix[1]]);
		pat[i].v[2] = *((double *)cgf->t[0].fdata[i][pcsix[2]]);
		if (!isLab) {
			pat[i].v[0] /= 100.0;		/* Normalise XYZ to range 0.0 - 1.0 */
			pat[i].v[1] /= 100.0;
			pat[i].v[2] /= 100.0;
		}
		if (!isLab) { /* Convert test patch result XYZ to PCS (D50 Lab) */
			icmXYZ2Lab(&icmD50, pat[i].v, pat[i].v);
		}
		for (j = 0; j < nchan; j++) {
			pat[i].d[j] = *((double *)cgf->t[0].fdata[i][chix[j]]);
		}
	}

	/* Sort by the selected channel */
#define HEAP_COMPARE(A,B) (A.d[chan] < B.d[chan])
	HEAPSORT(pval, pat, npat);
#undef HEAP_COMPARE

	/* Create the plot */
	{
		int i;
		double *xx;
		double *y0;
		double *y1;
		double *y2;

		if ((xx = (double *)malloc(sizeof(double) * npat)) == NULL)
			error("Malloc failed - xx[]");
		if ((y0 = (double *)malloc(sizeof(double) * npat)) == NULL)
			error("Malloc failed - y0[]");
		if ((y1 = (double *)malloc(sizeof(double) * npat)) == NULL)
			error("Malloc failed - y1[]");
		if ((y2 = (double *)malloc(sizeof(double) * npat)) == NULL)
			error("Malloc failed - y2[]");
		
		for (i = 0; i < npat; i++) {
			xx[i] = pat[i].d[chan];
			y0[i] = pat[i].v[0];
			y1[i] = 50 + pat[i].v[1]/2.0;
			y2[i] = 50 + pat[i].v[2]/2.0;

//			printf("~1 %d: xx = %f, y = %f %f %f\n",i,xx[i],y0[i],y1[i],y2[i]);
		}
		do_plot6(xx,y0,y1,NULL,NULL,y2,NULL,npat);

		free(y2);
		free(y1);
		free(y0);
		free(xx);
	}

	free(pat);
	cgf->del(cgf);

	return 0;
}
예제 #2
0
파일: mpplu.c 프로젝트: comstock/hargyllcms
int
main(int argc, char *argv[]) {
	int fa,nfa;				/* argument we're looking at */
	char prof_name[100];
	mpp *mppo;
	int verb = 0;
	int test = 0;			/* special test code */
	int dogam = 0;			/* Create gamut */
	int dowrl = 0;			/* Create VRML gamut */
	int doaxes = 1;			/* Create VRML axes */
	double trans = 0.0;		/* Transparency */
	double gamres = 0.0;	/* Gamut resolution */
	int repYxy = 0;			/* Report Yxy */
	int repSpec = 0;		/* Report Spectral */
	int bwd = 0;			/* Do reverse lookup */
	double dlimit;			/* Device ink limit */
	double limit = -1.0;	/* Used ink limit */
	int spec = 0;			/* Use spectral data flag */
	int    spec_n;			/* Number of spectral bands, 0 if not valid */
	double spec_wl_short;	/* First reading wavelength in nm (shortest) */
	double spec_wl_long;	/* Last reading wavelength in nm (longest) */
	int fwacomp = 0;		/* FWA compensation */
	icxIllumeType illum = icxIT_default;	/* Spectral defaults */
	xspect cust_illum;		/* Custom illumination spectrum */
	icxObserverType observ = icxOT_default;
	char buf[200];
	double in[MAX_CHAN], out[MAX_CHAN];
	int rv = 0;

	inkmask imask;						/* Device Ink mask */
	char *ident = NULL;					/* Device colorspec description */
	icColorSpaceSignature pcss;			/* Type of PCS space */
	int devn, pcsn;						/* Number of components */

	icColorSpaceSignature pcsor = icSigLabData;	/* Default */
	
	error_program = argv[0];

	if (argc < 2)
		usage();

	/* Process the arguments */
	for(fa = 1;fa < argc;fa++) {
		nfa = fa;					/* skip to nfa if next argument is used */
		if (argv[fa][0] == '-')	{	/* Look for any flags */
			char *na = NULL;		/* next argument after flag, null if none */

			if (argv[fa][2] != '\000')
				na = &argv[fa][2];		/* next is directly after flag */
			else {
				if ((fa+1) < argc) {
					if (argv[fa+1][0] != '-') {
						nfa = fa + 1;
						na = argv[nfa];		/* next is seperate non-flag argument */
					}
				}
			}

			if (argv[fa][1] == '?')
				usage();

			/* Verbosity */
			else if (argv[fa][1] == 'v' || argv[fa][1] == 'V') {
				verb = 1;
			}
			/* function */
			else if (argv[fa][1] == 'f' || argv[fa][1] == 'F') {
				fa = nfa;
				if (na == NULL) usage();
    			switch (na[0]) {
					case 'f':
					case 'F':
						bwd = 0;
						break;
					case 'b':
					case 'B':
						bwd = 1;
						break;
					default:
						usage();
				}
			}

			/* PCS override */
			else if (argv[fa][1] == 'p' || argv[fa][1] == 'P') {
				fa = nfa;
				if (na == NULL) usage();
    			switch (na[0]) {
					case 'x':
					case 'X':
						pcsor = icSigXYZData;
						repYxy = repSpec = 0;
						break;
					case 'l':
					case 'L':
						pcsor = icSigLabData;
						repYxy = repSpec = 0;
						break;
					case 'y':
					case 'Y':
						pcsor = icSigXYZData;
						repYxy = 1;
						repSpec = 0;
						break;
					case 's':
					case 'S':
						pcsor = icSigXYZData;
						repYxy = 0;
						repSpec = 1;
						spec = 1;
						break;
					default:
						usage();
				}
			}

			/* Ink Limit */
			else if (argv[fa][1] == 'l' || argv[fa][1] == 'L') {
				fa = nfa;
				if (na == NULL) usage();
				limit = atof(na);
			}

			/* Spectral Illuminant type */
			else if (argv[fa][1] == 'i' || argv[fa][1] == 'I') {
				fa = nfa;
				if (na == NULL) usage();
				if (strcmp(na, "A") == 0) {
					spec = 1;
					illum = icxIT_A;
				} else if (strcmp(na, "C") == 0) {
					spec = 1;
					illum = icxIT_C;
				} else if (strcmp(na, "D50") == 0) {
					spec = 1;
					illum = icxIT_D50;
				} else if (strcmp(na, "D65") == 0) {
					spec = 1;
					illum = icxIT_D65;
				} else if (strcmp(na, "F5") == 0) {
					spec = 1;
					illum = icxIT_F5;
				} else if (strcmp(na, "F8") == 0) {
					spec = 1;
					illum = icxIT_F8;
				} else if (strcmp(na, "F10") == 0) {
					spec = 1;
					illum = icxIT_F10;
				} else {	/* Assume it's a filename */
					spec = 1;
					illum = icxIT_custom;
					if (read_xspect(&cust_illum, na) != 0)
						usage();
				}
			}

			/* Spectral Observer type */
			else if (argv[fa][1] == 'o' || argv[fa][1] == 'O') {
				fa = nfa;
				if (na == NULL) usage();
				if (strcmp(na, "1931_2") == 0) {			/* Classic 2 degree */
					spec = 1;
					observ = icxOT_CIE_1931_2;
				} else if (strcmp(na, "1964_10") == 0) {	/* Classic 10 degree */
					spec = 1;
					observ = icxOT_CIE_1964_10;
				} else if (strcmp(na, "1955_2") == 0) {		/* Stiles and Burch 1955 2 degree */
					spec = 1;
					observ = icxOT_Stiles_Burch_2;
				} else if (strcmp(na, "1978_2") == 0) {		/* Judd and Voss 1978 2 degree */
					spec = 1;
					observ = icxOT_Judd_Voss_2;
				} else if (strcmp(na, "shaw") == 0) {		/* Shaw and Fairchilds 1997 2 degree */
					spec = 1;
					observ = icxOT_Shaw_Fairchild_2;
				} else
					usage();
			}

			/* Fluerescent Whitner compensation */
			else if (argv[fa][1] == 'u' || argv[fa][1] == 'U')
				fwacomp = 1;

			/* Gamut plot */
			else if (argv[fa][1] == 'g' || argv[fa][1] == 'G')
				dogam = 1;

			/* VRML plot */
			else if (argv[fa][1] == 'w' || argv[fa][1] == 'W') {
				dogam = 1;
				dowrl = 1;
			}

			/* No VRML axes */
			else if (argv[fa][1] == 'n' || argv[fa][1] == 'N') {
				doaxes = 0;
			}

			/* Transparency */
			else if (argv[fa][1] == 'a' || argv[fa][1] == 'A') {
				fa = nfa;
				if (na == NULL) usage();
				trans = atof(na);
			}

			/* Surface Detail */
			else if (argv[fa][1] == 'd' || argv[fa][1] == 'D') {
				fa = nfa;
				if (na == NULL) usage();
				gamres = atof(na);
				dogam = 1;
			}

			/* Test code */
			else if (argv[fa][1] == 't' || argv[fa][1] == 'T') {
				fa = nfa;
				if (na == NULL) usage();
				test = atoi(na);
			}

			else 
				usage();
		} else
			break;
	}

	if (fa >= argc || argv[fa][0] == '-') usage();
	strcpy(prof_name,argv[fa]);

	if ((mppo = new_mpp()) == NULL)
		error ("Creation of MPP object failed");

	if ((rv = mppo->read_mpp(mppo,prof_name)) != 0)
		error ("%d, %s",rv,mppo->err);

	mppo->get_info(mppo, &imask, &devn, &dlimit, &spec_n, &spec_wl_short, &spec_wl_long, NULL);
	ident = icx_inkmask2char(imask, 1); 

	if (verb) {
		printf("MPP profile with %d colorants, type %s, TAC %f\n",devn,ident, dlimit);
	}

	if (limit <= 0.0 || dlimit < limit)
		limit = dlimit;

	pcss = pcsor;
	pcsn = 3;

	if (spec && spec_n == 0) {
		error("Spectral profile needed for spectral result, custom illuminant, observer or FWA");
	}

	/* Select CIE return value details */
	if ((rv = mppo->set_ilob(mppo, illum, &cust_illum, observ, NULL, pcss, fwacomp)) != 0) {
		if (rv == 1)
			error("Spectral profile needed for custom illuminant, observer or FWA");
		error("Error setting illuminant, observer, or FWA");
	}

	if (test != 0) {
		printf("!!!!! Running special test code no %d !!!!!\n",test);

		if (test == 1) {
			double **dv, **rdv;

			dv = dmatrix(0, pcsn-1, 0, devn-1);
			rdv = dmatrix(0, pcsn-1, 0, devn-1);

			printf("Checking partial derivative at each input value\n");
			/* Process colors to translate */
			for (;;) {
				int i,j;
				char *bp, *nbp;
				double tout[MAX_CHAN];

				/* Read in the next line */
				if (fgets(buf, 200, stdin) == NULL)
					break;
				if (buf[0] == '#') {
					fprintf(stdout,"%s\n",buf);
					continue;
				}
				/* For each input number */
				for (bp = buf-1, nbp = buf, i = 0; i < MAX_CHAN; i++) {
					bp = nbp;
					in[i] = strtod(bp, &nbp);
					if (nbp == bp)
						break;			/* Failed */
				}
				if (i == 0)
					break;

				/* Do conversion */
				mppo->lookup(mppo, out, in);
				mppo->dlookup(mppo, out, dv, in);
		
				for (j = 0; j < devn; j++) {
					double del = 1e-9;

					if (in[j] > 0.5)
						del = -del;

					in[j] += del;
					mppo->lookup(mppo, tout, in);
					in[j] -= del;
					
					for (i = 0; i < pcsn; i++) {
						rdv[i][j] = (tout[i] - out[i])/del;
					}
				}

				/* Output the results */
				for (j = 0; j < devn; j++) {
					if (j > 0)
						fprintf(stdout," %f",in[j]);
					else
						fprintf(stdout,"%f",in[j]);
				}
				printf(" [%s] -> ", ident);
		
				for (j = 0; j < pcsn; j++) {
					if (j > 0)
						fprintf(stdout," %f",out[j]);
					else
						fprintf(stdout,"%f",out[j]);
				}
				printf(" [%s]\n", icm2str(icmColorSpaceSignature, pcss));

				/* Print the derivatives */
				for (i = 0; i < pcsn; i++) {
					
					printf("Output chan %d: ",i);
					for (j = 0; j < devn; j++) {
						if (j < (devn-1))
							fprintf(stdout,"%f ref %f, ",dv[i][j], rdv[i][j]);
						else
							fprintf(stdout,"%f ref %f\n",dv[i][j], rdv[i][j]);
					}
				}
			}

			free_dmatrix(dv, 0, pcsn-1, 0, devn-1);
			free_dmatrix(rdv, 0, pcsn-1, 0, devn-1);

		} else if (test == 2) {
			char *xl, gam_name[100];

			strcpy(gam_name, prof_name);
			if ((xl = strrchr(gam_name, '.')) == NULL)	/* Figure where extention is */
				xl = gam_name + strlen(gam_name);
	
			strcpy(xl,".wrl");
			diag_gamut(mppo, gamres, doaxes, trans, gam_name);

		} else {
			printf("Unknown test!\n");
		}

	} else if (dogam) {
		gamut *gam;
		char *xl, gam_name[100];
		int docusps = 1;

		if ((gam = mppo->get_gamut(mppo, gamres)) == NULL)
			error("get_gamut failed\n");

		strcpy(gam_name, prof_name);
		if ((xl = strrchr(gam_name, '.')) == NULL)	/* Figure where extention is */
			xl = gam_name + strlen(gam_name);
	
		strcpy(xl,".gam");
		if (gam->write_gam(gam,gam_name))
			error ("write gamut failed on '%s'",gam_name);
	
		if (dowrl) {
			strcpy(xl,".wrl");
			if (gam->write_vrml(gam,gam_name, doaxes, docusps))
				error ("write vrml failed on '%s'",gam_name);
		}

		gam->del(gam);

	} else {
		/* Normal color lookup */

		if (repYxy) {	/* report Yxy rather than XYZ */
			if (pcss == icSigXYZData)
				pcss = icSigYxyData; 
		}

		/* Process colors to translate */
		for (;;) {
			int i,j;
			char *bp, *nbp;

			/* Read in the next line */
			if (fgets(buf, 200, stdin) == NULL)
				break;
			if (buf[0] == '#') {
				fprintf(stdout,"%s\n",buf);
				continue;
			}
			/* For each input number */
			for (bp = buf-1, nbp = buf, i = 0; i < MAX_CHAN; i++) {
				bp = nbp;
				in[i] = strtod(bp, &nbp);
				if (nbp == bp)
					break;			/* Failed */
			}
			if (i == 0)
				break;

			if (!bwd) {

				if (repSpec) {
					xspect ospec;

					/* Do lookup of spectrum */
					mppo->lookup_spec(mppo, &ospec, in);
			
					/* Output the results */
					for (j = 0; j < devn; j++) {
						if (j > 0)
							fprintf(stdout," %f",in[j]);
						else
							fprintf(stdout,"%f",in[j]);
					}
					printf(" [%s] -> ", ident);
			
					for (j = 0; j < spec_n; j++) {
						if (j > 0)
							fprintf(stdout," %f",ospec.spec[j]);
						else
							fprintf(stdout,"%f",ospec.spec[j]);
					}

					printf(" [%3.0f .. %3.0f nm]\n", spec_wl_short, spec_wl_long);

				} else {

					/* Do conversion */
					mppo->lookup(mppo, out, in);
			
					/* Output the results */
					for (j = 0; j < devn; j++) {
						if (j > 0)
							fprintf(stdout," %f",in[j]);
						else
							fprintf(stdout,"%f",in[j]);
					}
					printf(" [%s] -> ", ident);
			
					if (repYxy && pcss == icSigYxyData) {
						double X = out[0];
						double Y = out[1];
						double Z = out[2];
						double sum = X + Y + Z;
						if (sum < 1e-6) {
							out[0] = out[1] = out[2] = 0.0;
						} else {
							out[0] = Y;
							out[1] = X/sum;
							out[2] = Y/sum;
						}
					}
					for (j = 0; j < pcsn; j++) {
						if (j > 0)
							fprintf(stdout," %f",out[j]);
						else
							fprintf(stdout,"%f",out[j]);
					}

					printf(" [%s]\n", icm2str(icmColorSpaceSignature, pcss));
				}

			} else {	/* Do a reverse lookup */

				if (repYxy && pcss == icSigYxyData) {
					double Y = in[0];
					double x = in[1];
					double y = in[2];
					double z = 1.0 - x - y;
					double sum;
					if (y < 1e-6) {
						in[0] = in[1] = in[2] = 0.0;
					} else {
						sum = Y/y;
						in[0] = x * sum;
						in[1] = Y;
						in[2] = z * sum;
					}
				}

				/* Do conversion */
				mpp_rev(mppo, limit, out, in);

				/* Output the results */
				for (j = 0; j < pcsn; j++) {
					if (j > 0)
						fprintf(stdout," %f",in[j]);
					else
						fprintf(stdout,"%f",in[j]);
				}
				printf(" [%s] -> ", icm2str(icmColorSpaceSignature, pcss));
		
				for (j = 0; j < devn; j++) {
					if (j > 0)
						fprintf(stdout," %f",out[j]);
					else
						fprintf(stdout,"%f",out[j]);
				}

				printf(" [%s]\n", ident);
			}
		}
	}

	free(ident);
	mppo->del(mppo);

	return 0;
}