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

Colour.cc

Go to the documentation of this file.
00001 /*
00002     File:           Colour.cc
00003 
00004     Function:       Implements Colour.h
00005 
00006     Author(s):      Andrew Willmott
00007 
00008     Copyright:      (c) 1995-2000, Andrew Willmott
00009 
00010     Notes:          Useful info on colour (Gamma & Colour FAQs):                    
00011                         http://www.inforamp.net/~poynton/notes/colour_and_gamma
00012                     Useful info on colour transforms:
00013                         http://www.sgi.com/grafica/matrix/index.html
00014                         http://www.sgi.com/grafica/interp/index.html
00015 */
00016 
00017 #include "gcl/Colour.h"
00018 #include "gcl/Geometry.h"
00019 
00032 Colour &ClipColour(Colour &c)
00033 {
00034     if (c[0] > 1.0) c[0] = 1.0;
00035     if (c[0] < 0.0) c[0] = 0.0;
00036     if (c[1] > 1.0) c[1] = 1.0;
00037     if (c[1] < 0.0) c[1] = 0.0;
00038     if (c[2] > 1.0) c[2] = 1.0;
00039     if (c[2] < 0.0) c[2] = 0.0;
00040 
00041     return(c);
00042 }
00043 
00044 Colour &ClipColourZero(Colour &c)
00045 {
00046     if (c[0] < 0.0) c[0] = 0.0;
00047     if (c[1] < 0.0) c[1] = 0.0;
00048     if (c[2] < 0.0) c[2] = 0.0;
00049 
00050     return(c);
00051 }
00052 
00053 Colour HSVCol(ClrReal hue, ClrReal saturation, ClrReal value)
00054 // Convert HSV to RGB...
00055 {
00056     hue =       hue - 360 * floor(hue / 360);
00057     Int         face = (Int) floor(hue / 120);
00058     ClrReal     d = (hue - 120 * face) / 60;
00059     Colour      result;
00060 
00061     if (face == 3)
00062         face--;
00063     
00064     result[face] = value;
00065     
00066     if (d > 1)
00067     {
00068         result[(face + 1) % 3] = value * (1 - saturation * (2 - d));
00069         result[(face + 2) % 3] = value * (1 - saturation);
00070     }
00071     else
00072     {
00073         result[(face + 1) % 3] = value * (1 - saturation);
00074         result[(face + 2) % 3] = value * (1 - saturation * d);
00075     }
00076 
00077     return(result);
00078 }
00079 
00080 // --- Colour transformations ----------------
00081 
00082 ClrTrans RGBScale(ClrReal rscale, ClrReal gscale, ClrReal bscale)
00083 {
00084     return(HScale4f(Colour(rscale, gscale, bscale)));
00085 }
00086 
00087 ClrTrans RGBToLum()
00088 {
00089     ClrTrans result;
00090     
00091     result[0] = Vec4f(cRGBToLum, 0.0);
00092     result[1] = Vec4f(cRGBToLum, 0.0);
00093     result[2] = Vec4f(cRGBToLum, 0.0);
00094     result[3] = vl_w;
00095     
00096     return(result);
00097 }
00098 
00099 ClrTrans RGBSaturate(ClrReal sat)
00100 {
00101     // saturate by interpolating with greyscale pixel
00102     return(Mix(RGBToLum(), ClrTrans(vl_I), sat));
00103 }
00104 
00105 ClrTrans RGBReplace(const Colour &c)
00106 // replace with colour c
00107 {
00108     ClrTrans result = vl_0;
00109 
00110     result[0][3] = c[0];
00111     result[1][3] = c[1];
00112     result[2][3] = c[2];
00113     result[3][3] = 1.0;
00114 
00115     return(result);
00116 }
00117 
00118 ClrTrans RGBPixelMix(ClrReal mix, const Colour &c)
00119 // If you use c = cBlack, mix < 1.0 will darken the image,
00120 // and mix > 1.0 will lighten it.
00121 // If you use the average colour of an image, c = img.AverageColour(),
00122 // mix < 1.0 will lower contrast, mix > 1.0 raise it.
00123 {
00124     return(Mix(RGBReplace(c), ClrTrans(vl_I), mix));
00125 }
00126 
00127 ClrTrans RGBOffset(const Colour &c)
00128 {
00129     return(HTrans4f(c));
00130 }
00131 
00132 ClrTrans RGBHueRotate(ClrReal degrees)
00133 {
00134     ClrTrans    trans, shear;
00135     Colour      newLum;
00136     
00137     // align grey vector with z axis (vl_z)
00138     trans = HRot4f(norm(Colour(1, -1, 0)), DegsToRads(45));
00139 
00140     // what is the luminance vector in the new space?
00141     newLum = xform(trans, cRGBToLum);
00142     // shear so plane parallel to this vector is now horizontal (x-y)
00143     // if dot(x, newLum) = c, (shear * x)[2] * newLum[2] = c,
00144     // i.e. is constant
00145     shear = vl_I;
00146     shear[2][0] = newLum[0] / newLum[2];
00147     shear[2][1] = newLum[1] / newLum[2];
00148     trans = xform(trans, shear);
00149 
00150     // rotate the hue!
00151     trans = xform(trans, HRot4f(vl_z, DegsToRads(degrees))); 
00152 
00153     // unshear
00154     shear[2][0] = -shear[2][0];
00155     shear[2][1] = -shear[2][1];
00156     trans = xform(trans, shear);
00157     // unrotate
00158     trans = xform(trans, HRot4f(norm(Colour(1, -1, 0)), DegsToRads(-45)));
00159 
00160     return(trans);
00161 }
00162 
00163 Colour YUVToRGB(const Colour &yuv)
00164 {
00165     Colour  rgb;
00166 
00167     rgb[0] = yuv[0] + 1.4075 * (yuv[2] - 0.5);
00168     rgb[1] = yuv[0] - 0.3455 * (yuv[1] - 0.5) - 0.7169 * (yuv[2] - 0.5);
00169     rgb[2] = yuv[0] + 1.7790 * (yuv[1] - 0.5);
00170 
00171     return(rgb);
00172 }
00173 
00174 Colour RGBToYUV(const Colour &rgb)
00175 {
00176     Colour  yuv;
00177 
00178     yuv[0] = rgb[0] *   0.299 + rgb[1] *   0.587 + rgb[2] *  0.114;
00179     yuv[1] = rgb[0] * -0.1687 + rgb[1] * -0.3313 + rgb[2] *  0.500 + 0.5;
00180     yuv[2] = rgb[0] *   0.500 + rgb[1] * -0.4187 + rgb[2] * -0.0813 + 0.5;
00181 
00182     return(yuv);
00183 }
00184 
00185 #ifdef CL_TMPL_INST
00186 template class Array<Colour>;
00187 #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