/*--------------------------------------------------------------------- * xyzmap_oFunc -- output-table functions (inverse of input mappings) *--------------------------------------------------------------------- */ double xyzmap_oFunc (double q, fut_calcData_p dataP) { double s; s = q; /* Recover headroom: */ s = 1.4 * s; /* [0, 1] -> [0, 1.4] */ /* Linearize */ s = Hinverse (s, &(((auxData_p)dataP)->lc)); /* [0, 1.4] -> [0, 2.4] -> [0, 1.205] */ /* Interpret according to white point and rescale for ICC: */ switch (dataP->chan) { case 0: s *= (KCP_D50_X * XYZSCALE); /* X */ break; case 1: s *= (KCP_D50_Y * XYZSCALE); /* Y */ break; case 2: s *= (KCP_D50_Z * XYZSCALE); /* Z */ break; } s = RESTRICT (s, 0.0, 1.0); return s; }
/*--------------------------------------------------------------------- * cmyklini_iFunc -- input mappings *--------------------------------------------------------------------- */ double cmyklin_iFunc ( double a, fut_calcData_p dataP) { a = (a + L0) / (1.0 + L0); a = Hinverse (a, &(((auxData_p)dataP)->lc)); a = (a - YMIN) / (1.0 - YMIN); return RESTRICT (a, 0.0, 1.0); }
/*--------------------------------------------------------------------- * cmyklin_oFunc -- output mapping *--------------------------------------------------------------------- */ double cmyklin_oFunc ( double s, fut_calcData_p dataP) { s = (1.0 - YMIN) * s + YMIN; s = Hfunc (s, &(((auxData_p)dataP)->lc)); s = (1.0 + L0) * s - L0; s = RESTRICT (s, 0.0, 1.0); return s; }
/*--------------------------------------------------------------------- * uvLLab_gFun -- grid-table functions *--------------------------------------------------------------------- */ double uvLLab_gFun (double_p dP, fut_calcData_p dataP) { double u = dP[0], v = dP[1], l = dP[2]; double x, y, z, p, delta, a, astar, bstar; /* Decode piecewise linear functions of u and v: */ delta = u - UGRID0; a = (delta > 0.0) ? ((auxData_p)dataP)->uvLLabC.bu1 : ((auxData_p)dataP)->uvLLabC.bu0; delta = UNMAP (delta, a); u = U0 + delta; delta = v - VGRID0; a = (delta > 0.0) ? ((auxData_p)dataP)->uvLLabC.bv1 : ((auxData_p)dataP)->uvLLabC.bv0; delta = UNMAP (delta, a); v = V0 + delta; u = 0.070 + 0.40996784565916 * u; /* CIE 1976 u' */ v = 0.165 + 0.41986827661910 * v; /* CIE 1976 v' */ /* Compute CIE 1931 tristimulus values: */ y = Hinverse (l, &(((auxData_p)dataP)->lc)); /* CIE 1931 Y */ y = (254.0 * y + 1.0) / 255.0; /* recompress for Prophecy */ x = 2.25 * (u / v) * y; /* CIE 1931 X */ z = ((3.0 - 0.75 * u) / v - 5.0) * y; /* CIE 1931 Z */ /* Scale to white point: */ x /= XWHITE; y /= YWHITE; z /= ZWHITE; /* Convert to CIELAB: */ astar = (Hfunc (x, &(((auxData_p)dataP)->lc)) - Hfunc (y, &(((auxData_p)dataP)->lc))) / 0.00232; /* CIE 1976 a* */ bstar = (Hfunc (y, &(((auxData_p)dataP)->lc)) - Hfunc (z, &(((auxData_p)dataP)->lc))) / 0.00580; /* CIE 1976 b* */ /* Encode CIELAB for L* in [0, 100] and a* & b* in [-200, 200]: */ switch (dataP->chan) { case 0: /* (L*)/100 */ p = Hfunc (y, &(((auxData_p)dataP)->lc)); break; case 1: /* ~ 1/2 + (a*)/400 */ p = MID12BIT + 0.0025 * astar; break; case 2: /* ~ 1/2 + (b*)/400 */ p = MID12BIT + 0.0025 * bstar; break; default: p = 6.023e+23; /* Avogadro's number */ break; } return RESTRICT (p, 0.0, 1.0); }
double uvLLab_iv (double v, fut_calcData_p dataP) /* piecewise linear in v' */ { double delta, a; #if defined KCP_MAP_BASE_MAX_REF v *= KCP_16_TO_8_ENCODING; #endif delta = v - V0; a = (delta > 0.0) ? ((auxData_p)dataP)->uvLLabC.bv1 : ((auxData_p)dataP)->uvLLabC.bv0; delta = REMAP (delta, a); v = VGRID0 + delta; return RESTRICT (v, 0.0, 1.0); }
/*--------------------------------------------------------------------- * xfun, yfun, zfun -- input mappings *--------------------------------------------------------------------- */ double uvLLab_iu (double u, fut_calcData_p dataP) /* piecewise linear in u' */ { double delta, a; #if defined KCP_MAP_BASE_MAX_REF u *= KCP_16_TO_8_ENCODING; #endif delta = u - U0; a = (delta > 0.0) ? ((auxData_p)dataP)->uvLLabC.bu1 : ((auxData_p)dataP)->uvLLabC.bu0; delta = REMAP (delta, a); u = UGRID0 + delta; return RESTRICT (u, 0.0, 1.0); }
/*---------------------------------------------------------------------------- * outfun -- rescale and clip a* and b*; decompress L* *---------------------------------------------------------------------------- */ double uvLLab_oFun (double p, fut_calcData_p dataP) { switch (dataP->chan) { case 0: p = Hinverse (p, &(((auxData_p)dataP)->lc)); /* Y */ p = (255.0 * p - 1.0) / 254.0; /* decompress from Prophecy Dmax */ p = Hfunc (p, &(((auxData_p)dataP)->lc)); /* (L*)/100, in [-0.0356, 1] */ break; case 1: case 2: p = 400.0 * (p - MID12BIT); /* CIE 1976 a*, b*, in [-200, 200] */ p = RESTRICT (p, -128.0, 127.0); /* clip to [-128, 127] */ p = p + 128.0; /* -> [0, 255] */ p /= 255.0; /* from [0, 255] to [0, 1] */ break; default: p = 6.023e+23; break; } #if defined KCP_MAP_BASE_MAX_REF p *= KCP_8_TO_16_ENCODING; #endif return RESTRICT (p, 0.0, 1.0); /* L* in [0, 100]; a* & b* in [-128, 127] */ }
/* yzfun -- piecewise-linear input mappings, with gridpoint at * neutral (a* = b* = 0; 8-bit encoding = 128) */ static double yzfun (double y, fut_calcData_p dataP) { double delta, neutralgrid; neutralgrid = ((fData_p) dataP)->neutralgrid; delta = y - ((fData_p) dataP)->neutralInput; if (delta < 0.0) { y = neutralgrid * (y / ((fData_p) dataP)->neutralInput); } else { y = 1.0 - (1.0 - neutralgrid) * ((1.0 - y) / (1.0 - ((fData_p) dataP)->neutralInput)); } return RESTRICT (y, 0.0, 1.0); }
double uvLLab_iL (double l, fut_calcData_p dataP) /* piecewise linear in v' */ { double y; #if defined KCP_MAP_BASE_MAX_REF l *= KCP_16_TO_8_ENCODING; #endif /* Convert to luminance: */ y = Hinverse (l, &(((auxData_p)dataP)->lc)); /* ==> y is compressed relative luminance */ y = (255.0 * y - 1.0) / 254.0; /* decompress for L*a*b* */ /* Convert back to (L*)/100: */ l = Hfunc (y, &(((auxData_p)dataP)->lc)); /* (L*)/100, in [-0.0356, 1] */ return RESTRICT (l, 0.0, 1.0); }
/*--------------------------------------------------------------------- * xyzmap_iFunc -- input mappings *--------------------------------------------------------------------- */ double xyzmap_iFunc (double xyz, fut_calcData_p dataP) { switch (dataP->chan) { case 0: xyz /= (KCP_D50_X * XYZSCALE); /* X */ break; case 1: xyz /= (KCP_D50_Y * XYZSCALE); /* Y */ break; case 2: xyz /= (KCP_D50_Z * XYZSCALE); /* Z */ break; } xyz = Hfunc (xyz, &(((auxData_p)dataP)->lc)); xyz /= 1.4; return RESTRICT (xyz, 0.0, 1.0); }