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; }
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; }