summaryrefslogtreecommitdiff
path: root/gamut
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2016-10-02 19:25:17 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2016-10-02 19:25:17 +0200
commitc2ca7be5a751879159f3cb591a64bb9568b79762 (patch)
tree04e38d4f4a2aad4d789bda0a65b7abb80a3439a2 /gamut
parent45c152c326d87478fbf41714b4b8e2f7b57a282b (diff)
parent3db384424bd7398ffbb7a355cab8f15f3add009f (diff)
Updated version 1.9.1+repack from 'upstream/1.9.1+repack'
with Debian dir 98a996367aa69ae41accf9c6d369f600bc94de80
Diffstat (limited to 'gamut')
-rw-r--r--gamut/gammap.c50
-rw-r--r--gamut/gammap.h2
-rw-r--r--gamut/gamut.c131
-rw-r--r--gamut/gamut.h14
-rw-r--r--gamut/maptest.c2
-rw-r--r--gamut/smthtest.c1
6 files changed, 178 insertions, 22 deletions
diff --git a/gamut/gammap.c b/gamut/gammap.c
index e276b99..03b9502 100644
--- a/gamut/gammap.c
+++ b/gamut/gammap.c
@@ -23,8 +23,12 @@
* There is a general expectation (especially in comparing products)
* that the profile colorimetric intent be not strictly minimum delta E,
* but that it correct neutral axis, luminence range and keep hue
- * proportionality. Ideally there should be an intent that matches
+ * proportionality (i.e. clip with constant Hue and Luminance).
+ * Ideally there should be an intent that matches
* this, that can be selected for the colorimetric table (or perhaps be default).
+ * !! Maybe even the normal perceptual gamut mapping should use a !!
+ * !! Hue and Luminance preserving clipping ? Should this be the default !!
+ * !! for all inverse lookups ?? !!
*
* It might be good to offer the black mapping method as an option (icx_BPmap),
* as well as offering different profile (xicc/xlut.c) black point options
@@ -37,7 +41,7 @@
* messing up the guide vector mappings. Even if this is fixed, the
* actual neutral aim point within nearsmooth is Jab 0,0, while
* the mapping in gammap is from the source neutral to the chosen
- * ??????
+ * ?????? (is this fixed to some degree ?)
*/
@@ -519,10 +523,12 @@ static void map_trans(void *cntx, double out[3], double in[3]);
/* Return NULL on error. */
gammap *new_gammap(
int verb, /* Verbose flag */
- gamut *sc_gam, /* Source colorspace gamut */
+ gamut *sc_gam, /* Source colorspace gamut (L gamut if sh_gam != NULL) */
gamut *isi_gam, /* Input source image gamut (NULL if none) */
gamut *d_gam, /* Destination colorspace gamut */
icxGMappingIntent *gmi, /* Gamut mapping specification */
+ gamut *sh_gam, /* If not NULL, then use sc_gam for the luminence */
+ /* mapping, and sh_gam for the hull mapping (i.e. general compression) */
int src_kbp, /* Use K only black point as src gamut black point */
int dst_kbp, /* Use K only black point as dst gamut black point */
int dst_cmymap, /* masks C = 1, M = 2, Y = 4 to force 100% cusp map */
@@ -533,8 +539,8 @@ gammap *new_gammap(
char *diagname /* If non-NULL, write a gamut mapping diagnostic WRL */
) {
gammap *s; /* This */
- gamut *si_gam = NULL; /* Source image gamut (intersected with sc_gam) */
- gamut *scl_gam; /* Source colorspace gamut with rotation and L mapping applied */
+ gamut *si_gam = NULL; /* Source image gamut (intersected with sc_gam), assm. NULL if sh_gam */
+ gamut *scl_gam = NULL; /* Source colorspace gamut with rotation and L mapping applied */
gamut *sil_gam; /* Source image gamut with rotation and L mapping applied */
double s_cs_wp[3]; /* Source colorspace white point */
@@ -1261,18 +1267,28 @@ glumknf = 1.0;
}
#endif
- if ((scl_gam = parttransgamut(s, sc_gam)) == NULL) {
- fprintf(stderr,"gamut map: parttransgamut failed\n");
- if (si_gam != sc_gam)
- si_gam->del(si_gam);
- free(s);
- return NULL;
+ /* If we were provided with a distinct source gamut hull, i.e. because */
+ /* we are doing a general compression/expansion, and sh_gam is an expanded/compressed */
+ /* destination gamut, use it for creating the nearsmth vectors */
+ if (sh_gam != NULL) {
+ scl_gam = sh_gam;
+
+ /* Map the source colorspace gamut through the L mapping */
+ } else {
+ if ((scl_gam = parttransgamut(s, sc_gam)) == NULL) {
+ fprintf(stderr,"gamut map: parttransgamut failed\n");
+ if (si_gam != sc_gam)
+ si_gam->del(si_gam);
+ free(s);
+ return NULL;
+ }
}
if (sc_gam == si_gam)
sil_gam = scl_gam;
else {
+ /* Map the source image gamut through the L mapping */
if ((sil_gam = parttransgamut(s, si_gam)) == NULL) {
fprintf(stderr,"gamut map: parttransgamut failed\n");
if (si_gam != sc_gam)
@@ -1322,7 +1338,8 @@ typedef struct {
s->igrey->del(s->igrey);
if (sil_gam != scl_gam)
sil_gam->del(sil_gam);
- scl_gam->del(scl_gam);
+ if (scl_gam != sh_gam)
+ scl_gam->del(scl_gam);
if (si_gam != sc_gam)
si_gam->del(si_gam);
free(s);
@@ -1493,7 +1510,8 @@ typedef struct {
s->igrey->del(s->igrey);
if (sil_gam != scl_gam)
sil_gam->del(sil_gam);
- scl_gam->del(scl_gam);
+ if (scl_gam != sh_gam)
+ scl_gam->del(scl_gam);
if (si_gam != sc_gam)
si_gam->del(si_gam);
free(s);
@@ -1523,7 +1541,8 @@ typedef struct {
s->igrey->del(s->igrey);
if (sil_gam != scl_gam)
sil_gam->del(sil_gam);
- scl_gam->del(scl_gam);
+ if (scl_gam != sh_gam)
+ scl_gam->del(scl_gam);
if (si_gam != sc_gam)
si_gam->del(si_gam);
free(s);
@@ -2275,7 +2294,8 @@ typedef struct {
if (sil_gam != scl_gam)
sil_gam->del(sil_gam);
- scl_gam->del(scl_gam);
+ if (scl_gam != sh_gam)
+ scl_gam->del(scl_gam);
if (si_gam != sc_gam)
si_gam->del(si_gam);
diff --git a/gamut/gammap.h b/gamut/gammap.h
index 69207a4..247ff65 100644
--- a/gamut/gammap.h
+++ b/gamut/gammap.h
@@ -58,6 +58,8 @@ gammap *new_gammap(
gamut *s_gam, /* Source image gamut (NULL if none) */
gamut *d_gam, /* Destination colorspace gamut */
icxGMappingIntent *gmi, /* Gamut mapping specification */
+ gamut *sh_gam, /* If not NULL, then use sc_gam for the luminence */
+ /* mapping, and sh_gam for the hull mapping (i.e. general compression) */
int src_kbp, /* Use K only black point as src gamut black point */
int dst_kbp, /* Use K only black point as dst gamut black point */
int dst_cmymap, /* masks C = 1, M = 2, Y = 4 to force 100% cusp map */
diff --git a/gamut/gamut.c b/gamut/gamut.c
index 3fc1c97..14b45c7 100644
--- a/gamut/gamut.c
+++ b/gamut/gamut.c
@@ -175,6 +175,7 @@ static int compute_vector_isect(gamut *s, double *p1, double *p2, double *min, d
static int compute_vector_isectns(gamut *s, double *p1, double *p2, gispnt *lp, int ll);
static double log_scale(gamut *s, double ss);
static int intersect(gamut *s, gamut *s1, gamut *s2);
+static int exp_cyl(gamut *s, gamut *s1, double ratio);
static int nexpintersect(gamut *s, gamut *s1, gamut *s2);
static int expdstbysrcmdst(gamut *s, gamut *s1, gamut *s2, gamut *s3,
void (*cvect)(void *cntx, double *p2, double *p1), void *cntx);
@@ -561,7 +562,8 @@ gamut *new_gamut(
double sres, /* Resolution (in rect coord units) of surface triangles */
/* 0.0 = default */
int isJab, /* Flag indicating Jab space */
-int isRast /* Flag indicating Raster rather than colorspace */
+int isRast /* Flag indicating Raster rather than colorspace, */
+ /* so that we only do one pass rather than two of surface fitting. */
) {
gamut *s;
@@ -658,6 +660,7 @@ int isRast /* Flag indicating Raster rather than colorspace */
s->getvert = getvert;
s->volume = volume;
s->intersect = intersect;
+ s->exp_cyl = exp_cyl;
s->nexpintersect = nexpintersect;
s->expdstbysrcmdst = expdstbysrcmdst;
s->radial = radial;
@@ -1206,6 +1209,128 @@ static int intersect(gamut *s, gamut *sa, gamut *sb) {
return 0;
}
+
+/* ------------------------------------ */
+
+/* Initialise this gamut with the source gamut */
+/* expanded cylindrically around the nautral axis by */
+/* the given ratio. */
+/* (We assume that the this gamut is currently empty) */
+static int exp_cyl(gamut *s, gamut *sa, double ratio) {
+ int i, j, k;
+ double bp[3], wp[3];
+
+ if IS_LIST_EMPTY(sa->tris)
+ triangulate(sa);
+
+ s->sres = sa->sres;
+
+ s->isJab = sa->isJab;
+
+ s->isRast = sa->isRast;
+
+ if (s->isRast) {
+ s->logpow = RAST_LOG_POW; /* Wrap the surface more closely */
+ s->no2pass = 1; /* Only do one pass */
+ }
+
+ for (j = 0; j < 3; j++)
+ s->cent[j] = sa->cent[j];
+
+ /* Clear some flags */
+ s->cswbset = 0;
+ s->cswbset = 0;
+ s->dcuspixs = 0;
+
+ /* Copy white & black points */
+ if (sa->cswbset) {
+ for (j = 0; j < 3; j++) {
+ s->cs_wp[j] = sa->cs_wp[j];
+ s->cs_bp[j] = sa->cs_bp[j];
+ s->cs_kp[j] = sa->cs_kp[j];
+ }
+ s->cswbset = sa->cswbset;
+
+ icmCpy3(wp, s->cs_wp);
+ icmCpy3(bp, s->cs_bp);
+
+ } else {
+ wp[0] = 100.0, wp[1] = 0.0, wp[2] = 0.0;
+ bp[0] = 0.0, bp[1] = 0.0, bp[2] = 0.0;
+ }
+
+ /* Don't filter the points (gives a more accurate result) */
+ s->nofilter = 1;
+
+ /* For each vertex */
+ for (i = 0; i < sa->nv; i++) {
+ double pp[3], cp[3];
+ double vv;
+
+ if (!(sa->verts[i]->f & GVERT_TRI))
+ continue;
+
+ icmCpy3(pp, sa->verts[i]->p); /* Point in question */
+
+ /* Parameter along neutral axis black to white */
+ vv = (pp[0] - bp[0])/(wp[0] - bp[0]);
+
+ /* lv is point at same L on neutral axis */
+ cp[0] = pp[0];
+ cp[1] = vv * (wp[1] - bp[1]) + bp[1];
+ cp[2] = vv * (wp[2] - bp[2]) + bp[2];
+
+ /* Convert to vector from neutral axis point */
+ icmSub3(pp, pp, cp);
+
+ /* Scale a,b */
+ pp[1] *= ratio;
+ pp[2] *= ratio;
+
+ /* Convert back to point */
+ icmAdd3(pp, pp, cp);
+
+ expand_gamut(s, pp);
+ }
+
+ /* Copy and expand cusps */
+ if (sa->cu_inited != 0) {
+ /* For each cusp */
+ for (i = 0; i < 6; i++) {
+ double pp[3], cp[3];
+ double vv;
+
+ icmCpy3(pp, sa->cusps[i]);
+
+ /* Parameter along neutral axis black to white */
+ vv = (pp[0] - bp[0])/(wp[0] - bp[0]);
+
+ /* lv is point at same L on neutral axis */
+ cp[0] = pp[0];
+ cp[1] = vv * (wp[1] - bp[1]) + bp[1];
+ cp[2] = vv * (wp[2] - bp[2]) + bp[2];
+
+ /* Convert to vector from neutral axis point */
+ icmSub3(pp, pp, cp);
+
+ /* Scale a,b */
+ pp[1] *= ratio;
+ pp[2] *= ratio;
+
+ /* Convert back to point */
+ icmAdd3(pp, pp, cp);
+
+ icmCpy3(s->cusps[i], pp);
+ }
+ s->cu_inited = sa->cu_inited;
+ }
+
+ s->nofilter = 0;
+
+ return 0;
+}
+
+
/* ------------------------------------ */
/* Initialise this gamut with neutral axis points from sa, */
@@ -4534,8 +4659,10 @@ double *gakp
}
//printf("~1 colorspace white %f %f %f, black %f %f %f, kblack %f %f %f\n", s->cs_wp[0], s->cs_wp[1], s->cs_wp[2], s->cs_bp[0], s->cs_bp[1], s->cs_bp[2], s->cs_kp[0],s->cs_kp[1],s->cs_kp[2]);
- if (gawp != NULL || gabp != NULL) {
+ if (gawp != NULL || gabp != NULL || gakp != NULL) {
//printf("~1 computing gamut white & black\n");
+ if (s->nv == 0)
+ return 1;
compgawb(s); /* make sure we have gamut white/black available */
}
diff --git a/gamut/gamut.h b/gamut/gamut.h
index e70d898..e74f942 100644
--- a/gamut/gamut.h
+++ b/gamut/gamut.h
@@ -249,7 +249,7 @@ struct _gamut {
double xvra; /* Extra vertex ratio - set/used by nssverts() */
int ssnverts; /* total ss verticies - set/used by nssverts() */
int ssvertn; /* Number of verts created for current triangle */
- sobol *ss; /* Sibol ss generator currently being used */
+ sobol *ss; /* Sobol ss generator currently being used */
gtri *nexttri; /* Context for getnexttri() */
@@ -315,14 +315,22 @@ struct _gamut {
/* Initialise this gamut with the intersection of the */
/* the two given gamuts. */
+ int (*exp_cyl)(struct _gamut *s, struct _gamut *s1, double ratio);
+ /* Initialise this gamut with the source gamut */
+ /* expanded cylindrically around the nautral axis by */
+ /* the given ratio. */
+
int (*nexpintersect)(struct _gamut *s, struct _gamut *s1, struct _gamut *s2);
- /* Return s1 expanded with neutral axis points */
- /* and then intersected with s2. */
+ /* Initialise this gamut with neutral axis points from sa, */
+ /* and then intersected with sb. */
int (*expdstbysrcmdst)(struct _gamut *s,
struct _gamut *dst, struct _gamut *sc, struct _gamut *dc,
void (*cvect)(void *cntx, double *p2, double *p1), void *cntx);
/* Expand dst by ((dc - sc) > 0) */
+ /* Initialise this gamut with the image/destination gamut sc */
+ /* expanded by the amount that dest (dc) colorspace is outside */
+ /* the source colorspace gamut. */
double (*radial)(struct _gamut *s, double out[3], double in[3]);
/* return point on surface in same radial direction. */
diff --git a/gamut/maptest.c b/gamut/maptest.c
index 433e719..ae74a1c 100644
--- a/gamut/maptest.c
+++ b/gamut/maptest.c
@@ -33,7 +33,6 @@
#include "rspl.h"
#include "gammap.h"
#include "vrml.h"
-#include "ui.h"
void usage(void) {
fprintf(stderr,"Map bteween two gamuts, Version %s\n",ARGYLL_VERSION_STR);
@@ -203,6 +202,7 @@ main(int argc, char *argv[]) {
gimg, /* Image gamut */
gout, /* Destination gamut */
&gmi,
+ NULL, /* No gamut hull gamut */
0, 0, /* Normal black points */
0, /* Normal CMY cusp mapping */
0, /* No relative weighting override */
diff --git a/gamut/smthtest.c b/gamut/smthtest.c
index b794ed0..71ba1e2 100644
--- a/gamut/smthtest.c
+++ b/gamut/smthtest.c
@@ -36,7 +36,6 @@
#include "gamut.h"
#include "nearsmth.h"
#include "vrml.h"
-#include "ui.h"
double m21po[3] = { 2.0, 1.0, 2.0 }; /* Many to 1 filter mixing power LCh (theoretically 2) */