00001
00002
00003
00004 #ifndef CHARLS_COLORTRANSFORM
00005 #define CHARLS_COLORTRANSFORM
00006
00007
00008
00009
00010
00011
00012
00013 template<class sample>
00014 struct TransformNoneImpl
00015 {
00016 typedef sample SAMPLE;
00017
00018 inlinehint Triplet<SAMPLE> operator() (int v1, int v2, int v3)
00019 { return Triplet<SAMPLE>(v1, v2, v3); }
00020 };
00021
00022
00023 template<class sample>
00024 struct TransformNone : public TransformNoneImpl<sample>
00025 {
00026 typedef struct TransformNoneImpl<sample> INVERSE;
00027 };
00028
00029
00030
00031 template<class sample>
00032 struct TransformHp1
00033 {
00034 enum { RANGE = 1 << sizeof(sample)*8 };
00035 typedef sample SAMPLE;
00036
00037 struct INVERSE
00038 {
00039 INVERSE(const TransformHp1&) {};
00040
00041 inlinehint Triplet<SAMPLE> operator() (int v1, int v2, int v3)
00042 { return Triplet<SAMPLE>(v1 + v2 - RANGE/2, v2, v3 + v2 - RANGE/2); }
00043 };
00044
00045 inlinehint Triplet<SAMPLE> operator() (int R, int G, int B)
00046 {
00047 Triplet<SAMPLE> hp1;
00048 hp1.v2 = SAMPLE(G);
00049 hp1.v1 = SAMPLE(R - G + RANGE/2);
00050 hp1.v3 = SAMPLE(B - G + RANGE/2);
00051 return hp1;
00052 }
00053 };
00054
00055
00056
00057
00058
00059 template<class sample>
00060 struct TransformHp2
00061 {
00062 enum { RANGE = 1 << sizeof(sample)*8 };
00063 typedef sample SAMPLE;
00064
00065 struct INVERSE
00066 {
00067 INVERSE(const TransformHp2&) {};
00068
00069 inlinehint Triplet<SAMPLE> operator() (int v1, int v2, int v3)
00070 {
00071 Triplet<SAMPLE> rgb;
00072 rgb.R = SAMPLE(v1 + v2 - RANGE/2);
00073 rgb.G = SAMPLE(v2);
00074 rgb.B = SAMPLE(v3 + ((rgb.R + rgb.G) >> 1) - RANGE/2);
00075 return rgb;
00076 }
00077 };
00078
00079 inlinehint Triplet<SAMPLE> operator() (int R, int G, int B)
00080 {
00081 return Triplet<SAMPLE>(R - G + RANGE/2, G, B - ((R+G )>>1) - RANGE/2);
00082 }
00083
00084
00085 };
00086
00087
00088
00089 template<class sample>
00090 struct TransformHp3
00091 {
00092 enum { RANGE = 1 << sizeof(sample)*8 };
00093 typedef sample SAMPLE;
00094
00095 struct INVERSE
00096 {
00097 INVERSE(const TransformHp3&) {};
00098
00099 inlinehint Triplet<SAMPLE> operator() (int v1, int v2, int v3)
00100 {
00101 int G = v1 - ((v3 + v2)>>2) + RANGE/4;
00102 Triplet<SAMPLE> rgb;
00103 rgb.R = SAMPLE(v3 + G - RANGE/2);
00104 rgb.G = SAMPLE(G);
00105 rgb.B = SAMPLE(v2 + G - RANGE/2);
00106 return rgb;
00107 }
00108 };
00109
00110 inlinehint Triplet<SAMPLE> operator() (int R, int G, int B)
00111 {
00112 Triplet<SAMPLE> hp3;
00113 hp3.v2 = SAMPLE(B - G + RANGE/2);
00114 hp3.v3 = SAMPLE(R - G + RANGE/2);
00115 hp3.v1 = SAMPLE(G + ((hp3.v2 + hp3.v3)>>2)) - RANGE/4;
00116 return hp3;
00117 }
00118 };
00119
00120
00121
00122
00123
00124 template<class TRANSFORM>
00125 struct TransformShifted
00126 {
00127 typedef typename TRANSFORM::SAMPLE SAMPLE;
00128
00129 struct INVERSE
00130 {
00131 INVERSE(const TransformShifted& transform) :
00132 _shift(transform._shift),
00133 _inverseTransform(transform._colortransform)
00134 {}
00135
00136 inlinehint Triplet<SAMPLE> operator() (int v1, int v2, int v3)
00137 {
00138 Triplet<SAMPLE> result = _inverseTransform(v1 << _shift, v2 << _shift, v3 << _shift);
00139
00140 return Triplet<SAMPLE>(result.R >> _shift, result.G >> _shift, result.B >> _shift);
00141 }
00142
00143 inlinehint Quad<SAMPLE> operator() (int v1, int v2, int v3, int v4)
00144 {
00145 Triplet<SAMPLE> result = _inverseTransform(v1 << _shift, v2 << _shift, v3 << _shift);
00146
00147 return Quad<SAMPLE>(result.R >> _shift, result.G >> _shift, result.B >> _shift, v4);
00148 }
00149
00150 int _shift;
00151 typename TRANSFORM::INVERSE _inverseTransform;
00152 };
00153
00154
00155 TransformShifted(int shift) :
00156 _shift(shift)
00157 {
00158 }
00159
00160 inlinehint Triplet<SAMPLE> operator() (int R, int G, int B)
00161 {
00162 Triplet<SAMPLE> result = _colortransform(R << _shift, G << _shift, B << _shift);
00163
00164 return Triplet<SAMPLE>(result.R >> _shift, result.G >> _shift, result.B >> _shift);
00165 }
00166
00167 inlinehint Quad<SAMPLE> operator() (int R, int G, int B, int A)
00168 {
00169 Triplet<SAMPLE> result = _colortransform(R << _shift, G << _shift, B << _shift);
00170
00171 return Quad<SAMPLE>(result.R >> _shift, result.G >> _shift, result.B >> _shift, A);
00172 }
00173
00174 int _shift;
00175 TRANSFORM _colortransform;
00176 };
00177
00178
00179
00180 #endif