diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/alphix.c | 16 | ||||
-rw-r--r-- | target/alphix.h | 6 | ||||
-rw-r--r-- | target/ofps.c | 109 | ||||
-rw-r--r-- | target/ofps.h | 4 | ||||
-rw-r--r-- | target/targen.c | 31 |
5 files changed, 142 insertions, 24 deletions
diff --git a/target/alphix.c b/target/alphix.c index 68dfd48..6e5fc85 100644 --- a/target/alphix.c +++ b/target/alphix.c @@ -1,8 +1,10 @@ /* - * Argyll Color Correction System - * * Alphabetic index class. + */ + +/* + * Argyll Color Correction System * * Author: Graeme W. Gill * Date: 22/8/2005 @@ -63,6 +65,10 @@ static int fromanat(alphix *p, char *ax) { int cl; int i, k, rv = 0; + cl = strlen(ax); + if (cl > p->nd) /* String is too long to be our index */ + return -1; + if (p->nd > 10) { if ((tb = malloc((p->nd+1) * sizeof(char))) == NULL) return -1; /* Malloc error */ @@ -70,7 +76,6 @@ static int fromanat(alphix *p, char *ax) { tb = _tb; /* Pack the string out to the right number of digits with spaces. */ - cl = strlen(ax); for (v = tb; cl < p->nd; v++, cl++) *v = ' '; strcpy(v, ax); @@ -110,7 +115,7 @@ static char *find_start(alphix *p, char *ax) { if (*v == p->ds[i].seq[k]) break; /* Found */ } - if (k >= p->ds[i].n) /* Not found */ + if (k >= p->ds[i].n) /* Not found, so we are at the start */ break; } return v+1; @@ -444,6 +449,9 @@ int patch_location_order( /* We assume that the sequences are distinguishable ... */ v = find_start(rh, ax); + if (*v == '\000') /* Nothing looks like a alphix */ + return -1; + ri = rh->nix(rh, v); *v = '\000'; li = lh->nix(lh, ax); diff --git a/target/alphix.h b/target/alphix.h index 091c191..aad5b9f 100644 --- a/target/alphix.h +++ b/target/alphix.h @@ -2,9 +2,11 @@ #ifndef ALPHIX_H /* - * Argyll Color Correction System - * * Alphabetic indexing class + */ + +/* + * Argyll Color Correction System * * Author: Graeme W. Gill * Date: 22/8/2005 diff --git a/target/ofps.c b/target/ofps.c index dfcee2e..5c2219c 100644 --- a/target/ofps.c +++ b/target/ofps.c @@ -66,7 +66,7 @@ dimension points are aware of the lower dimension ones. In this way the distribution of points on lower dimensional surfaces is well spread, while - the higher dimension points take thier positions into account. + the higher dimension points take their positions into account. */ /* @@ -107,7 +107,7 @@ In general there are many sub-dimensions views, not all of which would probably be regarded as important. - To measure spread, independent voronoi tesselations of + To measure spread, independent voronoi tessellations of these sub dimensions would be neededi, and they could be used partly driver optimization (??). @@ -717,6 +717,85 @@ default_ofps_to_percept(void *od, double *p, double *d) { } } +/* Filtered perceptual lookup, used for setting up rspl cache values. */ +/* Input is device values, output L*a*b* like perceptual values. */ +static void +filtered_ofps_to_percept(void *ss, double *p, double *d) { + ofps *s = (ofps *)ss; + double rad = 1.0/s->pcache_res; /* Filter radius = grid res. */ + int fres = 2; /* +/- 2 around center */ + int e, f; + double pw; /* Accumulated Weight */ + double off[MXPD]; /* Offset value */ + double out[MXPD]; /* Offset output value */ + double roff[MXPD]; /* Reflection offset value (for clip case) */ + double rout[MXPD]; /* Reflected offset output value */ + DCOUNT(co, MXPD, s->di, -fres, -fres, fres+1); + + if (rad > 0.05) /* Don't loose too much detail */ + rad = 0.05; + +//printf("filtered called with %s\n",debPdv(s->di,d)); + + for (f = 0; f < s->di; f++) + p[f] = 0.0; /* Accumulated value */ + pw = 0.0; + + DC_INIT(co); + + while (!DC_DONE(co)) { + double tw = 1.0; + int clip = 0; + +//printf(" sub samp at %s\n", debPiv(s->di, co)); + for (e = 0; e < s->di; e++) { + double w, ov; + ov = ((double)co[e])/(fres+1) * rad; + roff[e] = off[e] = d[e] + ov; + if (off[e] < 0.0) { + off[e] = 0.0; + roff[e] = 0.0 - ov; + clip = 1; + } + else if (off[e] > 1.0) { + off[e] = 1.0; + roff[e] = 1.0 - ov; + clip = 1; + } +//printf(" w[%d] = %f\n",e,(fres+1 - fabs((double)co[e]))/(fres+1)); + w = (fres+1 - fabs((double)co[e]))/(fres+1); + tw *= w; + } +//printf(" off %s wt %f\n", debPdv(s->di,off),tw); + s->percept(s->od, out, off); + + /* For clipped case, use reflected value from reflected location */ + if (clip) { + s->percept(s->od, rout, roff); +//printf(" roff %s\n", debPdv(s->di, roff)); +//printf(" out %s\n", debPdv(s->di, out)); +//printf(" rout %s\n", debPdv(s->di, rout)); + + for (f = 0; f < s->di; f++) + out[f] = 2 * out[f] - rout[f]; + +//printf(" eout %s\n", debPdv(s->di, out)); + } + for (f = 0; f < s->di; f++) + p[f] += tw * out[f]; + pw += tw; + + DC_INC(co); + } + for (f = 0; f < s->di; f++) + p[f] /= pw; + +//s->percept(s->od, out, d); +//printf(" u out %s\n", debPdv(s->di, out)); +//printf(" f out %s\n", debPdv(s->di, p)); +//printf("\n"); +} + /* Cached perceptual lookup */ static void ofps_cache_percept(void *od, double *p, double *d) { @@ -4968,27 +5047,41 @@ ofps_init_pcache(ofps *s) { if (gr > TNPAGRIDMAXRES) gr = TNPAGRIDMAXRES; +#ifndef DEBUG if (s->verb) - printf("Perceptual cache resolution = %d\n",gr); - -#ifdef DEBUG - printf("Perceptual cache resolution = %d\n",gr); #endif + { + printf("Perceptual cache resolution = %d\n",gr); + printf("Seeding cache..."); fflush(stdout); + } /* Create a rspl to cache the perceptual lookup */ - if ((s->pcache = new_rspl(RSPL_NOFLAGS, s->di, s->di)) == NULL) error("new_rspl failed"); for (e = 0; e < di; e++) gres[e] = gr; + s->pcache_res = gr; - s->pcache->set_rspl(s->pcache, RSPL_SET_APXLS, s->od, s->percept, NULL, NULL, gres, NULL, NULL); +// s->pcache->set_rspl(s->pcache, RSPL_SET_APXLS, s->od, s->percept, NULL, NULL, gres, NULL, NULL); + + /* Filtering seems to make this more robust for some profiles, less for others. */ + if (s->percept != default_ofps_to_percept) + s->pcache->set_rspl(s->pcache, RSPL_NOFLAGS, s, filtered_ofps_to_percept, + NULL, NULL, gres, NULL, NULL); + else + s->pcache->set_rspl(s->pcache, RSPL_NOFLAGS, s->od, s->percept, + NULL, NULL, gres, NULL, NULL); /* Hmm. Should we store the underlying ->percept & ->od somewhere before we overwrite it ? */ s->percept = ofps_cache_percept; s->od = s->pcache; +#ifndef DEBUG + if (s->verb) +#endif + printf("done\n"); + } /* --------------------------------------------------- */ diff --git a/target/ofps.h b/target/ofps.h index e2b1d55..05ca121 100644 --- a/target/ofps.h +++ b/target/ofps.h @@ -276,10 +276,12 @@ struct _ofps { unsigned int lwmask; /* Last word mask */ /* Perceptual function handed in. All device values must have been */ - /* clipped before calling this, otherwise use It is assumed that */ + /* clipped before calling this. (On running, is replaced with rspl */ + /* cached version) */ void (*percept)(void *od, double *out, double *in); void *od; /* Opaque data for perceptual point */ + int pcache_res; /* Grid resolution of pcache */ rspl *pcache; /* cache of perceptual lookup */ /* Other info */ diff --git a/target/targen.c b/target/targen.c index a29ef63..74bbe96 100644 --- a/target/targen.c +++ b/target/targen.c @@ -43,8 +43,10 @@ /* NOTE: - The device model is assumed to not take xpow into account, - hence the expected values don't reflect its effect. + xpow is applied over the top of the normal or supplied + device model, so it effectively becomes a modification + of the device model. + The general filter is applied prior to the xpow being applied. Many of the test patch types do take it into account when computing the ink limit. @@ -101,6 +103,10 @@ any possible angle, none of the test data points should appear to line up. The Argyll target generator seems to acheive this goal. + A final problem withe regular grids is that they can lead to + Runge's phenomenon, depending on the nature of the interpolation + algorithm used. + */ #undef DEBUG @@ -677,7 +683,7 @@ double xpow /* Extra device power, default = none */ if (xpow < 0.0) xpow = XPOW_DEFAULT; - s->ixpow = xpow; + s->ixpow = 1.0/xpow; /* See if we have a profile */ if (profName != NULL @@ -877,6 +883,7 @@ usage(int level, char *diag, ...) { fprintf(stderr," -V demphasis Degree of dark region patch concentration 1.0-4.0 (default %.2f = none)\n",DEMPH_DEFAULT); fprintf(stderr," -F L,a,b,rad Filter out samples outside Lab sphere.\n"); fprintf(stderr," -O Don't re-order display RGB patches for minimum delay\n"); + fprintf(stderr," -U Don't filter out duplicate patches\n"); #ifdef VRML_DIAG fprintf(stderr," -w Dump diagnostic outfilel%s file (Lab locations)\n",vrml_ext()); fprintf(stderr," -W Dump diagnostic outfiled%s file (Device locations)\n",vrml_ext()); @@ -941,8 +948,9 @@ int main(int argc, char *argv[]) { double uilimit = -1.0; /* Underlying (pre-calibration, scale 1.0) ink limit */ double nemph = NEMPH_DEFAULT; double demph = DEMPH_DEFAULT; + int dontdedupe = 0; /* Don't filter duplicate samples */ int dontreorder = 0; /* Don't re-order RGB display patches for min delay */ - int filter = 0; /* Filter values */ + int filter = 0; /* Filter values outside given sphere */ double filt[4] = { 50,0,0,0 }; static char fname[MAXNAMEL+1] = { 0 }; /* Output file base name */ static char pname[MAXNAMEL+1] = { 0 }; /* Device profile name */ @@ -1231,6 +1239,11 @@ int main(int argc, char *argv[]) { dontreorder = 1; } + /* Don't filter out redundant patches */ + else if (argv[fa][1] == 'U') { + dontdedupe = 1; + } + #ifdef VRML_DIAG else if (argv[fa][1] == 'w') /* Lab */ dumpvrml |= 1; @@ -1612,7 +1625,7 @@ int main(int argc, char *argv[]) { val[e] = icx_powlike(val[e], xpow * demph); /* See if it is already in the fixed list */ - if (fxlist != NULL) { + if (!dontdedupe && fxlist != NULL) { int k; for (k = 0; k < fxno; k++) { for (e = 0; e < di; e++) { @@ -1717,7 +1730,7 @@ int main(int argc, char *argv[]) { addp = 0; /* See if it is already in the fixed list */ - if (fxlist != NULL) { + if (!dontdedupe && fxlist != NULL) { int k; for (k = 0; k < fxno; k++) { for (e = 0; e < di; e++) { @@ -1802,7 +1815,7 @@ int main(int argc, char *argv[]) { addp = 0; /* Don't add patches over ink limit */ /* See if it is already in the fixed list */ - if (addp && fxlist != NULL) { + if (addp && !dontdedupe && fxlist != NULL) { int k; for (k = 0; k < fxno; k++) { for (e = 0; e < di; e++) { @@ -1891,7 +1904,7 @@ int main(int argc, char *argv[]) { addp = 1; /* Default add the point */ /* See if it is already in the fixed list */ - if (fxlist != NULL) { + if (!dontdedupe && fxlist != NULL) { int k; for (k = 0; k < fxno; k++) { for (e = 0; e < di; e++) { @@ -1998,7 +2011,7 @@ int main(int argc, char *argv[]) { addp = 0; /* Don't add patches over ink limit */ /* See if it is already in the fixed list */ - if (addp && fxlist != NULL) { + if (addp && !dontdedupe && fxlist != NULL) { int k; for (k = 0; k < fxno; k++) { for (e = 0; e < di; e++) { |