int main(int argc, char *argv[]) { int i; char out_name[MAXNAMEL+1]; /* VRML output file */ double gamres = GAMRES; /* Surface resolution */ gamut *gam; #if defined(__IBMC__) && defined(_M_IX86) _control87(EM_UNDERFLOW, EM_UNDERFLOW); #endif if (argc < 2) { strcpy(out_name, "RefMediumGamut.gam"); } else { strncpy(out_name,argv[1],MAXNAMEL); out_name[MAXNAMEL] = '\000'; } /* Creat a gamut surface */ gam = new_gamut(gamres, 0, 0); /* For all the supplied surface points, */ /* add them to the gamut */ for (i = 0; i < NPOINTS; i++) { double lab[3]; icmLCh2Lab(lab, points[i]); //printf("~1 LCh %f %f %f -> Lab %f %f %f\n", points[i][0], points[i][1], points[i][2], lab[0], lab[1], lab[2]); gam->expand(gam, lab); } /* Add selected cusp points to set cusp values */ gam->setcusps(gam, 0, NULL); for (i = 0; i < 6; i++) { double lab[3]; icmLCh2Lab(lab, cpoints[i]); //printf("~1 LCh %f %f %f -> Lab %f %f %f\n", points[i][0], points[i][1], points[i][2], lab[0], lab[1], lab[2]); gam->setcusps(gam, 1, lab); } gam->setcusps(gam, 2, NULL); if (gam->write_gam(gam, out_name)) error ("write gamut failed on '%s'",out_name); gam->del(gam); return 0; }
int main(int argc, char *argv[]) { int fa,nfa; /* argument we're looking at */ char out_name[100]; int npoints = DEF_POINTS; int ntpoints = DEF_TPOINTS; double height = DEF_HEIGHT; gamut *gam; int rand = 0; int verb = 0; int doaxes = 1; int dofilt = 0; int i; #ifdef NUMSUP_H error_program = "surftest"; #endif /* 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(NULL); /* Verbosity */ else if (argv[fa][1] == 'v' || argv[fa][1] == 'V') { verb = 1; } /* Random */ else if (argv[fa][1] == 'r' || argv[fa][1] == 'R') { rand = 1; } /* No axis output */ else if (argv[fa][1] == 'n' || argv[fa][1] == 'N') { doaxes = 0; } /* Segmented maxima filtering */ else if (argv[fa][1] == 'f' || argv[fa][1] == 'F') { dofilt = 1; } /* Height */ else if (argv[fa][1] == 'h' || argv[fa][1] == 'H') { fa = nfa; if (na == NULL) usage("No parameter after flag -h"); height = atof(na); } /* Number of test points */ else if (argv[fa][1] == 't' || argv[fa][1] == 'T') { fa = nfa; if (na == NULL) usage("No parameter after flag -t"); ntpoints = atoi(na); } else usage("Unknown flag"); } else break; } if (fa < argc && argv[fa][0] != '-') npoints = atoi(argv[fa]); strcpy(out_name,"surftest.wrl"); if (verb) { printf("Number of surface points = %d\n",npoints * npoints * npoints); printf("Number of test points = %d\n",ntpoints); } /* Creat a gamut object */ if ((gam = new_gamut(0.0, 0, 0)) == NULL) error("Failed to create aa gamut object\n"); if (dofilt == 0) gam->setnofilt(gam); if (rand) { npoints = npoints * npoints * npoints; /* Create and add our random test points */ for (i = 0; i < npoints;) { int j; double pp[3], sum, rad; /* Make normalzed random direction vector on sphere radius 30 */ for (sum = 0.0, j = 0; j < 3; j++) { double tt = d_rand(-1.0, 1.0); pp[j] = tt; sum += tt * tt; } if (sum < 1e-6) continue; sum = sqrt(sum); rad = d_rand(30.0, 30.0 + height); for (j = 0; j < 3; j++) { pp[j] /= sum; pp[j] *= rad; } pp[0] += 50.0; //printf("~1 point %f %f %f\n",pp[0],pp[1],pp[2]); // if (verb) printf("\r%d",i+1); fflush(stdout); gam->expand(gam, pp); i++; } // if (verb) printf("\n"); } else { int co[3]; /* Create and add our gridded test points */ for (co[0] = 0; co[0] < npoints; co[0]++) { for (co[1] = 0; co[1] < npoints; co[1]++) { for (co[2] = 0; co[2] < npoints; co[2]++) { double pp[3], sum, rad; int m, n; #ifndef NEVER /* Make sure at least one coords are 0 & 1 */ for (n = m = 0; m < 3; m++) { if (co[m] == 0 || co[m] == (npoints-1)) n++; } if (n < 1) continue; #endif pp[0] = 2.0 * (co[0]/(npoints-1.0) - 0.5); pp[1] = 2.0 * (co[1]/(npoints-1.0) - 0.5); pp[2] = 2.0 * (co[2]/(npoints-1.0) - 0.5); #ifdef NEVER /* Make normalzed random direction vector on sphere radius 30 */ for (sum = 0.0, m = 0; m < 3; m++) { sum += pp[m] * pp[m]; } if (sum < 1e-6) continue; sum = sqrt(sum); #else sum = 1.0; #endif /* NEVER */ rad = d_rand(30.0, 30.0 + height); for (m = 0; m < 3; m++) { pp[m] /= sum; pp[m] *= rad; } pp[0] += 50.0; //printf("~1 point %f %f %f\n",pp[0],pp[1],pp[2]); gam->expand(gam, pp); } } } } /* Write out the gamut surface */ if (gam->write_vrml(gam, out_name, doaxes, 0)) error ("write vrml failed on '%s'",out_name); if (verb) printf("Written out the gamut surface\n"); /* Test the gamut surface */ for (i = 0; i < ntpoints;) { int j; double pp[3], sum; double r, out[3]; /* Make normalzed random direction vector on sphere */ for (sum = 0.0, j = 0; j < 3; j++) { double tt = d_rand(-1.0, 1.0); pp[j] = tt; sum += tt * tt; } if (sum < 1e-6) continue; sum = sqrt(sum); for (j = 0; j < 3; j++) { pp[j] /= sum; } /* Test surface */ r = gam->radial(gam, out, pp); i++; } gam->del(gam); return 0; }
/* Return NULL on error, check errc+err for reason */ static gamut *icxLuMatrixGamut( icxLuBase *plu, /* this */ double detail /* gamut detail level, 0.0 = def */ ) { xicc *p = plu->pp; /* parent xicc */ icxLuMatrix *lumat = (icxLuMatrix *)plu; /* Lookup xMatrix type object */ icColorSpaceSignature pcs; icmLookupFunc func; double white[3], black[3], kblack[3]; gamut *gam; int res; /* Sample point resolution */ int i, e; if (detail == 0.0) detail = 10.0; /* get some details */ plu->spaces(plu, NULL, NULL, NULL, NULL, NULL, NULL, &func, &pcs); if (func != icmFwd && func != icmBwd) { p->errc = 1; sprintf(p->err,"Creating Gamut surface for anything other than Device <-> PCS is not supported."); return NULL; } if (pcs != icSigLabData && pcs != icxSigJabData) { p->errc = 1; sprintf(p->err,"Creating Gamut surface PCS of other than Lab or Jab is not supported."); return NULL; } gam = new_gamut(detail, pcs == icxSigJabData, 0); /* Explore the gamut by itterating through */ /* it with sample points in device space. */ res = (int)(600.0/detail); /* Establish an appropriate sampling density */ if (res < 40) res = 40; /* Since matrix profiles can't be non-monotonic, */ /* just itterate through the surface colors. */ for (i = 0; i < 3; i++) { int co[3]; int ep[3]; int co_e = 0; for (e = 0; e < 3; e++) { co[e] = 0; ep[e] = res; } ep[i] = 2; while (co_e < 3) { double in[3]; double out[3]; for (e = 0; e < 3; e++) /* Convert count to input value */ in[e] = co[e]/(ep[e]-1.0); /* Always use the device->PCS conversion */ if (lumat->fwd_lookup((icxLuBase *)lumat, out, in) > 1) error ("%d, %s",p->errc,p->err); gam->expand(gam, out); /* Increment the counter */ for (co_e = 0; co_e < 3; co_e++) { co[co_e]++; if (co[co_e] < ep[co_e]) break; /* No carry */ co[co_e] = 0; } } } #ifdef NEVER /* Try it twice */ for (i = 0; i < 3; i++) { int co[3]; int ep[3]; int co_e = 0; for (e = 0; e < 3; e++) { co[e] = 0; ep[e] = res; } ep[i] = 2; while (co_e < 3) { double in[3]; double out[3]; for (e = 0; e < 3; e++) /* Convert count to input value */ in[e] = co[e]/(ep[e]-1.0); /* Always use the device->PCS conversion */ if (lumat->fwd_lookup((icxLuBase *)lumat, out, in) > 1) error ("%d, %s",p->errc,p->err); gam->expand(gam, out); /* Increment the counter */ for (co_e = 0; co_e < 3; co_e++) { co[co_e]++; if (co[co_e] < ep[co_e]) break; /* No carry */ co[co_e] = 0; } } } #endif #ifdef NEVER // (doesn't seem to make much difference) /* run along the primary ridges in more detail too */ /* just itterate through the surface colors. */ for (i = 0; i < 3; i++) { int j; double in[3]; double out[3]; res *= 4; for (j = 0; j < res; j++) { double vv = i/(res-1.0); in[0] = in[1] = in[2] = vv; in[i] = 0.0; if (lumat->fwd_lookup((icxLuBase *)lumat, out, in) > 1) error ("%d, %s",p->errc,p->err); gam->expand(gam, out); in[0] = in[1] = in[2] = 0.0; in[i] = vv; if (lumat->fwd_lookup((icxLuBase *)lumat, out, in) > 1) error ("%d, %s",p->errc,p->err); gam->expand(gam, out); } } #endif /* Put the white and black points in the gamut */ plu->efv_wh_bk_points(plu, white, black, kblack); gam->setwb(gam, white, black, kblack); /* set the cusp points by itterating through the 0 & 100% colorant combinations */ { DCOUNT(co, 3, 3, 0, 0, 2); gam->setcusps(gam, 0, NULL); DC_INIT(co); while(!DC_DONE(co)) { int e; double in[3]; double out[3]; if (!(co[0] == 0 && co[1] == 0 && co[2] == 0) && !(co[0] == 1 && co[1] == 1 && co[2] == 1)) { /* Skip white and black */ for (e = 0; e < 3; e++) in[e] = (double)co[e]; /* Always use the device->PCS conversion */ if (lumat->fwd_lookup((icxLuBase *)lumat, out, in) > 1) error ("%d, %s",p->errc,p->err); gam->setcusps(gam, 3, out); } DC_INC(co); } gam->setcusps(gam, 2, NULL); } #ifdef NEVER /* Not sure if this is a good idea ?? */ gam->getwb(gam, NULL, NULL, white, black); /* Get the actual gamut white and black points */ gam->setwb(gam, white, black); /* Put it back as colorspace one */ #endif return gam; }
int main(int argc, char *argv[]) { int fa, nfa, mfa; /* argument we're looking at */ int n, ng = 0; /* Current allocation, number of input gamuts */ gamdisp *gds; /* Definition of each gamut */ int doaxes = 1; int docusps = 0; int isect = 0; FILE *wrl; char out_name[MAXNAMEL+1]; char iout_name[MAXNAMEL+1] = "\000";; if (argc < 3) usage("Too few arguments, got %d expect at least 2",argc-1); mfa = 1; /* Minimum final arguments */ if ((gds = (gamdisp *)malloc((ng+1) * sizeof(gamdisp))) == NULL) error("Malloc failed on gamdisp"); set_default(gds, 0); /* 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+mfa) < argc) { if (argv[fa+1][0] != '-') { nfa = fa + 1; na = argv[nfa]; /* next is seperate non-flag argument */ } } } if (argv[fa][1] == '?') usage("Usage requested"); /* Color */ else if (argv[fa][1] == 'c' || argv[fa][1] == 'C') { fa = nfa; if (na == NULL) usage("Expect argument after flag -c"); switch (na[0]) { case 'r': case 'R': gds[ng].in_colors = gam_red; break; case 'g': case 'G': gds[ng].in_colors = gam_green; break; case 'b': case 'B': gds[ng].in_colors = gam_blue; break; case 'c': case 'C': gds[ng].in_colors = gam_cyan; break; case 'm': case 'M': gds[ng].in_colors = gam_magenta; break; case 'y': case 'Y': gds[ng].in_colors = gam_yellow; break; case 'e': case 'E': gds[ng].in_colors = gam_grey; break; case 'w': case 'W': gds[ng].in_colors = gam_white; break; case 'n': case 'N': gds[ng].in_colors = gam_natural; break; default: usage("Unknown argument after flag -c '%c'",na[0]); } } /* Transparency */ else if (argv[fa][1] == 't' || argv[fa][1] == 'T') { double v; fa = nfa; if (na == NULL) usage("Expect argument after flag -t"); v = atof(na); if (v < 0.0) v = 0.0; else if (v > 1.0) v = 1.0; gds[ng].in_trans = v; } /* Solid output */ else if (argv[fa][1] == 's' || argv[fa][1] == 'S') { gds[ng].in_rep = gam_solid; } /* Wireframe output */ else if (argv[fa][1] == 'w' || argv[fa][1] == 'W') { gds[ng].in_rep = gam_wire; } /* No axis output */ else if (argv[fa][1] == 'n' || argv[fa][1] == 'N') { doaxes = 0; } /* Add cusp markers */ else if (argv[fa][1] == 'k' || argv[fa][1] == 'K') { docusps = 1; } /* Print intersecting volume */ else if (argv[fa][1] == 'i' || argv[fa][1] == 'I') { isect = 1; /* There is an intersection output gamut file */ if (argv[fa][1] == 'I' && na != NULL) { fa = nfa; strncpy(iout_name, na, MAXNAMEL); iout_name[MAXNAMEL] = '\000'; } } else usage("Unknown flag '%c'",argv[fa][1]); } else if (argv[fa][0] != '\000') { /* Got a non-flag */ strncpy(gds[ng].in_name,argv[fa],MAXNAMEL); gds[ng].in_name[MAXNAMEL] = '\000'; ng++; if ((gds = (gamdisp *)realloc(gds, (ng+1) * sizeof(gamdisp))) == NULL) error("Realloc failed on gamdisp"); set_default(gds, ng); } else { break; } } /* The last "gamut" is actually the output VRML filename, */ /* so unwind it. */ if (ng < 2) usage("Not enough arguments to specify output VRML files"); strncpy(out_name,gds[--ng].in_name,MAXNAMEL); out_name[MAXNAMEL] = '\000'; #ifdef DEBUG for (n = 0; n < ng; n++) { printf("Input file %d is '%s'\n",n,gds[n].in_name); printf("Input file %d has color %d\n",n,gds[n].in_colors); printf("Input file %d has rep %d\n",n,gds[n].in_rep); printf("Input file %d has trans %f\n",n,gds[n].in_trans); } printf("Output file is '%s'\n",out_name); #endif /* DEBUG */ /* Open up the output file */ if ((wrl = fopen(out_name,"w")) == NULL) error("Error opening output file '%s'\n",out_name); /* Write the header info */ fprintf(wrl,"#VRML V2.0 utf8\n"); fprintf(wrl,"\n"); fprintf(wrl,"# Created by the Argyll CMS\n"); fprintf(wrl,"Transform {\n"); fprintf(wrl," children [\n"); fprintf(wrl," NavigationInfo {\n"); fprintf(wrl," type \"EXAMINE\" # It's an object we examine\n"); fprintf(wrl," } # We'll add our own light\n"); fprintf(wrl,"\n"); #ifdef NEVER fprintf(wrl," DirectionalLight {\n"); fprintf(wrl," direction 0 0 -1 # Light illuminating the scene\n"); fprintf(wrl," direction 0 -1 0 # Light illuminating the scene\n"); fprintf(wrl," }\n"); #else fprintf(wrl," DirectionalLight {\n"); fprintf(wrl," intensity 0.2\n"); fprintf(wrl," ambientIntensity 0.1\n"); fprintf(wrl," direction -1 -1 -1\n"); fprintf(wrl," }\n"); fprintf(wrl," DirectionalLight {\n"); fprintf(wrl," intensity 0.6\n"); fprintf(wrl," ambientIntensity 0.2\n"); fprintf(wrl," direction 1 1 1\n"); fprintf(wrl," }\n"); #endif fprintf(wrl,"\n"); fprintf(wrl," Viewpoint {\n"); fprintf(wrl," position 0 0 340 # Position we view from\n"); fprintf(wrl," }\n"); fprintf(wrl,"\n"); if (doaxes) { /* Define the axis boxes */ struct { double x, y, z; /* Box center */ double wx, wy, wz; /* Box size */ double r, g, b; /* Box color */ } axes[5] = { { 0, 0, 50-GCENT, 2, 2, 100, .7, .7, .7 }, /* L axis */ { 50, 0, 0-GCENT, 100, 2, 2, 1, 0, 0 }, /* +a (red) axis */ { 0, -50, 0-GCENT, 2, 100, 2, 0, 0, 1 }, /* -b (blue) axis */ { -50, 0, 0-GCENT, 100, 2, 2, 0, 1, 0 }, /* -a (green) axis */ { 0, 50, 0-GCENT, 2, 100, 2, 1, 1, 0 }, /* +b (yellow) axis */ }; /* Define the labels */ struct { double x, y, z; double size; char *string; double r, g, b; } labels[6] = { { -2, 2, -GCENT + 100 + 10, 10, "+L*", .7, .7, .7 }, /* Top of L axis */ { -2, 2, -GCENT - 10, 10, "0", .7, .7, .7 }, /* Bottom of L axis */ { 100 + 5, -3, 0-GCENT, 10, "+a*", 1, 0, 0 }, /* +a (red) axis */ { -5, -100 - 10, 0-GCENT, 10, "-b*", 0, 0, 1 }, /* -b (blue) axis */ { -100 - 15, -3, 0-GCENT, 10, "-a*", 0, 0, 1 }, /* -a (green) axis */ { -5, 100 + 5, 0-GCENT, 10, "+b*", 1, 1, 0 }, /* +b (yellow) axis */ }; fprintf(wrl," # Lab axes as boxes:\n"); for (n = 0; n < 5; n++) { fprintf(wrl," Transform { translation %f %f %f\n", axes[n].x, axes[n].y, axes[n].z); fprintf(wrl," children [\n"); fprintf(wrl," Shape{\n"); fprintf(wrl," geometry Box { size %f %f %f }\n", axes[n].wx, axes[n].wy, axes[n].wz); fprintf(wrl," appearance Appearance { material Material "); fprintf(wrl,"{ diffuseColor %f %f %f} }\n", axes[n].r, axes[n].g, axes[n].b); fprintf(wrl," }\n"); fprintf(wrl," ]\n"); fprintf(wrl," }\n"); } fprintf(wrl," # Axes identification:\n"); for (n = 0; n < 6; n++) { fprintf(wrl," Transform { translation %f %f %f\n", labels[n].x, labels[n].y, labels[n].z); fprintf(wrl," children [\n"); fprintf(wrl," Shape{\n"); fprintf(wrl," geometry Text { string [\"%s\"]\n",labels[n].string); fprintf(wrl," fontStyle FontStyle { family \"SANS\" style \"BOLD\" size %f }\n", labels[n].size); fprintf(wrl," }\n"); fprintf(wrl," appearance Appearance { material Material "); fprintf(wrl,"{ diffuseColor %f %f %f} }\n", labels[n].r, labels[n].g, labels[n].b); fprintf(wrl," }\n"); fprintf(wrl," ]\n"); fprintf(wrl," }\n"); } } /* Read each input in turn */ for (n = 0; n < ng; n++) { int i; cgats *pp; int nverts; int ntris; int Lf, af, bf; /* Fields holding L, a & b data */ int v0f, v1f, v2f; /* Fields holding verticies 0, 1 & 2 */ pp = new_cgats(); /* Create a CGATS structure */ /* Setup to cope with a gamut file */ pp->add_other(pp, "GAMUT"); if (pp->read_name(pp, gds[n].in_name)) error("Input file '%s' error : %s",gds[n].in_name, pp->err); if (pp->t[0].tt != tt_other || pp->t[0].oi != 0) error("Input file isn't a GAMUT format file"); if (pp->ntables != 2) error("Input file doesn't contain exactly two tables"); if ((nverts = pp->t[0].nsets) <= 0) error("No verticies"); if ((ntris = pp->t[1].nsets) <= 0) error("No triangles"); if ((Lf = pp->find_field(pp, 0, "LAB_L")) < 0) error("Input file doesn't contain field LAB_L"); if (pp->t[0].ftype[Lf] != r_t) error("Field LAB_L is wrong type"); if ((af = pp->find_field(pp, 0, "LAB_A")) < 0) error("Input file doesn't contain field LAB_A"); if (pp->t[0].ftype[af] != r_t) error("Field LAB_A is wrong type"); if ((bf = pp->find_field(pp, 0, "LAB_B")) < 0) error("Input file doesn't contain field LAB_B"); if (pp->t[0].ftype[bf] != r_t) error("Field LAB_B is wrong type"); /* Write the vertexes out */ fprintf(wrl,"\n"); fprintf(wrl," Transform {\n"); fprintf(wrl," translation 0 0 0\n"); fprintf(wrl," children [\n"); fprintf(wrl," Shape { \n"); if (gds[n].in_rep == gam_wire) { fprintf(wrl," geometry IndexedLineSet {\n"); } else { fprintf(wrl," geometry IndexedFaceSet {\n"); fprintf(wrl," ccw FALSE\n"); fprintf(wrl," convex TRUE\n"); } fprintf(wrl,"\n"); fprintf(wrl," coord Coordinate { \n"); fprintf(wrl," point [ # Verticy coordinates\n"); /* Spit out the point values, in order. */ /* Note that a->x, b->y, L->z */ for (i = 0; i < nverts; i++) { double L, a, b; L = *((double *)pp->t[0].fdata[i][Lf]); a = *((double *)pp->t[0].fdata[i][af]); b = *((double *)pp->t[0].fdata[i][bf]); fprintf(wrl," %f %f %f,\n",a, b, L - GCENT); } fprintf(wrl," ]\n"); fprintf(wrl," }\n"); fprintf(wrl,"\n"); /* Write the triangles/wires out */ if ((v0f = pp->find_field(pp, 1, "VERTEX_0")) < 0) error("Input file doesn't contain field VERTEX_0"); if (pp->t[1].ftype[v0f] != i_t) error("Field VERTEX_0 is wrong type"); if ((v1f = pp->find_field(pp, 1, "VERTEX_1")) < 0) error("Input file doesn't contain field VERTEX_1"); if (pp->t[1].ftype[v1f] != i_t) error("Field VERTEX_1 is wrong type"); if ((v2f = pp->find_field(pp, 1, "VERTEX_2")) < 0) error("Input file doesn't contain field VERTEX_2"); if (pp->t[1].ftype[v2f] != i_t) error("Field VERTEX_2 is wrong type"); fprintf(wrl," coordIndex [ # Indexes of poligon Verticies \n"); for (i = 0; i < ntris; i++) { int v0, v1, v2; v0 = *((int *)pp->t[1].fdata[i][v0f]); v1 = *((int *)pp->t[1].fdata[i][v1f]); v2 = *((int *)pp->t[1].fdata[i][v2f]); #ifdef HALF_HACK if (*((double *)pp->t[0].fdata[v0][Lf]) < HALF_HACK || *((double *)pp->t[0].fdata[v1][Lf]) < HALF_HACK || *((double *)pp->t[0].fdata[v2][Lf]) < HALF_HACK) continue; #endif /* HALF_HACK */ if (gds[n].in_rep == gam_wire) { if (v0 < v1) /* Only output 1 wire of two on an edge */ fprintf(wrl," %d, %d, -1\n", v0, v1); if (v1 < v2) fprintf(wrl," %d, %d, -1\n", v1, v2); if (v2 < v0) fprintf(wrl," %d, %d, -1\n", v2, v0); } else { fprintf(wrl," %d, %d, %d, -1\n", v0, v1, v2); } } fprintf(wrl," ]\n"); fprintf(wrl,"\n"); /* Write the colors out */ if (gds[n].in_colors == gam_natural) { fprintf(wrl," colorPerVertex TRUE\n"); fprintf(wrl," color Color {\n"); fprintf(wrl," color [ # RGB colors of each vertex\n"); for (i = 0; i < nverts; i++) { double rgb[3], Lab[3]; Lab[0] = *((double *)pp->t[0].fdata[i][Lf]); Lab[1] = *((double *)pp->t[0].fdata[i][af]); Lab[2] = *((double *)pp->t[0].fdata[i][bf]); gamut_Lab2RGB(rgb, Lab); fprintf(wrl," %f %f %f,\n", rgb[0], rgb[1], rgb[2]); } fprintf(wrl," ] \n"); fprintf(wrl," }\n"); } fprintf(wrl," }\n"); fprintf(wrl," appearance Appearance { \n"); fprintf(wrl," material Material {\n"); if (gds[n].in_trans > 0.0) { fprintf(wrl," transparency %f\n", gds[n].in_trans); } fprintf(wrl," ambientIntensity 0.3\n"); fprintf(wrl," shininess 0.5\n"); if (gds[n].in_colors != gam_natural) { fprintf(wrl," emissiveColor %f %f %f\n", color_rgb[gds[n].in_colors].r, color_rgb[gds[n].in_colors].g, color_rgb[gds[n].in_colors].b); } fprintf(wrl," }\n"); fprintf(wrl," }\n"); fprintf(wrl," } # end Shape\n"); fprintf(wrl," ] # end children\n"); fprintf(wrl," } # end Transform\n"); fprintf(wrl,"\n"); /* See if there are cusp values */ if (docusps) { int kk; double rgb[3], Lab[3]; char buf1[50]; char *cnames[6] = { "RED", "YELLOW", "GREEN", "CYAN", "BLUE", "MAGENTA" }; for (i = 0; i < 6; i++) { sprintf(buf1,"CUSP_%s", cnames[i]); if ((kk = pp->find_kword(pp, 0, buf1)) < 0) break; if (sscanf(pp->t[0].kdata[kk], "%lf %lf %lf", &Lab[0], &Lab[1], &Lab[2]) != 3) { break; } gamut_Lab2RGB(rgb, Lab); fprintf(wrl,"\n"); fprintf(wrl," Transform {\n"); fprintf(wrl," translation %f %f %f\n",Lab[1], Lab[2], Lab[0]-GCENT); fprintf(wrl," children [\n"); fprintf(wrl," Shape { \n"); fprintf(wrl," geometry Sphere { radius 2.0 }\n"); fprintf(wrl," appearance Appearance { material Material {\n"); if (gds[n].in_trans > 0.0) fprintf(wrl," transparency %f\n", gds[n].in_trans); if (gds[n].in_colors != gam_natural) fprintf(wrl," diffuseColor %f %f %f\n", color_rgb[gds[n].in_colors].r, color_rgb[gds[n].in_colors].g, color_rgb[gds[n].in_colors].b); else fprintf(wrl," diffuseColor %f %f %f\n", rgb[0], rgb[1], rgb[2]); fprintf(wrl," }\n"); fprintf(wrl," }\n"); fprintf(wrl," }\n"); fprintf(wrl," ]\n"); fprintf(wrl," }\n"); } fprintf(wrl,"\n"); } pp->del(pp); /* Clean up */ } /* Write the trailer */ fprintf(wrl," ] # end of children for world\n"); fprintf(wrl,"}\n"); /* Close the file */ fclose(wrl); if (isect && ng >= 2) { gamut *s, *s1, *s2; double v1, v2, vi; if ((s = new_gamut(0.0, 0, 0)) == NULL) error("Creating gamut object failed"); if ((s1 = new_gamut(0.0, 0, 0)) == NULL) error("Creating gamut object failed"); if ((s2 = new_gamut(0.0, 0, 0)) == NULL) error("Creating gamut object failed"); if (s1->read_gam(s1, gds[0].in_name)) error("Input file '%s' read failed",gds[n].in_name[0]); if (s2->read_gam(s2, gds[1].in_name)) error("Input file '%s' read failed",gds[n].in_name[1]); v1 = s1->volume(s1); v2 = s2->volume(s2); if (s->intersect(s, s1, s2)) error("Gamuts are not compatible! (Colorspace, gamut center ?)"); vi = s->volume(s); if (iout_name[0] != '\000') { if (s->write_gam(s, iout_name)) error("Writing intersection gamut to '%s' failed",iout_name); } printf("Intersecting volume = %.1f cubic units\n",vi); printf("'%s' volume = %.1f cubic units, intersect = %.2f%%\n",gds[0].in_name,v1,100.0 * vi/v1); printf("'%s' volume = %.1f cubic units, intersect = %.2f%%\n",gds[1].in_name,v2,100.0 * vi/v2); s1->del(s1); s2->del(s2); } if (ng > 0) free(gds); return 0; }