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