LabGcL.c revision 61b2299d
11.4Sis/* $Xorg: LabGcL.c,v 1.3 2000/08/17 19:44:39 cpqbld Exp $ */ 21.1Sis 31.1Sis/* 41.1Sis * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. 51.1Sis * All Rights Reserved 61.1Sis * 71.1Sis * This file is a component of an X Window System-specific implementation 81.1Sis * of XCMS based on the TekColor Color Management System. Permission is 91.1Sis * hereby granted to use, copy, modify, sell, and otherwise distribute this 101.1Sis * software and its documentation for any purpose and without fee, provided 111.1Sis * that this copyright, permission, and disclaimer notice is reproduced in 121.1Sis * all copies of this software and in supporting documentation. TekColor 131.1Sis * is a trademark of Tektronix, Inc. 141.1Sis * 151.1Sis * Tektronix makes no representation about the suitability of this software 161.1Sis * for any purpose. It is provided "as is" and with all faults. 171.1Sis * 181.1Sis * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, 191.1Sis * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 201.1Sis * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY 211.1Sis * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 221.1Sis * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF 231.1Sis * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 241.1Sis * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE. 251.1Sis * 261.1Sis * NAME 271.1Sis * CIELabGcL.c 281.1Sis * 291.1Sis * DESCRIPTION 301.1Sis * Source for XcmsCIELabClipL() gamut compression routine. 311.1Sis * 321.1Sis */ 331.1Sis/* $XFree86: xc/lib/X11/LabGcL.c,v 1.3 2001/01/17 19:41:38 dawes Exp $ */ 341.1Sis 351.1Sis#ifdef HAVE_CONFIG_H 361.1Sis#include <config.h> 371.1Sis#endif 381.1Sis#include "Xlibint.h" 391.1Sis#include "Xcmsint.h" 401.1Sis#include "Cv.h" 411.1Sis 421.1Sis 431.1Sis/************************************************************************ 441.1Sis * * 451.1Sis * PUBLIC ROUTINES * 461.1Sis * * 471.1Sis ************************************************************************/ 481.1Sis 491.1Sis/* 501.1Sis * NAME 511.1Sis * XcmsCIELabClipL - Return the closest L* 521.1Sis * 531.1Sis * SYNOPSIS 541.1Sis */ 551.1Sis/* ARGSUSED */ 561.1SisStatus 571.1SisXcmsCIELabClipL ( 581.1Sis XcmsCCC ccc, 591.1Sis XcmsColor *pColors_in_out, 601.1Sis unsigned int nColors, 611.1Sis unsigned int i, 621.1Sis Bool *pCompressed) 631.1Sis/* 641.1Sis * DESCRIPTION 651.1Sis * Return the closest L* for a specific hue and chroma. 661.1Sis * This routine takes any color as input and outputs 671.1Sis * a CIE XYZ color. 681.1Sis * 691.1Sis * Since this routine works with the L* within 701.1Sis * pColor_in_out intermediate results may be returned 711.1Sis * even though it may be invalid. 721.1Sis * 731.1Sis * RETURNS 741.1Sis * XcmsFailure - Failure 751.1Sis * XcmsSuccess - Succeeded 761.1Sis * 771.1Sis */ 781.1Sis{ 791.1Sis XcmsCCCRec myCCC; 801.1Sis XcmsColor *pColor; 811.1Sis XcmsColor Lab_max; 821.1Sis XcmsFloat hue, chroma, maxChroma; 831.1Sis Status retval; 841.1Sis 851.1Sis /* Use my own CCC */ 861.1Sis memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); 871.1Sis myCCC.clientWhitePt.format = XcmsUndefinedFormat;/* Inherit Screen WP */ 881.1Sis myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut compression */ 891.1Sis 901.1Sis /* 911.1Sis * Color specification passed as input can be assumed to: 921.1Sis * 1. Be in XcmsCIEXYZFormat 931.1Sis * 2. Already be white point adjusted for the Screen White Point. 941.1Sis * This means that the white point now associated with this 951.1Sis * color spec is the Screen White Point (even if the 961.1Sis * ccc->clientWhitePt differs). 971.1Sis */ 981.1Sis 991.1Sis pColor = pColors_in_out + i; 1001.1Sis 1011.1Sis if (ccc->visual->class < StaticColor) { 1021.1Sis /* 1031.1Sis * GRAY ! 1041.1Sis */ 1051.1Sis return(XcmsFailure); 1061.1Sis } else { 1071.1Sis /* Convert from CIEXYZ to CIE L*u*v* format */ 1081.1Sis if (_XcmsDIConvertColors(&myCCC, pColor, 1091.1Sis ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat) 1101.1Sis == XcmsFailure) { 1111.1Sis return(XcmsFailure); 1121.1Sis } 1131.1Sis 1141.1Sis hue = XCMS_CIELAB_PMETRIC_HUE(pColor->spec.CIELab.a_star, 1151.1Sis pColor->spec.CIELab.b_star); 1161.1Sis chroma = XCMS_CIELAB_PMETRIC_CHROMA(pColor->spec.CIELab.a_star, 1171.1Sis pColor->spec.CIELab.b_star); 1181.1Sis /* Step 1: compute the maximum L* and chroma for this hue. */ 1191.1Sis /* This copy may be overkill but it preserves the pixel etc. */ 1201.1Sis memcpy((char *)&Lab_max, (char *)pColor, sizeof(XcmsColor)); 1211.1Sis if (_XcmsCIELabQueryMaxLCRGB (&myCCC, hue, &Lab_max, 1221.1Sis (XcmsRGBi *)NULL) == XcmsFailure) { 1231.1Sis return (XcmsFailure); 1241.1Sis } 1251.1Sis maxChroma = XCMS_CIELAB_PMETRIC_CHROMA(Lab_max.spec.CIELab.a_star, 1261.1Sis Lab_max.spec.CIELab.b_star); 1271.1Sis 1281.1Sis /* Now check and return the appropriate L* */ 1291.1Sis if (chroma == maxChroma) { 1301.1Sis /* When the chroma input is equal to the maximum chroma */ 1311.1Sis /* merely return the L* for that chroma. */ 1321.1Sis memcpy((char *)pColor, (char *)&Lab_max, sizeof(XcmsColor)); 1331.1Sis retval = _XcmsDIConvertColors(&myCCC, pColor, 1341.1Sis ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); 1351.1Sis } else if (chroma > maxChroma) { 1361.1Sis /* When the chroma input is greater than the maximum chroma */ 1371.1Sis /* merely return the L* and chroma for the given hue. */ 1381.1Sis memcpy((char *)pColor, (char *)&Lab_max, sizeof(XcmsColor)); 1391.1Sis return (XcmsFailure); 1401.1Sis } else if (pColor->spec.CIELab.L_star < Lab_max.spec.CIELab.L_star) { 1411.1Sis /* Find the minimum lightness for the given chroma. */ 1421.1Sis if (pColor->format != XcmsCIELabFormat) { 1431.1Sis if (_XcmsDIConvertColors(ccc, pColor, 1441.1Sis ScreenWhitePointOfCCC(ccc), 1, XcmsCIELabFormat) 1451.1Sis == XcmsFailure) { 1461.1Sis return(XcmsFailure); 1471.1Sis } 1481.1Sis } 1491.1Sis if (XcmsCIELabQueryMinL(&myCCC, degrees(hue), chroma, pColor) 1501.1Sis == XcmsFailure) { 1511.1Sis return (XcmsFailure); 1521.1Sis } 1531.1Sis retval = _XcmsDIConvertColors(&myCCC, pColor, 1541.1Sis ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); 1551.1Sis } else { 1561.1Sis /* Find the maximum lightness for the given chroma. */ 1571.1Sis if (pColor->format != XcmsCIELabFormat) { 1581.1Sis if (_XcmsDIConvertColors(ccc, pColor, 1591.1Sis ScreenWhitePointOfCCC(ccc), 1, XcmsCIELabFormat) 1601.1Sis == XcmsFailure) { 1611.1Sis return(XcmsFailure); 1621.1Sis } 1631.1Sis } 1641.1Sis if (XcmsCIELabQueryMaxL(&myCCC, degrees(hue), chroma, pColor) 1651.1Sis == XcmsFailure) { 1661.1Sis return (XcmsFailure); 1671.1Sis } 1681.1Sis retval = _XcmsDIConvertColors(&myCCC, pColor, 1691.1Sis ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); 1701.1Sis } 1711.1Sis if (retval != XcmsFailure && pCompressed != NULL) { 1721.1Sis *(pCompressed + i) = True; 1731.1Sis } 1741.1Sis return(retval); 1751.1Sis } 1761.1Sis} 1771.1Sis