HVCGcV.c revision 1ab64890
11ab64890Smrg/* $Xorg: HVCGcV.c,v 1.3 2000/08/17 19:44:36 cpqbld Exp $ */ 21ab64890Smrg 31ab64890Smrg/* 41ab64890Smrg * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. 51ab64890Smrg * All Rights Reserved 61ab64890Smrg * 71ab64890Smrg * This file is a component of an X Window System-specific implementation 81ab64890Smrg * of Xcms based on the TekColor Color Management System. TekColor is a 91ab64890Smrg * trademark of Tektronix, Inc. The term "TekHVC" designates a particular 101ab64890Smrg * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent 111ab64890Smrg * foreign patents pending). Permission is hereby granted to use, copy, 121ab64890Smrg * modify, sell, and otherwise distribute this software and its 131ab64890Smrg * documentation for any purpose and without fee, provided that: 141ab64890Smrg * 151ab64890Smrg * 1. This copyright, permission, and disclaimer notice is reproduced in 161ab64890Smrg * all copies of this software and any modification thereof and in 171ab64890Smrg * supporting documentation; 181ab64890Smrg * 2. Any color-handling application which displays TekHVC color 191ab64890Smrg * cooordinates identifies these as TekHVC color coordinates in any 201ab64890Smrg * interface that displays these coordinates and in any associated 211ab64890Smrg * documentation; 221ab64890Smrg * 3. The term "TekHVC" is always used, and is only used, in association 231ab64890Smrg * with the mathematical derivations of the TekHVC Color Space, 241ab64890Smrg * including those provided in this file and any equivalent pathways and 251ab64890Smrg * mathematical derivations, regardless of digital (e.g., floating point 261ab64890Smrg * or integer) representation. 271ab64890Smrg * 281ab64890Smrg * Tektronix makes no representation about the suitability of this software 291ab64890Smrg * for any purpose. It is provided "as is" and with all faults. 301ab64890Smrg * 311ab64890Smrg * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, 321ab64890Smrg * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 331ab64890Smrg * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY 341ab64890Smrg * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 351ab64890Smrg * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF 361ab64890Smrg * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 371ab64890Smrg * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE. 381ab64890Smrg * 391ab64890Smrg * NAME 401ab64890Smrg * TekHVCGcV.c 411ab64890Smrg * 421ab64890Smrg * DESCRIPTION 431ab64890Smrg * Source for XcmsTekHVCClipV() gamut compression routine. 441ab64890Smrg * 451ab64890Smrg */ 461ab64890Smrg/* $XFree86: xc/lib/X11/HVCGcV.c,v 1.3 2001/01/17 19:41:37 dawes Exp $ */ 471ab64890Smrg 481ab64890Smrg#ifdef HAVE_CONFIG_H 491ab64890Smrg#include <config.h> 501ab64890Smrg#endif 511ab64890Smrg#include "Xlibint.h" 521ab64890Smrg#include "Xcmsint.h" 531ab64890Smrg#include "Cv.h" 541ab64890Smrg 551ab64890Smrg 561ab64890Smrg/************************************************************************ 571ab64890Smrg * * 581ab64890Smrg * PUBLIC ROUTINES * 591ab64890Smrg * * 601ab64890Smrg ************************************************************************/ 611ab64890Smrg 621ab64890Smrg/* 631ab64890Smrg * NAME 641ab64890Smrg * XcmsTekHVCClipV - Return the closest value 651ab64890Smrg * 661ab64890Smrg * SYNOPSIS 671ab64890Smrg */ 681ab64890Smrg/* ARGSUSED */ 691ab64890SmrgStatus 701ab64890SmrgXcmsTekHVCClipV ( 711ab64890Smrg XcmsCCC ccc, 721ab64890Smrg XcmsColor *pColors_in_out, 731ab64890Smrg unsigned int nColors, 741ab64890Smrg unsigned int i, 751ab64890Smrg Bool *pCompressed) 761ab64890Smrg/* 771ab64890Smrg * DESCRIPTION 781ab64890Smrg * Return the closest value for a specific hue and chroma. 791ab64890Smrg * This routine takes any color as input and outputs 801ab64890Smrg * a CIE XYZ color. 811ab64890Smrg * 821ab64890Smrg * Since this routine works with the value within 831ab64890Smrg * pColor_in_out intermediate results may be returned 841ab64890Smrg * even though it may be invalid. 851ab64890Smrg * 861ab64890Smrg * RETURNS 871ab64890Smrg * XcmsFailure - Failure 881ab64890Smrg * XcmsSuccess - Succeeded 891ab64890Smrg * 901ab64890Smrg */ 911ab64890Smrg{ 921ab64890Smrg XcmsColor *pColor; 931ab64890Smrg XcmsColor hvc_max; 941ab64890Smrg XcmsCCCRec myCCC; 951ab64890Smrg Status retval; 961ab64890Smrg 971ab64890Smrg /* 981ab64890Smrg * Insure TekHVC installed 991ab64890Smrg */ 1001ab64890Smrg if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { 1011ab64890Smrg return(XcmsFailure); 1021ab64890Smrg } 1031ab64890Smrg 1041ab64890Smrg /* Use my own CCC */ 1051ab64890Smrg memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); 1061ab64890Smrg myCCC.clientWhitePt.format = XcmsUndefinedFormat;/* Inherit Screen WP */ 1071ab64890Smrg myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut compression */ 1081ab64890Smrg 1091ab64890Smrg /* 1101ab64890Smrg * Color specification passed as input can be assumed to: 1111ab64890Smrg * 1. Be in XcmsCIEXYZFormat 1121ab64890Smrg * 2. Already be white point adjusted for the Screen White Point. 1131ab64890Smrg * This means that the white point now associated with this 1141ab64890Smrg * color spec is the Screen White Point (even if the 1151ab64890Smrg * ccc->clientWhitePt differs). 1161ab64890Smrg */ 1171ab64890Smrg 1181ab64890Smrg pColor = pColors_in_out + i; 1191ab64890Smrg 1201ab64890Smrg if (ccc->visual->class < StaticColor && 1211ab64890Smrg FunctionSetOfCCC(ccc) != (XPointer) &XcmsLinearRGBFunctionSet) { 1221ab64890Smrg /* 1231ab64890Smrg * GRAY ! 1241ab64890Smrg */ 1251ab64890Smrg return(XcmsFailure); 1261ab64890Smrg } else { 1271ab64890Smrg /* Convert from CIEXYZ to TekHVC format */ 1281ab64890Smrg if (_XcmsDIConvertColors(&myCCC, pColor, 1291ab64890Smrg &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsTekHVCFormat) 1301ab64890Smrg == XcmsFailure) { 1311ab64890Smrg return(XcmsFailure); 1321ab64890Smrg } 1331ab64890Smrg 1341ab64890Smrg /* check to make sure we have a valid TekHVC number */ 1351ab64890Smrg if (!_XcmsTekHVC_CheckModify (pColor)) { 1361ab64890Smrg return (XcmsFailure); 1371ab64890Smrg } 1381ab64890Smrg 1391ab64890Smrg /* Step 1: compute the maximum value and chroma for this hue. */ 1401ab64890Smrg /* This copy may be overkill but it preserves the pixel etc. */ 1411ab64890Smrg memcpy((char *)&hvc_max, (char *)pColor, sizeof(XcmsColor)); 1421ab64890Smrg if (_XcmsTekHVCQueryMaxVCRGB (&myCCC, hvc_max.spec.TekHVC.H, &hvc_max, 1431ab64890Smrg (XcmsRGBi *)NULL) == XcmsFailure) { 1441ab64890Smrg return (XcmsFailure); 1451ab64890Smrg } 1461ab64890Smrg 1471ab64890Smrg /* Now check and return the appropriate value */ 1481ab64890Smrg if (pColor->spec.TekHVC.C == hvc_max.spec.TekHVC.C) { 1491ab64890Smrg /* When the chroma input is equal to the maximum chroma */ 1501ab64890Smrg /* merely return the value for that chroma. */ 1511ab64890Smrg pColor->spec.TekHVC.V = hvc_max.spec.TekHVC.V; 1521ab64890Smrg if (!_XcmsTekHVC_CheckModify (pColor)) { 1531ab64890Smrg return (XcmsFailure); 1541ab64890Smrg } 1551ab64890Smrg retval = _XcmsDIConvertColors(&myCCC, pColor, 1561ab64890Smrg &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); 1571ab64890Smrg } else if (pColor->spec.TekHVC.C > hvc_max.spec.TekHVC.C) { 1581ab64890Smrg /* When the chroma input is greater than the maximum chroma */ 1591ab64890Smrg /* merely return the value and chroma for the given hue. */ 1601ab64890Smrg pColor->spec.TekHVC.C = hvc_max.spec.TekHVC.C; 1611ab64890Smrg pColor->spec.TekHVC.V = hvc_max.spec.TekHVC.V; 1621ab64890Smrg return (XcmsFailure); 1631ab64890Smrg } else if (pColor->spec.TekHVC.V < hvc_max.spec.TekHVC.V) { 1641ab64890Smrg /* When the value input is less than the maximum value point */ 1651ab64890Smrg /* compute the intersection of the line from 0,0 to max_V, max_C */ 1661ab64890Smrg /* using the chroma input. */ 1671ab64890Smrg pColor->spec.TekHVC.V = pColor->spec.TekHVC.C * 1681ab64890Smrg hvc_max.spec.TekHVC.V / hvc_max.spec.TekHVC.C; 1691ab64890Smrg if (pColor->spec.TekHVC.V >= hvc_max.spec.TekHVC.V) { 1701ab64890Smrg pColor->spec.TekHVC.C = hvc_max.spec.TekHVC.C; 1711ab64890Smrg pColor->spec.TekHVC.V = hvc_max.spec.TekHVC.V; 1721ab64890Smrg } 1731ab64890Smrg if (!_XcmsTekHVC_CheckModify (pColor)) { 1741ab64890Smrg return (XcmsFailure); 1751ab64890Smrg } 1761ab64890Smrg retval = _XcmsDIConvertColors(&myCCC, pColor, 1771ab64890Smrg &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); 1781ab64890Smrg } else { 1791ab64890Smrg /* When the value input is greater than the maximum value point */ 1801ab64890Smrg /* use HvcMaxValue to find the maximum value for the given chroma. */ 1811ab64890Smrg if (pColor->format != XcmsTekHVCFormat) { 1821ab64890Smrg if (_XcmsDIConvertColors(ccc, pColor, 1831ab64890Smrg &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat) 1841ab64890Smrg == XcmsFailure) { 1851ab64890Smrg return(XcmsFailure); 1861ab64890Smrg } 1871ab64890Smrg } 1881ab64890Smrg if (XcmsTekHVCQueryMaxV(&myCCC, 1891ab64890Smrg pColor->spec.TekHVC.H, 1901ab64890Smrg pColor->spec.TekHVC.C, 1911ab64890Smrg pColor) 1921ab64890Smrg == XcmsFailure) { 1931ab64890Smrg return (XcmsFailure); 1941ab64890Smrg } 1951ab64890Smrg retval = _XcmsDIConvertColors(&myCCC, pColor, 1961ab64890Smrg &myCCC.pPerScrnInfo->screenWhitePt, 1, XcmsCIEXYZFormat); 1971ab64890Smrg } 1981ab64890Smrg if (retval != XcmsFailure && pCompressed != NULL) { 1991ab64890Smrg *(pCompressed + i) = True; 2001ab64890Smrg } 2011ab64890Smrg return(retval); 2021ab64890Smrg } 2031ab64890Smrg} 204