dcmjpls/libcharls/clrtrans.h

00001 //
00002 // (C) Jan de Vaan 2007-2010, all rights reserved. See the accompanying "License.txt" for licensed use.
00003 //
00004 #ifndef CHARLS_COLORTRANSFORM
00005 #define CHARLS_COLORTRANSFORM
00006 
00007 //
00008 // This file defines simple classes that define (lossless) color transforms.
00009 // They are invoked in processline.h to convert between decoded values and the internal line buffers.
00010 // Color transforms work best for computer generated images.
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);          // new R
00073             rgb.G  = SAMPLE(v2);                     // new G
00074             rgb.B  = SAMPLE(v3 + ((rgb.R + rgb.G) >> 1) - RANGE/2); // new B
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); // new R
00104             rgb.G  = SAMPLE(G);             // new G
00105             rgb.B  = SAMPLE(v2 + G - RANGE/2); // new B
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 // Transform class that shifts bits towards the high bit when bitcount is not 8 or 16
00122 // needed to make the HP color transforms work correctly.
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


Generated on 6 Jan 2011 for OFFIS DCMTK Version 3.6.0 by Doxygen 1.5.1