From 22f703cab05b7cd368f4de9e03991b7664dc5022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 1 Sep 2014 13:56:46 +0200 Subject: Initial import of argyll version 1.5.1-8 --- gamut/viewgam.c | 700 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 700 insertions(+) create mode 100644 gamut/viewgam.c (limited to 'gamut/viewgam.c') diff --git a/gamut/viewgam.c b/gamut/viewgam.c new file mode 100644 index 0000000..0b58269 --- /dev/null +++ b/gamut/viewgam.c @@ -0,0 +1,700 @@ + +/* + * viewgam + * + * Gamut support routines. + * + * Author: Graeme W. Gill + * Date: 4/10/00 + * Version: 1.00 + * + * Copyright 2000 Graeme W. Gill + * All rights reserved. + * + * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :- + * see the License.txt file for licencing details. + */ + +#include +#include +#include +#include +#include +#include +#include "copyright.h" +#include "aconfig.h" +#include "numlib.h" +#include "gamut.h" +#include "cgats.h" + +/* + This program reads one or more CGATS format triangular gamut + surface descriptions, and combines them into a VRML file, + so that the gamuts can be visually compared. + + */ + +/* TTBD: + * + */ + +#undef DEBUG + +#undef HALF_HACK /* 27.0 */ + +void usage(char *diag, ...) { + fprintf(stderr,"View gamuts Version %s\n",ARGYLL_VERSION_STR); + fprintf(stderr,"Author: Graeme W. Gill, licensed under the AGPL Version 3\n"); + if (diag != NULL) { + va_list args; + fprintf(stderr,"Diagnostic: "); + va_start(args, diag); + vfprintf(stderr, diag, args); + va_end(args); + fprintf(stderr,"\n"); + } + fprintf(stderr,"usage: viewgam { [-c color] [-t trans] [-w|s] infile.gam } ... outfile.wrl\n"); + fprintf(stderr," -c color Color to make gamut, r = red, g = green, b = blue\n"); + fprintf(stderr," c = cyan, m = magenta, y = yellow, e = grey, w = white\n"); + fprintf(stderr," n = natural color\n"); + fprintf(stderr," -t trans Set transparency from 0.0 (opaque) to 1.0 (invisible)\n"); + fprintf(stderr," -w Show as a wireframe\n"); + fprintf(stderr," -s Show as a solid surace\n"); + fprintf(stderr," infile.gam Name of .gam file\n"); + fprintf(stderr," Repeat above for each input file\n\n"); + fprintf(stderr," -n Don't add Lab axes\n"); + fprintf(stderr," -k Add markers for prim. & sec. \"cusp\" points\n"); + fprintf(stderr," -i Compute and print intersecting volume of first 2 gamuts\n"); + fprintf(stderr," -I isect.gam Same as -i, but save intersection gamut to isect.gam\n"); + fprintf(stderr," outfile.wrl Name of output .wrl file\n"); + fprintf(stderr,"\n"); + exit(1); +} + +#define GCENT 50.0 /* Center of object view */ + +typedef enum { + gam_red = 0, + gam_green = 1, + gam_blue = 2, + gam_cyan = 3, + gam_magenta = 4, + gam_yellow = 5, + gam_grey = 6, + gam_white = 7, + gam_natural = 8 +} gam_colors; + +struct { + double r, g, b; +} color_rgb[8] = { + { 1, 0, 0 }, /* gam_red */ + { 0, 1, 0 }, /* gam_green */ + { 0, 0, 1 }, /* gam_blue */ + { 0, 1, 1 }, /* gam_cyan */ + { 1, 0, 1 }, /* gam_magenta */ + { 1, 1, 0 }, /* gam_yellow */ + { .1, .1, .1 }, /* gam_grey */ + { .7, .7, .7 } /* gam_white */ +}; + +typedef enum { + gam_solid = 0, + gam_wire = 1, + gam_points = 2 +} gam_reps; + +struct _gamdisp { + char in_name[MAXNAMEL+1]; + gam_colors in_colors; /* Color enum for each input */ + double in_trans; /* Transparency for each input */ + gam_reps in_rep; /* Representation enum for each input */ +}; typedef struct _gamdisp gamdisp; + + +/* Set a default for a given gamut */ +static void set_default(gamdisp *gds, int n) { + gds[n].in_name[0] = '\000'; + switch(n) { + case 0: + gds[n].in_colors = gam_natural; + gds[n].in_rep = gam_solid; + gds[n].in_trans = 0.0; + break; + case 1: + gds[n].in_colors = gam_white; + gds[n].in_rep = gam_wire; + gds[n].in_trans = 0.0; + break; + case 2: + gds[n].in_colors = gam_red; + gds[n].in_rep = gam_wire; + gds[n].in_trans = 0.0; + break; + case 3: + gds[n].in_colors = gam_cyan; + gds[n].in_rep = gam_wire; + gds[n].in_trans = 0.0; + break; + case 4: + gds[n].in_colors = gam_yellow; + gds[n].in_rep = gam_wire; + gds[n].in_trans = 0.2; + break; + case 5: + gds[n].in_colors = gam_green; + gds[n].in_rep = gam_wire; + gds[n].in_trans = 0.3; + break; + case 6: + gds[n].in_colors = gam_blue; + gds[n].in_rep = gam_wire; + gds[n].in_trans = 0.4; + break; + case 7: + gds[n].in_colors = gam_magenta; + gds[n].in_rep = gam_wire; + gds[n].in_trans = 0.5; + break; + default: + gds[n].in_colors = n % 6; + gds[n].in_rep = gam_wire; + gds[n].in_trans = 0.6; + break; + } +} + +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; +} + +#ifdef NEVER +/* Basic printf type error() and warning() routines */ + +void +error(char *fmt, ...) +{ + va_list args; + + fprintf(stderr,"icclu: Error - "); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); + exit (-1); +} + +void +warning(char *fmt, ...) +{ + va_list args; + + fprintf(stderr,"icclu: Warning - "); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); +} + +#endif /* NEVER */ -- cgit v1.2.3