HVCMxVC.c revision 1ab64890
11ab64890Smrg/* $Xorg: HVCMxVC.c,v 1.3 2000/08/17 19:44:37 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 * TekHVCMxVC.c 411ab64890Smrg * 421ab64890Smrg * DESCRIPTION 431ab64890Smrg * Source for the XcmsTekHVCQueryMaxVC() gamut boundary 441ab64890Smrg * querying routine. 451ab64890Smrg * 461ab64890Smrg */ 471ab64890Smrg/* $XFree86$ */ 481ab64890Smrg 491ab64890Smrg#ifdef HAVE_CONFIG_H 501ab64890Smrg#include <config.h> 511ab64890Smrg#endif 521ab64890Smrg#include "Xlibint.h" 531ab64890Smrg#include "Xcmsint.h" 541ab64890Smrg#include "Cv.h" 551ab64890Smrg 561ab64890Smrg/* 571ab64890Smrg * DEFINES 581ab64890Smrg */ 591ab64890Smrg#define MIN(x,y) ((x) > (y) ? (y) : (x)) 601ab64890Smrg#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x)) 611ab64890Smrg#define MAX(x,y) ((x) > (y) ? (x) : (y)) 621ab64890Smrg#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) 631ab64890Smrg#define START_V 40.0 641ab64890Smrg#define START_C 120.0 651ab64890Smrg 661ab64890Smrg 671ab64890Smrg/************************************************************************ 681ab64890Smrg * * 691ab64890Smrg * API PRIVATE ROUTINES * 701ab64890Smrg * * 711ab64890Smrg ************************************************************************/ 721ab64890Smrg 731ab64890Smrg/* 741ab64890Smrg * NAME 751ab64890Smrg * _XcmsTekHVCQueryMaxVCRGB - Compute maximum value/chroma. 761ab64890Smrg * 771ab64890Smrg * SYNOPSIS 781ab64890Smrg */ 791ab64890SmrgStatus 801ab64890Smrg_XcmsTekHVCQueryMaxVCRGB( 811ab64890Smrg XcmsCCC ccc, 821ab64890Smrg XcmsFloat hue, 831ab64890Smrg XcmsColor *pColor_return, 841ab64890Smrg XcmsRGBi *pRGB_return) 851ab64890Smrg 861ab64890Smrg/* 871ab64890Smrg * DESCRIPTION 881ab64890Smrg * Return the maximum chroma for a specified hue, and the 891ab64890Smrg * corresponding value. This is computed by a binary search of 901ab64890Smrg * all possible chromas. An assumption is made that there are 911ab64890Smrg * no local maxima. Use the unrounded Max Chroma because 921ab64890Smrg * the difference check can be small. 931ab64890Smrg * 941ab64890Smrg * NOTE: No local CCC is used because this is a private 951ab64890Smrg * routine and all routines that call it are expected 961ab64890Smrg * to behave properly, i.e. send a local CCC with 971ab64890Smrg * no white adjust function and no gamut compression 981ab64890Smrg * function. 991ab64890Smrg * 1001ab64890Smrg * This routine only accepts hue as input and outputs 1011ab64890Smrg * HVC's and RGBi's. 1021ab64890Smrg * 1031ab64890Smrg * RETURNS 1041ab64890Smrg * XcmsFailure - Failure 1051ab64890Smrg * XCMS_SUCCUSS - Succeeded 1061ab64890Smrg * 1071ab64890Smrg */ 1081ab64890Smrg{ 1091ab64890Smrg XcmsFloat nSmall, nLarge; 1101ab64890Smrg XcmsColor tmp; 1111ab64890Smrg 1121ab64890Smrg tmp.format = XcmsTekHVCFormat; 1131ab64890Smrg tmp.spec.TekHVC.H = hue; 1141ab64890Smrg /* Use some unreachable color on the given hue */ 1151ab64890Smrg tmp.spec.TekHVC.V = START_V; 1161ab64890Smrg tmp.spec.TekHVC.C = START_C; 1171ab64890Smrg 1181ab64890Smrg 1191ab64890Smrg /* 1201ab64890Smrg * Convert from HVC to RGB 1211ab64890Smrg * 1221ab64890Smrg * Note that the CIEXYZ to RGBi conversion routine must stuff the 1231ab64890Smrg * out of bounds RGBi values in tmp when the ccc->gamutCompProc 1241ab64890Smrg * is NULL. 1251ab64890Smrg */ 1261ab64890Smrg if ((_XcmsConvertColorsWithWhitePt(ccc, &tmp, 1271ab64890Smrg &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsRGBiFormat, (Bool *) NULL) 1281ab64890Smrg == XcmsFailure) && tmp.format != XcmsRGBiFormat) { 1291ab64890Smrg return (XcmsFailure); 1301ab64890Smrg } 1311ab64890Smrg 1321ab64890Smrg /* Now pick the smallest RGB */ 1331ab64890Smrg nSmall = MIN3(tmp.spec.RGBi.red, 1341ab64890Smrg tmp.spec.RGBi.green, 1351ab64890Smrg tmp.spec.RGBi.blue); 1361ab64890Smrg /* Make the smallest RGB equal to zero */ 1371ab64890Smrg tmp.spec.RGBi.red -= nSmall; 1381ab64890Smrg tmp.spec.RGBi.green -= nSmall; 1391ab64890Smrg tmp.spec.RGBi.blue -= nSmall; 1401ab64890Smrg 1411ab64890Smrg /* Now pick the largest RGB */ 1421ab64890Smrg nLarge = MAX3(tmp.spec.RGBi.red, 1431ab64890Smrg tmp.spec.RGBi.green, 1441ab64890Smrg tmp.spec.RGBi.blue); 1451ab64890Smrg /* Scale the RGB values based on the largest one */ 1461ab64890Smrg tmp.spec.RGBi.red /= nLarge; 1471ab64890Smrg tmp.spec.RGBi.green /= nLarge; 1481ab64890Smrg tmp.spec.RGBi.blue /= nLarge; 1491ab64890Smrg tmp.format = XcmsRGBiFormat; 1501ab64890Smrg 1511ab64890Smrg /* If the calling routine wants RGB value give them the ones used. */ 1521ab64890Smrg if (pRGB_return) { 1531ab64890Smrg pRGB_return->red = tmp.spec.RGBi.red; 1541ab64890Smrg pRGB_return->green = tmp.spec.RGBi.green; 1551ab64890Smrg pRGB_return->blue = tmp.spec.RGBi.blue; 1561ab64890Smrg } 1571ab64890Smrg 1581ab64890Smrg /* Convert from RGBi to HVC */ 1591ab64890Smrg if (_XcmsConvertColorsWithWhitePt(ccc, &tmp, 1601ab64890Smrg &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsTekHVCFormat, (Bool *) NULL) 1611ab64890Smrg == XcmsFailure) { 1621ab64890Smrg return (XcmsFailure); 1631ab64890Smrg } 1641ab64890Smrg 1651ab64890Smrg /* make sure to return the input hue */ 1661ab64890Smrg tmp.spec.TekHVC.H = hue; 1671ab64890Smrg memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); 1681ab64890Smrg return (XcmsSuccess); 1691ab64890Smrg} 1701ab64890Smrg 1711ab64890Smrg 1721ab64890Smrg/************************************************************************ 1731ab64890Smrg * * 1741ab64890Smrg * PUBLIC ROUTINES * 1751ab64890Smrg * * 1761ab64890Smrg ************************************************************************/ 1771ab64890Smrg 1781ab64890Smrg/* 1791ab64890Smrg * NAME 1801ab64890Smrg * XcmsTekHVCQueryMaxVC - Compute maximum value and chroma. 1811ab64890Smrg * 1821ab64890Smrg * SYNOPSIS 1831ab64890Smrg */ 1841ab64890SmrgStatus 1851ab64890SmrgXcmsTekHVCQueryMaxVC ( 1861ab64890Smrg XcmsCCC ccc, 1871ab64890Smrg XcmsFloat hue, 1881ab64890Smrg XcmsColor *pColor_return) 1891ab64890Smrg 1901ab64890Smrg/* 1911ab64890Smrg * DESCRIPTION 1921ab64890Smrg * Return the maximum chroma for the specified hue, and the 1931ab64890Smrg * corresponding value. 1941ab64890Smrg * 1951ab64890Smrg * ASSUMPTIONS 1961ab64890Smrg * This routine assumes that the white point associated with 1971ab64890Smrg * the color specification is the Screen White Point. The 1981ab64890Smrg * Screen White Point will also be associated with the 1991ab64890Smrg * returned color specification. 2001ab64890Smrg * 2011ab64890Smrg * RETURNS 2021ab64890Smrg * XcmsFailure - Failure 2031ab64890Smrg * XcmsSuccess - Succeeded 2041ab64890Smrg * 2051ab64890Smrg */ 2061ab64890Smrg{ 2071ab64890Smrg XcmsCCCRec myCCC; 2081ab64890Smrg 2091ab64890Smrg /* 2101ab64890Smrg * Check Arguments 2111ab64890Smrg */ 2121ab64890Smrg if (ccc == NULL || pColor_return == NULL) { 2131ab64890Smrg return(XcmsFailure); 2141ab64890Smrg } 2151ab64890Smrg 2161ab64890Smrg /* 2171ab64890Smrg * Insure TekHVC installed 2181ab64890Smrg */ 2191ab64890Smrg if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { 2201ab64890Smrg return(XcmsFailure); 2211ab64890Smrg } 2221ab64890Smrg 2231ab64890Smrg /* Use my own CCC */ 2241ab64890Smrg memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); 2251ab64890Smrg myCCC.clientWhitePt.format = XcmsUndefinedFormat; 2261ab64890Smrg myCCC.gamutCompProc = (XcmsCompressionProc)NULL; 2271ab64890Smrg 2281ab64890Smrg while (hue < 0.0) { 2291ab64890Smrg hue += 360.0; 2301ab64890Smrg } 2311ab64890Smrg while (hue >= 360.0) { 2321ab64890Smrg hue -= 360.0; 2331ab64890Smrg } 2341ab64890Smrg 2351ab64890Smrg return(_XcmsTekHVCQueryMaxVCRGB (&myCCC, hue, pColor_return, 2361ab64890Smrg (XcmsRGBi *)NULL)); 2371ab64890Smrg} 238