1 
2 /************************************************/
3 /* Benchmark RSPL reverse lookup                */
4 /************************************************/
5 
6 /* Author: Graeme Gill
7  * Date:   31/10/96
8  * Derived from tnd.c
9  * Copyright 1999 - 2000 Graeme W. Gill
10  *
11  * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
12  * see the License.txt file for licencing details.
13  */
14 
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <fcntl.h>
19 #include <math.h>
20 #include <time.h>
21 #include "copyright.h"
22 #include "aconfig.h"
23 #include "rspl.h"
24 #include "numlib.h"
25 //#include "ui.h"
26 
27 #undef DOLIMIT			/* Define to have ink limit */
28 #define LIMITVAL 2.5	/* Total ink limit sum */
29 #undef DOCHECK
30 #define TESTNN			/* Test Nearest Clipping */
31 
32 #define SHOW_OUTPUT		/* Define for printf on each conversion */
33 
34 /* 11, 19 give about 60 seconds */
35 #define GRES 17			/* Default grid resolution */
36 #define RRES 43			/* Default reverse test resolution */
37 #define DI 4			/* Dimensions in */
38 #define FDI 3			/* Function (out) Dimensions */
39 #define NIP 10			/* Number of solutions allowed */
40 
41 #define flimit(vv) ((vv) < 0.0 ? 0.0 : ((vv) > 1.0 ? 1.0 : (vv)))
42 #define fmin(a,b) ((a) < (b) ? (a) : (b))
43 #define fmin3(a,b,c)  (fmin((a), fmin((b),(c))))
44 #define fmax(a,b) ((a) > (b) ? (a) : (b))
45 #define fmax3(a,b,c)  (fmax((a), fmax((b),(c))))
46 
47 /* Fwd function approximated by rspl */
48 /* Dummy cmyk->rgb conversion. This simulates our device */
func(void * cbctx,double * out,double * in)49 void func(
50 void *cbctx,
51 double *out,
52 double *in) {
53 	double kk;
54 	double ci = in[0];
55 	double mi = in[1];
56 	double yi = in[2];
57 	double ki = in[3];
58 	double r,g,b;
59 
60 	ci += ki;			/* Add black back in */
61 	mi += ki;
62 	yi += ki;
63 	kk = fmax3(ci,mi,yi);
64 	if (kk > 1.0) {
65 		ci /= kk;
66 		mi /= kk;
67 		yi /= kk;
68 	}
69 	r = 1.0 - ci;
70 	g = 1.0 - mi;
71 	b = 1.0 - yi;
72 	out[0] = flimit(r);
73 	out[1] = flimit(g);
74 	out[2] = flimit(b);
75 }
76 
77 /* Simplex ink limit function */
limitf(void * lcntx,float * in)78 double limitf(
79 void *lcntx,
80 float *in
81 ) {
82 	int i;
83 	double ov;
84 
85 	for (ov = 0.0, i = 0; i < DI; i++) {
86 		ov += in[i];
87 	}
88 	return ov;
89 }
90 
91 
usage(void)92 void usage(void) {
93 	fprintf(stderr,"Benchmark rspl reverse, Version %s\n",ARGYLL_VERSION_STR);
94 	fprintf(stderr,"usage: revbench [-f fwdres] [-r revres] [-v level] iccin iccout\n");
95 	fprintf(stderr," -v            Verbose\n");
96 	fprintf(stderr," -f res        Set forward grid res\n");
97 	fprintf(stderr," -r res        Set reverse test res\n");
98 	exit(1);
99 }
100 
101 int
main(int argc,char * argv[])102 main(int argc, char *argv[]) {
103 	int fa,nfa;				/* argument we're looking at */
104 	int clutres = GRES;
105 	int rres = RRES;
106 	int verb = 0;
107 	int gres[MXDI];
108 	int e;
109 
110 	clock_t stime,ttime;
111 	rspl *rss;	/* Multi-resolution regularized spline structure */
112 
113 	error_program = argv[0];
114 
115 	/* Process the arguments */
116 	for(fa = 1;fa < argc;fa++) {
117 		nfa = fa;					/* skip to nfa if next argument is used */
118 		if (argv[fa][0] == '-')	{	/* Look for any flags */
119 			char *na = NULL;		/* next argument after flag, null if none */
120 
121 			if (argv[fa][2] != '\000')
122 				na = &argv[fa][2];		/* next is directly after flag */
123 			else {
124 				if ((fa+1) < argc) {
125 					if (argv[fa+1][0] != '-') {
126 						nfa = fa + 1;
127 						na = argv[nfa];		/* next is seperate non-flag argument */
128 					}
129 				}
130 			}
131 
132 			if (argv[fa][1] == '?')
133 				usage();
134 
135 			/* Verbosity */
136 			else if (argv[fa][1] == 'v' || argv[fa][1] == 'V') {
137 				verb = 1;
138 			}
139 			else if (argv[fa][1] == 'f' || argv[fa][1] == 'F') {
140 				fa = nfa;
141 				if (na == NULL) usage();
142 				clutres = atoi(na);
143 			}
144 			else if (argv[fa][1] == 'r' || argv[fa][1] == 'R') {
145 				fa = nfa;
146 				if (na == NULL) usage();
147 				rres = atoi(na);
148 			}
149 			else
150 				usage();
151 		} else
152 			break;
153 	}
154 
155 	printf("Started benchmark\n");
156 	/* Create the object */
157 	rss =  new_rspl(RSPL_NOFLAGS, DI, FDI);
158 
159 	for (e = 0; e < DI; e++)
160 		gres[e] = clutres;
161 
162 	printf("Rspl allocated\n");
163 	rss->set_rspl(rss, 0, (void *)NULL, func,
164 	               NULL, NULL, gres, NULL, NULL);
165 
166 	printf("Rspl set\n");
167 
168 	/* Start exploring the reverse test grid */
169 	{
170 		int ops = 0;
171 		double secs;
172 		rpsh counter;
173 		unsigned rcount;
174 		int ii[10];
175 		int f, rgres[MXDO];
176 
177 		int flags = 0;		/* rev hint flags */
178 		co tp[NIP];			/* Test point */
179 		double cvec[4];		/* Text clip vector */
180 		int auxm[4];		/* Auxiliary target value valid flag */
181 #ifdef DOCHECK
182 		int j;
183 #endif
184 #ifdef NEVER
185 		double lmin[4], lmax[4];	/* Locus min/max values */
186 #endif
187 
188 #ifdef DOCHECK
189 		char *check;		/* Check that we hit every cell */
190 #endif /* DOCHECK */
191 
192 		/* Set auxiliary target mask */
193 		auxm[0] = 0;
194 		auxm[1] = 0;
195 		auxm[2] = 0;
196 		auxm[3] = 1;
197 
198 #ifdef DOLIMIT
199 		rss->rev_set_limit(rss,
200 			limitf,
201 			NULL,
202 			LIMITVAL	/* limit maximum value */
203 		);
204 #endif /* DOLIMIT */
205 
206 		printf("Forward resolution %d\n",clutres);
207 		printf("Reverse resolution %d\n",rres);
208 
209 #ifdef DOCHECK
210 		if ((check = (char *)calloc(1, rcount)) == NULL)
211 			error("Malloc of check array\n");
212 #endif /* DOCHECK */
213 
214 		for (f = 0; f < FDI; f++)
215 			rgres[f] = rres;
216 
217 		rcount = rpsh_init(&counter, FDI, (unsigned int *)rgres, ii);	/* Initialise counter */
218 
219 		stime = clock();
220 
221 #ifdef TESTNN
222 		flags |= RSPL_NEARCLIP;
223 #endif
224 		/* Itterate though the grid */
225 		for (ops = 0;; ops++) {
226 			int r;
227 			int e;			/* Table index */
228 
229 #ifdef DOCHECK
230 			check[((ii[2] * rres + ii[1]) * rres) + ii[0]] = 1;
231 #endif /* DOCHECK */
232 
233 			for (e = 0; e < FDI; e++) { 	/* Input tables */
234 				tp[0].v[e] = ii[e]/(rres-1.0);		/* Vertex coordinates */
235 			}
236 
237 			if (verb)
238 				printf("Input = %f %f %f\n",tp[0].v[0], tp[0].v[1], tp[0].v[2]);
239 
240 #ifdef NEVER	/* Do locus lookup explicitly ? */
241 			/* Lookup the locus for the auxiliary (Black) chanel */
242 			if ((r = rss->rev_locus(rss,
243 				auxm, 	/* auxm Auxiliary mask flags */
244 				tp,		/* Input and auxiliary values */
245 				lmin,	/* Locus min/max return values */
246 				lmax
247 				)) == 0) {
248 				/* Rev locus failed - means that it will clip ? */
249 				tp[0].p[3] = 0.5;
250 				flags = RSPL_WILLCLIP;	/* Since there was no locus, we expect to clip */
251 			} else {
252 				/* Set the auxiliary target */
253 				tp[0].p[3] = (lmin[3] + lmax[3])/2.0;
254 				flags = RSPL_EXACTAUX;	/* Since we got locus, expect exact auxiliary match */
255 			}
256 #else
257 				tp[0].p[3] = 0.5;
258 				flags = RSPL_AUXLOCUS;	/* Auxiliary target is proportion of locus */
259 #endif	/* NEVER */
260 
261 			/* Clip vector to 0.5 */
262 			cvec[0] = 0.5 - tp[0].v[0];
263 			cvec[1] = 0.5 - tp[0].v[1];
264 			cvec[2] = 0.5 - tp[0].v[2];
265 			cvec[3] = 0.5 - tp[0].v[3];
266 
267 			/* Do reverse interpolation */
268 			if ((r = rss->rev_interp(rss,
269 				flags,	/* Hint flags */
270 				NIP,	/* Number of solutions allowed */
271 				auxm, 	/* auxm Auxiliary mask flags */
272 				cvec, 	/* cvec Clip vector direction & length */
273 				tp)		/* Input and output values */
274 				) == 0) {
275 				error("rev_interp failed\n");
276 			}
277 
278 			r &= RSPL_NOSOLNS;		/* Get number of solutions */
279 
280 			if (verb)
281 				printf("Output 1 of %d: %f, %f, %f, %f%s\n",
282 				  r & RSPL_NOSOLNS, tp[0].p[0], tp[0].p[1], tp[0].p[2], tp[0].p[3],
283 			      (r & RSPL_DIDCLIP) ? " [Clipped]" : "");
284 
285 
286 			if (rpsh_inc(&counter, ii))
287 				break;
288 
289 		}		/* Next grid point */
290 
291 		ttime = clock() - stime;
292 		secs = (double)ttime/CLOCKS_PER_SEC;
293 		printf("Done - %d ops in %f seconds, rate = %f ops/sec\n",ops, secs,ops/secs);
294 #ifdef DOCHECK
295 		for (j = 0; j < rcount; j++) {
296 			if (check[j] != 1) {
297 				printf("~~CHeck error at %d\n",j);
298 			}
299 		}
300 #endif /* DOCHECK */
301 	}
302 
303 	rss->del(rss);
304 	return 0;
305 }
306 
307 
308 
309 
310 
311 
312