11ab64890Smrg 21ab64890Smrg/* 31ab64890Smrg * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. 41ab64890Smrg * All Rights Reserved 561b2299dSmrg * 61ab64890Smrg * This file is a component of an X Window System-specific implementation 71ab64890Smrg * of XCMS based on the TekColor Color Management System. Permission is 81ab64890Smrg * hereby granted to use, copy, modify, sell, and otherwise distribute this 91ab64890Smrg * software and its documentation for any purpose and without fee, provided 101ab64890Smrg * that this copyright, permission, and disclaimer notice is reproduced in 111ab64890Smrg * all copies of this software and in supporting documentation. TekColor 121ab64890Smrg * is a trademark of Tektronix, Inc. 1361b2299dSmrg * 141ab64890Smrg * Tektronix makes no representation about the suitability of this software 151ab64890Smrg * for any purpose. It is provided "as is" and with all faults. 1661b2299dSmrg * 171ab64890Smrg * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, 181ab64890Smrg * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 191ab64890Smrg * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY 201ab64890Smrg * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 211ab64890Smrg * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF 221ab64890Smrg * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 231ab64890Smrg * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE. 241ab64890Smrg * 251ab64890Smrg * NAME 261ab64890Smrg * CIELabGcL.c 271ab64890Smrg * 281ab64890Smrg * DESCRIPTION 291ab64890Smrg * Source for XcmsCIELabClipL() gamut compression routine. 301ab64890Smrg * 311ab64890Smrg */ 321ab64890Smrg 331ab64890Smrg#ifdef HAVE_CONFIG_H 341ab64890Smrg#include <config.h> 351ab64890Smrg#endif 361ab64890Smrg#include "Xlibint.h" 371ab64890Smrg#include "Xcmsint.h" 381ab64890Smrg#include "Cv.h" 391ab64890Smrg 401ab64890Smrg 411ab64890Smrg/************************************************************************ 421ab64890Smrg * * 431ab64890Smrg * PUBLIC ROUTINES * 441ab64890Smrg * * 451ab64890Smrg ************************************************************************/ 461ab64890Smrg 471ab64890Smrg/* 481ab64890Smrg * NAME 491ab64890Smrg * XcmsCIELabClipL - Return the closest L* 501ab64890Smrg * 511ab64890Smrg * SYNOPSIS 521ab64890Smrg */ 531ab64890Smrg/* ARGSUSED */ 541ab64890SmrgStatus 551ab64890SmrgXcmsCIELabClipL ( 561ab64890Smrg XcmsCCC ccc, 571ab64890Smrg XcmsColor *pColors_in_out, 581ab64890Smrg unsigned int nColors, 591ab64890Smrg unsigned int i, 601ab64890Smrg Bool *pCompressed) 611ab64890Smrg/* 621ab64890Smrg * DESCRIPTION 631ab64890Smrg * Return the closest L* for a specific hue and chroma. 6461b2299dSmrg * This routine takes any color as input and outputs 651ab64890Smrg * a CIE XYZ color. 661ab64890Smrg * 671ab64890Smrg * Since this routine works with the L* within 681ab64890Smrg * pColor_in_out intermediate results may be returned 691ab64890Smrg * even though it may be invalid. 701ab64890Smrg * 711ab64890Smrg * RETURNS 721ab64890Smrg * XcmsFailure - Failure 731ab64890Smrg * XcmsSuccess - Succeeded 741ab64890Smrg * 751ab64890Smrg */ 761ab64890Smrg{ 771ab64890Smrg XcmsCCCRec myCCC; 781ab64890Smrg XcmsColor *pColor; 791ab64890Smrg XcmsColor Lab_max; 801ab64890Smrg XcmsFloat hue, chroma, maxChroma; 811ab64890Smrg Status retval; 821ab64890Smrg 831ab64890Smrg /* Use my own CCC */ 841ab64890Smrg memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); 851ab64890Smrg myCCC.clientWhitePt.format = XcmsUndefinedFormat;/* Inherit Screen WP */ 861ab64890Smrg myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut compression */ 871ab64890Smrg 881ab64890Smrg /* 891ab64890Smrg * Color specification passed as input can be assumed to: 901ab64890Smrg * 1. Be in XcmsCIEXYZFormat 911ab64890Smrg * 2. Already be white point adjusted for the Screen White Point. 921ab64890Smrg * This means that the white point now associated with this 931ab64890Smrg * color spec is the Screen White Point (even if the 941ab64890Smrg * ccc->clientWhitePt differs). 951ab64890Smrg */ 961ab64890Smrg 971ab64890Smrg pColor = pColors_in_out + i; 9861b2299dSmrg 991ab64890Smrg if (ccc->visual->class < StaticColor) { 1001ab64890Smrg /* 1011ab64890Smrg * GRAY ! 1021ab64890Smrg */ 1031ab64890Smrg return(XcmsFailure); 1041ab64890Smrg } else { 1051ab64890Smrg /* Convert from CIEXYZ to CIE L*u*v* format */ 1061ab64890Smrg if (_XcmsDIConvertColors(&myCCC, pColor, 1071ab64890Smrg ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat) 1081ab64890Smrg == XcmsFailure) { 1091ab64890Smrg return(XcmsFailure); 1101ab64890Smrg } 1111ab64890Smrg 1121ab64890Smrg hue = XCMS_CIELAB_PMETRIC_HUE(pColor->spec.CIELab.a_star, 1131ab64890Smrg pColor->spec.CIELab.b_star); 1141ab64890Smrg chroma = XCMS_CIELAB_PMETRIC_CHROMA(pColor->spec.CIELab.a_star, 1151ab64890Smrg pColor->spec.CIELab.b_star); 1161ab64890Smrg /* Step 1: compute the maximum L* and chroma for this hue. */ 1171ab64890Smrg /* This copy may be overkill but it preserves the pixel etc. */ 1181ab64890Smrg memcpy((char *)&Lab_max, (char *)pColor, sizeof(XcmsColor)); 1191ab64890Smrg if (_XcmsCIELabQueryMaxLCRGB (&myCCC, hue, &Lab_max, 1201ab64890Smrg (XcmsRGBi *)NULL) == XcmsFailure) { 1211ab64890Smrg return (XcmsFailure); 1221ab64890Smrg } 1231ab64890Smrg maxChroma = XCMS_CIELAB_PMETRIC_CHROMA(Lab_max.spec.CIELab.a_star, 1241ab64890Smrg Lab_max.spec.CIELab.b_star); 1251ab64890Smrg 1261ab64890Smrg /* Now check and return the appropriate L* */ 1271ab64890Smrg if (chroma == maxChroma) { 1281ab64890Smrg /* When the chroma input is equal to the maximum chroma */ 1291ab64890Smrg /* merely return the L* for that chroma. */ 1301ab64890Smrg memcpy((char *)pColor, (char *)&Lab_max, sizeof(XcmsColor)); 1311ab64890Smrg retval = _XcmsDIConvertColors(&myCCC, pColor, 1321ab64890Smrg ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); 1331ab64890Smrg } else if (chroma > maxChroma) { 1341ab64890Smrg /* When the chroma input is greater than the maximum chroma */ 1351ab64890Smrg /* merely return the L* and chroma for the given hue. */ 1361ab64890Smrg memcpy((char *)pColor, (char *)&Lab_max, sizeof(XcmsColor)); 1371ab64890Smrg return (XcmsFailure); 1381ab64890Smrg } else if (pColor->spec.CIELab.L_star < Lab_max.spec.CIELab.L_star) { 13961b2299dSmrg /* Find the minimum lightness for the given chroma. */ 1401ab64890Smrg if (pColor->format != XcmsCIELabFormat) { 1411ab64890Smrg if (_XcmsDIConvertColors(ccc, pColor, 1421ab64890Smrg ScreenWhitePointOfCCC(ccc), 1, XcmsCIELabFormat) 1431ab64890Smrg == XcmsFailure) { 1441ab64890Smrg return(XcmsFailure); 1451ab64890Smrg } 1461ab64890Smrg } 1471ab64890Smrg if (XcmsCIELabQueryMinL(&myCCC, degrees(hue), chroma, pColor) 1481ab64890Smrg == XcmsFailure) { 1491ab64890Smrg return (XcmsFailure); 1501ab64890Smrg } 1511ab64890Smrg retval = _XcmsDIConvertColors(&myCCC, pColor, 1521ab64890Smrg ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); 1531ab64890Smrg } else { 1541ab64890Smrg /* Find the maximum lightness for the given chroma. */ 1551ab64890Smrg if (pColor->format != XcmsCIELabFormat) { 1561ab64890Smrg if (_XcmsDIConvertColors(ccc, pColor, 1571ab64890Smrg ScreenWhitePointOfCCC(ccc), 1, XcmsCIELabFormat) 1581ab64890Smrg == XcmsFailure) { 1591ab64890Smrg return(XcmsFailure); 1601ab64890Smrg } 1611ab64890Smrg } 1621ab64890Smrg if (XcmsCIELabQueryMaxL(&myCCC, degrees(hue), chroma, pColor) 1631ab64890Smrg == XcmsFailure) { 1641ab64890Smrg return (XcmsFailure); 1651ab64890Smrg } 1661ab64890Smrg retval = _XcmsDIConvertColors(&myCCC, pColor, 1671ab64890Smrg ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); 1681ab64890Smrg } 1691ab64890Smrg if (retval != XcmsFailure && pCompressed != NULL) { 1701ab64890Smrg *(pCompressed + i) = True; 1711ab64890Smrg } 1721ab64890Smrg return(retval); 1731ab64890Smrg } 1741ab64890Smrg} 175