From 3db384424bd7398ffbb7a355cab8f15f3add009f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 2 Oct 2016 19:24:58 +0200 Subject: New upstream version 1.9.1+repack --- gamut/gammap.c | 50 ++++++++++++++------- gamut/gammap.h | 2 + gamut/gamut.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- gamut/gamut.h | 14 ++++-- gamut/maptest.c | 2 +- gamut/smthtest.c | 1 - 6 files changed, 178 insertions(+), 22 deletions(-) (limited to 'gamut') 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) */ -- cgit v1.2.3