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