From 22f703cab05b7cd368f4de9e03991b7664dc5022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 1 Sep 2014 13:56:46 +0200 Subject: Initial import of argyll version 1.5.1-8 --- xicc/xmono.c | 324 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 xicc/xmono.c (limited to 'xicc/xmono.c') diff --git a/xicc/xmono.c b/xicc/xmono.c new file mode 100644 index 0000000..f0ee04f --- /dev/null +++ b/xicc/xmono.c @@ -0,0 +1,324 @@ +/* + * International Color Consortium color transform expanded support + * + * Author: Graeme W. Gill + * Date: 2/7/00 + * Version: 1.00 + * + * Copyright 2000 Graeme W. Gill + * All rights reserved. + * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :- + * see the License.txt file for licencing details. + * + * Based on the old iccXfm class. + */ + +/* + * This module provides the expands icclib functionality + * for monochrome profiles. + * This file is #included in xicc.c, to keep its functions private. + */ + +/* + * TTBD: + * Some of the error handling is crude. Shouldn't use + * error(), should return status. + * + */ + +/* ============================================================= */ +/* Forward and Backward Monochrome type conversion */ +/* Return 0 on success, 1 if clipping occured, 2 on other error */ + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* Individual components of Fwd conversion: */ +static int +icxLuMonoFwd_curve ( +icxLuMono *p, /* This */ +double *out, /* Vector of output values */ +double *in /* Vector of input values */ +) { + return ((icmLuMono *)p->plu)->fwd_curve((icmLuMono *)p->plu, out, in); +} + +static int +icxLuMonoFwd_map ( +icxLuMono *p, /* This */ +double *out, /* Vector of output values */ +double *in /* Vector of input values */ +) { + return ((icmLuMono *)p->plu)->fwd_map((icmLuMono *)p->plu, out, in); +} + +static int +icxLuMonoFwd_abs ( +icxLuMono *p, /* This */ +double *out, /* Vector of output values */ +double *in /* Vector of input values */ +) { + int rv = 0; + rv |= ((icmLuMono *)p->plu)->fwd_abs((icmLuMono *)p->plu, out, in); + + if (p->pcs == icxSigJabData) { + p->cam->XYZ_to_cam(p->cam, out, out); + } + return rv; +} + + +/* Overall Fwd conversion routine */ +static int +icxLuMonoFwd_lookup ( +icxLuBase *pp, /* This */ +double *out, /* Vector of output values */ +double *in /* Vector of input values */ +) { + int rv = 0; + icxLuMono *p = (icxLuMono *)pp; + rv |= icxLuMonoFwd_curve(p, out, in); + rv |= icxLuMonoFwd_map(p, out, out); + rv |= icxLuMonoFwd_abs(p, out, out); + return rv; +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* Given a relative XYZ or Lab PCS value, convert in the fwd direction into */ +/* the nominated output PCS (ie. Absolute, Jab etc.) */ +/* (This is used in generating gamut compression in B2A tables) */ +void icxLuMono_fwd_relpcs_outpcs( +icxLuBase *pp, +icColorSpaceSignature is, /* Input space, XYZ or Lab */ +double *out, double *in) { + icxLuMono *p = (icxLuMono *)pp; + + icmLab2XYZ(&icmD50, out, in); + if (is == icSigLabData && p->natpcs == icSigXYZData) { + icxLuMonoFwd_abs(p, out, out); + } else if (is == icSigXYZData && p->natpcs == icSigLabData) { + icxLuMonoFwd_abs(p, out, out); + } +} + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* Individual components of Bwd conversion: */ + +static int +icxLuMonoBwd_abs ( +icxLuMono *p, /* This */ +double *out, /* Vector of output values */ +double *in /* Vector of input values */ +) { + int rv = 0; + + if (p->pcs == icxSigJabData) { + p->cam->cam_to_XYZ(p->cam, out, in); + rv |= ((icmLuMono *)p->plu)->bwd_abs((icmLuMono *)p->plu, out, out); + /* Hack to prevent CAM02 weirdness being amplified by */ + /* any later per channel clipping. */ + /* Limit -Y to non-stupid values by scaling */ + if (out[1] < -0.1) { + out[0] *= -0.1/out[1]; + out[2] *= -0.1/out[1]; + out[1] = -0.1; + } + } else { + rv |= ((icmLuMono *)p->plu)->bwd_abs((icmLuMono *)p->plu, out, in); + } + return rv; +} + +static int +icxLuMonoBwd_map ( +icxLuMono *p, /* This */ +double *out, /* Vector of output values */ +double *in /* Vector of input values */ +) { + return ((icmLuMono *)p->plu)->bwd_map((icmLuMono *)p->plu, out, in); +} + +static int +icxLuMonoBwd_curve ( +icxLuMono *p, /* This */ +double *out, /* Vector of output values */ +double *in /* Vector of input values */ +) { + return ((icmLuMono *)p->plu)->bwd_curve((icmLuMono *)p->plu, out, in); +} + +/* Overall Bwd conversion routine */ +static int +icxLuMonoBwd_lookup ( +icxLuBase *pp, /* This */ +double *out, /* Vector of output values */ +double *in /* Vector of input values */ +) { + double temp[3]; + int rv = 0; + icxLuMono *p = (icxLuMono *)pp; + rv |= icxLuMonoBwd_abs(p, temp, in); + rv |= icxLuMonoBwd_map(p, out, temp); + rv |= icxLuMonoBwd_curve(p, out, out); + return rv; +} + +static void +icxLuMono_free( +icxLuBase *p +) { + p->plu->del(p->plu); + if (p->cam != NULL) + p->cam->del(p->cam); + free(p); +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* Given a nominated output PCS (ie. Absolute, Jab etc.), convert it in the bwd */ +/* direction into a relative XYZ or Lab PCS value */ +/* (This is used in generating gamut compression in B2A tables) */ +void icxLuMono_bwd_outpcs_relpcs( +icxLuBase *pp, +icColorSpaceSignature os, /* Output space, XYZ or Lab */ +double *out, double *in) { + icxLuMono *p = (icxLuMono *)pp; + + if (os == icSigXYZData && p->natpcs == icSigLabData) { + icxLuMonoFwd_abs(p, out, in); + icmLab2XYZ(&icmD50, out, out); + } else if (os == icSigXYZData && p->natpcs == icSigLabData) { + icxLuMonoFwd_abs(p, out, in); + icmXYZ2Lab(&icmD50, out, out); + } else { + icxLuMonoFwd_abs(p, out, in); + } +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +static gamut *icxLuMonoGamut(icxLuBase *plu, double detail); + +static icxLuBase * +new_icxLuMono( +xicc *xicp, +int flags, /* clip, merge flags */ +icmLuBase *plu, /* Pointer to Lu we are expanding */ +icmLookupFunc func, /* Functionality requested */ +icRenderingIntent intent, /* Rendering intent */ +icColorSpaceSignature pcsor, /* PCS override (0 = def) */ +icxViewCond *vc, /* Viewing Condition (NULL if pcsor is not CIECAM) */ +int dir /* 0 = fwd, 1 = bwd */ +) { + icxLuMono *p; + + /* Do the basic icxLuMono creation and initialisation */ + + if ((p = (icxLuMono *) calloc(1,sizeof(icxLuMono))) == NULL) + return NULL; + + p->pp = xicp; + p->plu = plu; + p->del = icxLuMono_free; + p->lutspaces = icxLutSpaces; + p->spaces = icxLuSpaces; + p->get_native_ranges = icxLu_get_native_ranges; + p->get_ranges = icxLu_get_ranges; + p->efv_wh_bk_points = icxLuEfv_wh_bk_points; + p->get_gamut = icxLuMonoGamut; + p->fwd_relpcs_outpcs = icxLuMono_fwd_relpcs_outpcs; + p->bwd_outpcs_relpcs = icxLuMono_bwd_outpcs_relpcs; + p->nearclip = 0; /* Set flag defaults */ + p->mergeclut = 0; + p->noisluts = 0; + p->noipluts = 0; + p->nooluts = 0; + p->intsep = 0; + + p->fwd_lookup = icxLuMonoFwd_lookup; + p->fwd_curve = icxLuMonoFwd_curve; + p->fwd_map = icxLuMonoFwd_map; + p->fwd_abs = icxLuMonoFwd_abs; + p->bwd_lookup = icxLuMonoBwd_lookup; + p->bwd_abs = icxLuMonoFwd_abs; + p->bwd_map = icxLuMonoFwd_map; + p->bwd_curve = icxLuMonoFwd_curve; + if (dir) { + p->lookup = icxLuMonoBwd_lookup; + p->inv_lookup = icxLuMonoFwd_lookup; + } else { + p->lookup = icxLuMonoFwd_lookup; + p->inv_lookup = icxLuMonoBwd_lookup; + } + + /* There are no mono specific flags */ + p->flags = flags; + p->func = func; + + /* Get details of internal, native color space */ + plu->lutspaces(p->plu, &p->natis, NULL, &p->natos, NULL, &p->natpcs); + + /* Get other details of conversion */ + p->plu->spaces(p->plu, NULL, &p->inputChan, NULL, &p->outputChan, NULL, NULL, NULL, NULL, NULL); + + /* Init the CAM model */ + if (pcsor == icxSigJabData) { + p->vc = *vc; /* Copy the structure */ + p->cam = new_icxcam(cam_default); + p->cam->set_view(p->cam, vc->Ev, vc->Wxyz, vc->La, vc->Yb, vc->Lv, vc->Yf, vc->Fxyz, + XICC_USE_HK); + } else + p->cam = NULL; + + /* Remember the effective intent */ + p->intent = intent; + + /* Get the effective spaces */ + plu->spaces(plu, &p->ins, NULL, &p->outs, NULL, NULL, NULL, NULL, &p->pcs, NULL); + + /* Override with pcsor */ + if (pcsor == icxSigJabData) { + p->pcs = pcsor; + if (func == icmBwd || func == icmGamut || func == icmPreview) + p->ins = pcsor; + if (func == icmFwd || func == icmPreview) + p->outs = pcsor; + } + + /* In general the native and effective ranges of the icx will be the same as the */ + /* underlying icm lookup object. */ + p->plu->get_lutranges(p->plu, p->ninmin, p->ninmax, p->noutmin, p->noutmax); + p->plu->get_ranges(p->plu, p->inmin, p->inmax, p->outmin, p->outmax); + + /* If we have a Jab PCS override, reflect this in the effective icx range. */ + /* Note that the ab ranges are nominal. They will exceed this range */ + /* for colors representable in L*a*b* PCS */ + if (p->ins == icxSigJabData) { + p->inmin[0] = 0.0; p->inmax[0] = 100.0; + p->inmin[1] = -128.0; p->inmax[1] = 128.0; + p->inmin[2] = -128.0; p->inmax[2] = 128.0; + } else if (p->outs == icxSigJabData) { + p->outmin[0] = 0.0; p->outmax[0] = 100.0; + p->outmin[1] = -128.0; p->outmax[1] = 128.0; + p->outmin[2] = -128.0; p->outmax[2] = 128.0; + } + + return (icxLuBase *)p; +} + +/* ============================================================= */ + +/* Given an xicc lookup object, returm a gamut object. */ +/* Note that the PCS must be Lab or Jab */ +/* Return NULL on error, check errc+err for reason */ +static gamut *icxLuMonoGamut( +icxLuBase *plu, /* this */ +double detail /* gamut detail level, 0.0 = def */ +) { + gamut *xgam; + xicc *p = plu->pp; /* parent xicc */ + + p->errc = 1; + sprintf(p->err,"Creating Mono gamut surface not supported yet."); + plu->del(plu); + xgam = NULL; + + return xgam; +} + -- cgit v1.2.3