Main Page Class Hierarchy Compound List File List Compound Members File Members

ColourSystem.cc

Go to the documentation of this file.
00001 /*
00002 File: ColourSystem.cc
00003 
00004 Function: Provides a class to help with colour space conversions to
00005 and from three-primary display devices.
00006 
00007 Author: Andrew Willmott
00008 
00009 */
00010 
00011 #include "ColourSystem.h"
00012 
00074  ColourSystem::ColourSystem(
00075 Chroma primary1,
00076 Chroma primary2,
00077 Chroma primary3,
00078 Chroma whitePoint,
00079 ClrReal whiteLuminance
00080 )
00081 {
00082 Colour whiteXYZ, csWhite;
00083 
00084 prim0 = primary1;
00085 prim1 = primary2; 
00086 prim2 = primary3;
00087 white = whitePoint;
00088 whiteLum = whiteLuminance;
00089 
00090 toXYZ[0] = Colour(prim0[0], prim1[0], prim2[0]);
00091 toXYZ[1] = Colour(prim0[1], prim1[1], prim2[1]);
00092 toXYZ[2] = cWhite - toXYZ[0] - toXYZ[1];
00093 
00094 fromXYZ = inv(toXYZ);
00095 
00096 // now we must scale so that the white point
00097 // maps to the cs colour [1, 1, 1].
00098 
00099 whiteXYZ = Colour(white[0], white[1], 1.0 - white[0] - white[1]);
00100 whiteXYZ *= whiteLum / white[1];
00101 
00102 csWhite = fromXYZ * whiteXYZ;
00103 
00104 fromXYZ[0] /= csWhite[0];
00105 fromXYZ[1] /= csWhite[1];
00106 fromXYZ[2] /= csWhite[2];
00107 col(toXYZ, 0) *= csWhite[0];
00108 col(toXYZ, 1) *= csWhite[1];
00109 col(toXYZ, 2) *= csWhite[2]; 
00110 }
00111 
00112  Colour ColourSystem::XYZToGamut(const Colour &cieXYZ)
00120 {
00121 Colour csClr = fromXYZ * cieXYZ;
00122 Colour t;
00123 ClrReal tMin;
00124 
00125 // Is the contribution of one of the primaries negative?
00126 
00127 if (MinCmpt(csClr) < 0.0)
00128 {
00129 // find how far we must move along the line through the white
00130 // point until we hit each axial plane
00131 t = cWhite / (cWhite - csClr);
00132 
00133 // find smallest +ve intercept
00134 tMin = 1.0;
00135 if (t[0] >= 0.0) tMin = t[0];
00136 if (t[1] >= 0.0 && t[1] < tMin) tMin = t[1];
00137 if (t[2] >= 0.0 && t[2] < tMin) tMin = t[2];
00138 
00139 csClr = cWhite + (csClr - cWhite) * tMin;
00140 ClipColourZero(csClr);
00141 Assert(MinCmpt(csClr) >= 0.0, "bad correction");
00142 }
00143 
00144 return(csClr);
00145 }
00146 
00147  Colour ColourSystem::XYZToGamutClip(const Colour &cieXYZ)
00148 {
00149 Colour c = XYZToGamut(cieXYZ);
00150 
00151 if (c[0] > 1.0) c[0] = 1.0;
00152 if (c[1] > 1.0) c[1] = 1.0;
00153 if (c[2] > 1.0) c[2] = 1.0;
00154 
00155 return(c); 
00156 }
00157 
00158  Colour ColourSystem::ChromaToGamut(const Chroma &cieChroma)
00159 {
00160 Colour c;
00161 
00162 c = XYZToGamut(Colour(cieChroma, 1.0 - cieChroma[0] - cieChroma[1]));
00163 c /= cieChroma[1];
00164 
00165 return(c);
00166 }
00167 
00168  Bool ColourSystem::XYZIsOutOfGamut(const Colour &cieXYZ)
00169 {
00170 return(MinCmpt(fromXYZ * cieXYZ) < 0.0);
00171 }
00172 
00173  Bool ColourSystem::ChromaIsOutOfGamut(const Chroma &cieChroma)
00174 {
00175 return(MinCmpt(fromXYZ * Colour(cieChroma, 1.0 - cieChroma[0] - cieChroma[1]))
00176 < 0.0);
00177 }
00178 
00179 // --- CIE standard illuminants ---------------------------------------
00180 
00181 const Chroma csIllumA(0.448, 0.407); // Incandescent light
00182 const Chroma csIllumB(0.348, 0.352); // Solar light
00183 const Chroma csIllumC(0.3101, 0.3162); // For NTSC television
00184 const Chroma csIllumD55(0.332, 0.348); // Photography
00185 const Chroma csIllumD65(0.3127, 0.3291); // Overcast Daylight
00186 const Chroma csIllumD75(0.299, 0.315);
00187 const Chroma csIllumE(0.3333333, 0.3333333); // Uniform illuminant
00188 
00189 // luminances of standard illuminants, in candela/watt
00190 
00191 const ClrReal csMaxLum(683.0); // defined maximum at 555 nm 
00192 const ClrReal csWhiteLum(179.0); // uniform white light
00193 const ClrReal csD65Lum(203.0);
00194 const ClrReal csALum(160.0);
00195 const ClrReal csBLum(208.0);
00196 
00197 
00198 // NOTE: most of this data is simply reformatted from the delphi
00199 // source code provided by EFG's fabulous CIE page above.
00200 
00201 // The following define the x and y coordinates of the phosphors and
00202 // reference white points of various broadcast systems.
00203 
00204 // [Martindale91] notes that NTSC primaries aren't remotely similar
00205 // to those used in modern displays.
00206 //
00207 // CCIR Report 476-1
00208 // "Colorimetric Standards in Colour Television"
00209 // See http://www.igd.fhg.de/icib/tv/ccir/rep_476-1/gen.html
00210 //
00211 // CCIR Report 624-4
00212 // "Characteristics of Television Systems"
00213 // See http://www.igd.fhg.de/icib/tv/ccir/rep_624/read.html
00214 
00215 ColourSystem csNTSC(
00216 Chroma(0.67, 0.33),
00217 Chroma(0.21, 0.71),
00218 Chroma(0.14, 0.08),
00219 Chroma(0.310, 0.316)
00220 );
00221 
00222 // CCIR Report 476-1
00223 // "Colorimetric Standards in Colour Television"
00224 // See http://www.igd.fhg.de/icib/tv/ccir/rep_476-1/gen.html
00225 //
00226 // CCIR Report 624-4
00227 // "Characteristics of Television Systems"
00228 // See http://www.igd.fhg.de/icib/tv/ccir/rep_624/read.html
00229 
00230 ColourSystem csPAL_SECAM(
00231 Chroma(0.64, 0.33),
00232 Chroma(0.29, 0.60),
00233 Chroma(0.15, 0.06),
00234 Chroma(0.313, 0.329)
00235 );
00236 
00237 // CCIR Recommendation 709
00238 // "Basic Parameter Values for the HDTV Standard for the Studio and for
00239 // International Programme Exchange"
00240 // See http://www.igd.fhg.de/icib/tv/ccir/rec_709/pictures/page-2.tiff
00241 
00242 // EBU Technical Document 3271 (EBU = European Broadcasting Union)
00243 // "Interlaced version of the 1250/50 HDTV production standard"
00244 // http://www.igd.fhg.de/icib/tv/org/ebu/td_3271/pictures/page5.tiff
00245 
00246 // This is used for all HDTV stuff.
00247 
00248 ColourSystem csEBU(
00249 Chroma(0.640, 0.330),
00250 Chroma(0.300, 0.600),
00251 Chroma(0.150, 0.060),
00252 Chroma(0.3127, 0.3290)
00253 );
00254 
00255 // SMPTE 240M (SMPTE = The Society of Motion Picture and Television Engineers)
00256 // "Signal Parameters -- 1125-line High-Definition Production System"
00257 // http://www.igd.fhg.de/icib/tv/org/smpte/st_240M-1992/read.html
00258 
00259 ColourSystem csSMPTE(
00260 Chroma(0.630, 0.340),
00261 Chroma(0.310, 0.595),
00262 Chroma(0.155, 0.070),
00263 csIllumD65
00264 );
00265 
00266 
00267 ColourSystem csShortPersistencePhosphors( // [Foley96, p. 583]
00268 Chroma(0.61, 0.35),
00269 Chroma(0.29, 0.59),
00270 Chroma(0.15, 0.063),
00271 csIllumC
00272 );
00273 
00274 ColourSystem csLongPersistencePhosphors( // [Foley96, p. 583]
00275 Chroma(0.62, 0.33),
00276 Chroma(0.21, 0.685),
00277 Chroma(0.15, 0.063),
00278 csIllumC
00279 );
00280 
00281 ColourSystem csDellPhosphors( // 12 Jan 99 E-mail from Dell
00282 Chroma(0.625, 0.340), // All Dell monitors except
00283 Chroma(0.275, 0.605), // Nokia 91862
00284 Chroma(0.150, 0.065),
00285 csIllumD65
00286 );
00287 
00288 #ifdef UNFINISHED
00289 Sony Trinitron
00290 Red 0.621 0.340 
00291 Green 0.281 0.606 
00292 Blue 0.152 0.067 
00293 
00294 Hitachi CM2198 (all +- 0.02):
00295 
00296 Red 0.624 0.339 
00297 Green 0.285 0.604 
00298 Blue 0.150 0.065
00299 
00300 #endif
00301 
00302  ColourSystem &csDisplay = csEBU;
00303 
00304 #ifdef UNFINISHED
00305 ClrReal CIELumToLightness(ClrReal lum)
00306 { 
00307 float relative_luminance;
00308 
00309 if (reference_luminance == 0.)
00310 return 0.;
00311 
00312 relative_luminance = luminance / reference_luminance;
00313 if (relative_luminance > 0.008856)
00314 return (1.16 * pow(relative_luminance, 0.33) - 0.16);
00315 else
00316 return 9.033 * relative_luminance;
00317 }
00318 #endif

Generated at Sat Aug 5 00:16:58 2000 for Graphics Class Library by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000

AltStyle によって変換されたページ (->オリジナル) /