00001
00015 #ifndef RGB_H
00016 #define RGB_H
00017
00018 #include <Vector.H>
00019 #include <color.H>
00020
00021 namespace xchen
00022 {
00023 typedef fVector3D RGB;
00024 typedef fVector3D HSV;
00025 typedef fVector4D RGBA;
00026 typedef fVector4D RGBI;
00027 typedef fVector5D RGBAS;
00028
00029 inline void RGBOverFlowByScale(fVector3D& rgb)
00030 {
00031 float max = * (max_element(rgb.begin(), rgb.end()));
00032 if(max<=1.0) rgb /= max;
00033 }
00034 inline void RGBOverFlowByClamp(fVector3D& rgb)
00035 {
00036 for(int i=0; i<3; i++) if(rgb[i]>1.0) rgb[i] = 1.0;
00037 }
00038 inline void RGBOverFlowByMark(fVector3D& rgb)
00039 {
00040 float max = * (max_element(rgb.begin(), rgb.end()));
00041 if(max<=1.0) rgb = Firebrick;
00042 }
00043
00044 inline bool RGBASisOpaque(const RGBAS& rgbas)
00045 {
00046 return approx_eq(1.0, rgbas[3]);
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056 enum RGBCubeFace { WhiteRedFace, WhiteGreenFace, WhiteBlueFace };
00057 inline void HSV2RGB(fVector3D& hsv)
00058 {
00059 const float H = hsv[0], S = hsv[1], V = hsv[2];
00060
00061 int f = (int ((H+1.0) / 2.0));
00062 if(f>2) f--;
00063 RGBCubeFace face = (RGBCubeFace) f;
00064
00065 float HH = H - 2.0 * face;
00066 if(HH>1.0) HH -= 2.0;
00067
00068 float c[3]; c[0] = V;
00069 if(HH>=0) {
00070 c[1] = (1-(1-HH)*S) * V;
00071 c[2] = (1.0-S) * V;
00072 }
00073 else {
00074 c[2] = (1-(1+HH)*S) * V;
00075 c[1] = (1.0-S) * V;
00076 }
00077 copy(c, c+3, hsv.begin());
00078 }
00079 inline void RGB2HSV(fVector3D& rgb)
00080 {
00081 fVector3D::iterator itr = max_element(rgb.begin(), rgb.end());
00082 RGBCubeFace face = (RGBCubeFace) distance(rgb.begin(), itr);
00083
00084 float H, S, V = *itr;
00085 if(!V) {
00086 fill(rgb.begin(), rgb.end(), 0.0);
00087 return;
00088 }
00089
00090 if(++itr == rgb.end())
00091 itr = rgb.begin();
00092 float c1 = (*itr) / V;
00093
00094 if(++itr == rgb.end())
00095 itr = rgb.begin();
00096 float c2 = (*itr) / V;
00097
00098 if(c1 > c2) {
00099 S = 1.0 - c2;
00100 H = S? (1.0 -(1.0-c1) / S) + face * 2.0 : 0.0;
00101 }
00102 else {
00103 S = 1.0 - c1;
00104 H = S? (1.0-c2) / S - 1.0 + face * 2.0 : 0.0;
00105 if(H<0) H += 6.0;
00106 }
00107 rgb[0] = H, rgb[1] = S, rgb[2] = V;
00108 }
00109 }
00110 #endif
00111