diff options
Diffstat (limited to 'nx-X11/lib/src/xcms/LabMxLC.c')
-rw-r--r-- | nx-X11/lib/src/xcms/LabMxLC.c | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/nx-X11/lib/src/xcms/LabMxLC.c b/nx-X11/lib/src/xcms/LabMxLC.c new file mode 100644 index 000000000..8cc089a22 --- /dev/null +++ b/nx-X11/lib/src/xcms/LabMxLC.c @@ -0,0 +1,218 @@ + +/* + * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. + * All Rights Reserved + * + * This file is a component of an X Window System-specific implementation + * of XCMS based on the TekColor Color Management System. Permission is + * hereby granted to use, copy, modify, sell, and otherwise distribute this + * software and its documentation for any purpose and without fee, provided + * that this copyright, permission, and disclaimer notice is reproduced in + * all copies of this software and in supporting documentation. TekColor + * is a trademark of Tektronix, Inc. + * + * Tektronix makes no representation about the suitability of this software + * for any purpose. It is provided "as is" and with all faults. + * + * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, + * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE. + * + * + * + * NAME + * CIELabMxVC.c + * + * DESCRIPTION + * Source for the XcmsCIELabQueryMaxLC() gamut boundary + * querying routine. + * + * DOCUMENTATION + * "TekColor Color Management System, System Implementor's Manual" + * and + * Fred W. Billmeyer & Max Saltzman, "Principles of Color + * Technology", John Wily & Sons, Inc, 1981. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "Xlibint.h" +#include "Xcmsint.h" +#include "Cv.h" + +/* + * DEFINES + */ +#define MIN(x,y) ((x) > (y) ? (y) : (x)) +#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x)) +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) +#define START_LSTAR (XcmsFloat)40.0 +#define START_CHROMA (XcmsFloat)3.6 + + +/************************************************************************ + * * + * API PRIVATE ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * _XcmsCIELabQueryMaxLCRGB - Compute maximum L* and chroma. + * + * SYNOPSIS + */ +Status +_XcmsCIELabQueryMaxLCRGB( + XcmsCCC ccc, + XcmsFloat hue, /* hue in radians */ + XcmsColor *pColor_return, + XcmsRGBi *pRGB_return) +/* + * DESCRIPTION + * Return the maximum psychometric chroma for a specified + * hue, and the corresponding L*. This is computed + * by a binary search of all possible chromas. An assumption + * is made that there are no local maxima. Use the unrounded + * Max psychometric chroma because the difference check can be + * small. + * + * NOTE: No local CCC is used because this is a private + * routine and all routines that call it are expected + * to behave properly, i.e. send a local CCC with + * no white adjust function and no gamut compression + * function. + * + * This routine only accepts hue in radians as input and outputs + * Lab and RGBi. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsFloat nSmall, nLarge; + XcmsColor tmp; + + tmp.format = XcmsCIELabFormat; + /* Use some unreachable color on the given hue */ + tmp.spec.CIELab.L_star = START_LSTAR; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, START_CHROMA); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, START_CHROMA); + /* + * Convert from Lab to RGB + * + * Note that the CIEXYZ to RGBi conversion routine must stuff the + * out of bounds RGBi values in tmp when the ccc->gamutCompProc + * is NULL. + */ + if ((_XcmsConvertColorsWithWhitePt(ccc, &tmp, ScreenWhitePointOfCCC(ccc), + (unsigned int)1, XcmsRGBiFormat, (Bool *) NULL) + == XcmsFailure) && tmp.format != XcmsRGBiFormat) { + return (XcmsFailure); + } + + /* Now pick the smallest RGB */ + nSmall = MIN3(tmp.spec.RGBi.red, + tmp.spec.RGBi.green, + tmp.spec.RGBi.blue); + /* Make the smallest RGB equal to zero */ + tmp.spec.RGBi.red -= nSmall; + tmp.spec.RGBi.green -= nSmall; + tmp.spec.RGBi.blue -= nSmall; + + /* Now pick the largest RGB */ + nLarge = MAX3(tmp.spec.RGBi.red, + tmp.spec.RGBi.green, + tmp.spec.RGBi.blue); + /* Scale the RGB values based on the largest one */ + tmp.spec.RGBi.red /= nLarge; + tmp.spec.RGBi.green /= nLarge; + tmp.spec.RGBi.blue /= nLarge; + tmp.format = XcmsRGBiFormat; + + /* If the calling routine wants RGB value give them the ones used. */ + if (pRGB_return) { + pRGB_return->red = tmp.spec.RGBi.red; + pRGB_return->green = tmp.spec.RGBi.green; + pRGB_return->blue = tmp.spec.RGBi.blue; + } + + /* Convert from RGBi to Lab */ + if (_XcmsConvertColorsWithWhitePt(ccc, &tmp, + ScreenWhitePointOfCCC(ccc), 1, XcmsCIELabFormat, (Bool *) NULL) + == XcmsFailure) { + return (XcmsFailure); + } + + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return (XcmsSuccess); +} + + +/************************************************************************ + * * + * PUBLIC ROUTINES * + * * + ************************************************************************/ + +/* + * NAME + * XcmsCIELabQueryMaxLC - Compute maximum L* and chroma. + * + * SYNOPSIS + */ +Status +XcmsCIELabQueryMaxLC ( + XcmsCCC ccc, + XcmsFloat hue_angle, /* hue_angle in degrees */ + XcmsColor *pColor_return) + +/* + * DESCRIPTION + * Return the point of maximum chroma for the specified + * hue_angle. + * + * ASSUMPTIONS + * This routine assumes that the white point associated with + * the color specification is the Screen White Point. The + * Screen White Point will also be associated with the + * returned color specification. + * + * RETURNS + * XcmsFailure - Failure + * XcmsSuccess - Succeeded + * + */ +{ + XcmsCCCRec myCCC; + + /* + * Check Arguments + */ + if (ccc == NULL || pColor_return == NULL) { + return(XcmsFailure); + } + + /* Use my own CCC */ + memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); + myCCC.clientWhitePt.format = XcmsUndefinedFormat; + myCCC.gamutCompProc = (XcmsCompressionProc)NULL; + + while (hue_angle < 0.0) { + hue_angle += 360.0; + } + while (hue_angle >= 360.0) { + hue_angle -= 360.0; + } + + return(_XcmsCIELabQueryMaxLCRGB (&myCCC, radians(hue_angle), pColor_return, + (XcmsRGBi *)NULL)); +} |