Files
2026-08-20 20:28:40 +01:00

256 lines
6.0 KiB
C

/*
* surftest
*
* Do a torture test of the gamut surfacing algorithm in gamut.
*
* Author: Graeme W. Gill
* Date: 11/11/2006
* Version: 1.00
*
* Copyright 2000, 2006 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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <string.h>
#include <math.h>
#include "copyright.h"
#include "aconfig.h"
#include "numlib.h"
#include "icc.h"
#include "cgats.h"
#include "gamut.h"
#define DEF_POINTS 5
#define DEF_TPOINTS 50
#define DEF_HEIGHT 5.0
void usage(char *diag) {
fprintf(stderr,"Do gamut surface torture test, Version %s\n",ARGYLL_VERSION_STR);
fprintf(stderr,"Author: Graeme W. Gill, licensed under the AGPL Version 3\n");
fprintf(stderr,"usage: surftest [options] npoints\n");
if (diag != NULL)
fprintf(stderr,"Diagnostic: %s\n",diag);
fprintf(stderr," -v Verbose\n");
fprintf(stderr," -r Random points\n");
fprintf(stderr," -n Don't add VRML axes or white/black point\n");
fprintf(stderr," -h height Height above sqhere (default %f)\n",DEF_HEIGHT);
fprintf(stderr," -f Do segemented maxima filtering (default is not)\n");
fprintf(stderr," -t ntpoints Number of test points (default %d)\n",DEF_TPOINTS);
fprintf(stderr," npoints Number of random points, default %d^3\n",DEF_POINTS);
fprintf(stderr," Outputs surftest.wrl");
fprintf(stderr,"\n");
exit(1);
}
int
main(int argc, char *argv[]) {
int fa,nfa; /* argument we're looking at */
static char out_name[MAXNAMEL+1];
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;
}