HVCMxVC.c revision 1ab64890
1/* $Xorg: HVCMxVC.c,v 1.3 2000/08/17 19:44:37 cpqbld Exp $ */ 2 3/* 4 * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc. 5 * All Rights Reserved 6 * 7 * This file is a component of an X Window System-specific implementation 8 * of Xcms based on the TekColor Color Management System. TekColor is a 9 * trademark of Tektronix, Inc. The term "TekHVC" designates a particular 10 * color space that is the subject of U.S. Patent No. 4,985,853 (equivalent 11 * foreign patents pending). Permission is hereby granted to use, copy, 12 * modify, sell, and otherwise distribute this software and its 13 * documentation for any purpose and without fee, provided that: 14 * 15 * 1. This copyright, permission, and disclaimer notice is reproduced in 16 * all copies of this software and any modification thereof and in 17 * supporting documentation; 18 * 2. Any color-handling application which displays TekHVC color 19 * cooordinates identifies these as TekHVC color coordinates in any 20 * interface that displays these coordinates and in any associated 21 * documentation; 22 * 3. The term "TekHVC" is always used, and is only used, in association 23 * with the mathematical derivations of the TekHVC Color Space, 24 * including those provided in this file and any equivalent pathways and 25 * mathematical derivations, regardless of digital (e.g., floating point 26 * or integer) representation. 27 * 28 * Tektronix makes no representation about the suitability of this software 29 * for any purpose. It is provided "as is" and with all faults. 30 * 31 * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE, 32 * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 33 * PARTICULAR PURPOSE. IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY 34 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 35 * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF 36 * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 37 * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE. 38 * 39 * NAME 40 * TekHVCMxVC.c 41 * 42 * DESCRIPTION 43 * Source for the XcmsTekHVCQueryMaxVC() gamut boundary 44 * querying routine. 45 * 46 */ 47/* $XFree86$ */ 48 49#ifdef HAVE_CONFIG_H 50#include <config.h> 51#endif 52#include "Xlibint.h" 53#include "Xcmsint.h" 54#include "Cv.h" 55 56/* 57 * DEFINES 58 */ 59#define MIN(x,y) ((x) > (y) ? (y) : (x)) 60#define MIN3(x,y,z) ((x) > (MIN((y), (z))) ? (MIN((y), (z))) : (x)) 61#define MAX(x,y) ((x) > (y) ? (x) : (y)) 62#define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) 63#define START_V 40.0 64#define START_C 120.0 65 66 67/************************************************************************ 68 * * 69 * API PRIVATE ROUTINES * 70 * * 71 ************************************************************************/ 72 73/* 74 * NAME 75 * _XcmsTekHVCQueryMaxVCRGB - Compute maximum value/chroma. 76 * 77 * SYNOPSIS 78 */ 79Status 80_XcmsTekHVCQueryMaxVCRGB( 81 XcmsCCC ccc, 82 XcmsFloat hue, 83 XcmsColor *pColor_return, 84 XcmsRGBi *pRGB_return) 85 86/* 87 * DESCRIPTION 88 * Return the maximum chroma for a specified hue, and the 89 * corresponding value. This is computed by a binary search of 90 * all possible chromas. An assumption is made that there are 91 * no local maxima. Use the unrounded Max Chroma because 92 * the difference check can be small. 93 * 94 * NOTE: No local CCC is used because this is a private 95 * routine and all routines that call it are expected 96 * to behave properly, i.e. send a local CCC with 97 * no white adjust function and no gamut compression 98 * function. 99 * 100 * This routine only accepts hue as input and outputs 101 * HVC's and RGBi's. 102 * 103 * RETURNS 104 * XcmsFailure - Failure 105 * XCMS_SUCCUSS - Succeeded 106 * 107 */ 108{ 109 XcmsFloat nSmall, nLarge; 110 XcmsColor tmp; 111 112 tmp.format = XcmsTekHVCFormat; 113 tmp.spec.TekHVC.H = hue; 114 /* Use some unreachable color on the given hue */ 115 tmp.spec.TekHVC.V = START_V; 116 tmp.spec.TekHVC.C = START_C; 117 118 119 /* 120 * Convert from HVC to RGB 121 * 122 * Note that the CIEXYZ to RGBi conversion routine must stuff the 123 * out of bounds RGBi values in tmp when the ccc->gamutCompProc 124 * is NULL. 125 */ 126 if ((_XcmsConvertColorsWithWhitePt(ccc, &tmp, 127 &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsRGBiFormat, (Bool *) NULL) 128 == XcmsFailure) && tmp.format != XcmsRGBiFormat) { 129 return (XcmsFailure); 130 } 131 132 /* Now pick the smallest RGB */ 133 nSmall = MIN3(tmp.spec.RGBi.red, 134 tmp.spec.RGBi.green, 135 tmp.spec.RGBi.blue); 136 /* Make the smallest RGB equal to zero */ 137 tmp.spec.RGBi.red -= nSmall; 138 tmp.spec.RGBi.green -= nSmall; 139 tmp.spec.RGBi.blue -= nSmall; 140 141 /* Now pick the largest RGB */ 142 nLarge = MAX3(tmp.spec.RGBi.red, 143 tmp.spec.RGBi.green, 144 tmp.spec.RGBi.blue); 145 /* Scale the RGB values based on the largest one */ 146 tmp.spec.RGBi.red /= nLarge; 147 tmp.spec.RGBi.green /= nLarge; 148 tmp.spec.RGBi.blue /= nLarge; 149 tmp.format = XcmsRGBiFormat; 150 151 /* If the calling routine wants RGB value give them the ones used. */ 152 if (pRGB_return) { 153 pRGB_return->red = tmp.spec.RGBi.red; 154 pRGB_return->green = tmp.spec.RGBi.green; 155 pRGB_return->blue = tmp.spec.RGBi.blue; 156 } 157 158 /* Convert from RGBi to HVC */ 159 if (_XcmsConvertColorsWithWhitePt(ccc, &tmp, 160 &ccc->pPerScrnInfo->screenWhitePt, 1, XcmsTekHVCFormat, (Bool *) NULL) 161 == XcmsFailure) { 162 return (XcmsFailure); 163 } 164 165 /* make sure to return the input hue */ 166 tmp.spec.TekHVC.H = hue; 167 memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); 168 return (XcmsSuccess); 169} 170 171 172/************************************************************************ 173 * * 174 * PUBLIC ROUTINES * 175 * * 176 ************************************************************************/ 177 178/* 179 * NAME 180 * XcmsTekHVCQueryMaxVC - Compute maximum value and chroma. 181 * 182 * SYNOPSIS 183 */ 184Status 185XcmsTekHVCQueryMaxVC ( 186 XcmsCCC ccc, 187 XcmsFloat hue, 188 XcmsColor *pColor_return) 189 190/* 191 * DESCRIPTION 192 * Return the maximum chroma for the specified hue, and the 193 * corresponding value. 194 * 195 * ASSUMPTIONS 196 * This routine assumes that the white point associated with 197 * the color specification is the Screen White Point. The 198 * Screen White Point will also be associated with the 199 * returned color specification. 200 * 201 * RETURNS 202 * XcmsFailure - Failure 203 * XcmsSuccess - Succeeded 204 * 205 */ 206{ 207 XcmsCCCRec myCCC; 208 209 /* 210 * Check Arguments 211 */ 212 if (ccc == NULL || pColor_return == NULL) { 213 return(XcmsFailure); 214 } 215 216 /* 217 * Insure TekHVC installed 218 */ 219 if (XcmsAddColorSpace(&XcmsTekHVCColorSpace) == XcmsFailure) { 220 return(XcmsFailure); 221 } 222 223 /* Use my own CCC */ 224 memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); 225 myCCC.clientWhitePt.format = XcmsUndefinedFormat; 226 myCCC.gamutCompProc = (XcmsCompressionProc)NULL; 227 228 while (hue < 0.0) { 229 hue += 360.0; 230 } 231 while (hue >= 360.0) { 232 hue -= 360.0; 233 } 234 235 return(_XcmsTekHVCQueryMaxVCRGB (&myCCC, hue, pColor_return, 236 (XcmsRGBi *)NULL)); 237} 238