Logo Search packages:      
Sourcecode: gdcm version File versions  Download package

colortransform.h

// 
// (C) Jan de Vaan 2007-2009, all rights reserved. See the accompanying "License.txt" for licensed use. 
// 
#ifndef CHARLS_COLORTRANSFORM
#define CHARLS_COLORTRANSFORM

//
// This file defines simple classes that define (lossless) color transforms.
// They are invoked in processline.h to convert between decoded values and the internal line buffers. 
// Color transforms work best for computer generated images. 
//

template<class sample>
struct TransformNoneImpl
{
      typedef sample SAMPLE;

      inlinehint Triplet<SAMPLE> operator() (int v1, int v2, int v3)
      { return Triplet<SAMPLE>(v1, v2, v3); }
};


template<class sample>
struct TransformNone : public TransformNoneImpl<sample>
{
      typedef struct TransformNoneImpl<sample> INVERSE;
};



template<class sample>
struct TransformHp1
{
      enum { RANGE = 1 << sizeof(sample)*8 };
      typedef sample SAMPLE;

      struct INVERSE
      {
            INVERSE(const TransformHp1&) {};

            inlinehint Triplet<SAMPLE> operator() (int v1, int v2, int v3)
            { return Triplet<SAMPLE>(v1 + v2 - RANGE/2, v2, v3 + v2 - RANGE/2); }
      };

      inlinehint Triplet<SAMPLE> operator() (int R, int G, int B)
      {
            Triplet<SAMPLE> hp1;
            hp1.v2 = SAMPLE(G);
            hp1.v1 = SAMPLE(R - G + RANGE/2);
            hp1.v3 = SAMPLE(B - G + RANGE/2);
            return hp1;
      }
};





template<class sample>
struct TransformHp2
{
      enum { RANGE = 1 << sizeof(sample)*8 };
      typedef sample SAMPLE;

      struct INVERSE
      {
            INVERSE(const TransformHp2&) {};

            inlinehint   Triplet<SAMPLE> operator() (int v1, int v2, int v3)
            {
                  Triplet<SAMPLE> rgb;
                  rgb.R  = SAMPLE(v1 + v2 - RANGE/2);          // new R
                  rgb.G  = SAMPLE(v2);                     // new G                       
                  rgb.B  = SAMPLE(v3 + ((rgb.R + rgb.G) >> 1) - RANGE/2); // new B
                  return rgb;
            }
      };

      inlinehint Triplet<SAMPLE> operator() (int R, int G, int B)
      {
            return Triplet<SAMPLE>(R - G + RANGE/2, G, B - ((R+G )>>1) - RANGE/2);
      }


};



template<class sample>
struct TransformHp3
{
      enum { RANGE = 1 << sizeof(sample)*8 };
      typedef sample SAMPLE;

      struct INVERSE
      {
            INVERSE(const TransformHp3&) {};

            inlinehint Triplet<SAMPLE> operator() (int v1, int v2, int v3)
            {
                  int G = v1 - ((v3 + v2)>>2) + RANGE/4;
                  Triplet<SAMPLE> rgb;
                  rgb.R  = SAMPLE(v3 + G - RANGE/2); // new R
                  rgb.G  = SAMPLE(G);             // new G                    
                  rgb.B  = SAMPLE(v2 + G - RANGE/2); // new B
                  return rgb;
            }
      };

      inlinehint Triplet<SAMPLE> operator() (int R, int G, int B)
      {
            Triplet<SAMPLE> hp3;          
            hp3.v2 = SAMPLE(B - G + RANGE/2);
            hp3.v3 = SAMPLE(R - G + RANGE/2);
            hp3.v1 = SAMPLE(G + ((hp3.v2 + hp3.v3)>>2)) - RANGE/4;
            return hp3;
      }
};


// Transform class that shifts bits towards the high bit when bitcount is not 8 or 16
// needed to make the HP color transforms work correctly.

template<class TRANSFORM>
struct TransformShifted
{     
      typedef typename TRANSFORM::SAMPLE SAMPLE;

      struct INVERSE
      {
            INVERSE(const TransformShifted& transform) : 
                  _shift(transform._shift),
                  _inverseTransform(transform._colortransform)
            {}

            inlinehint Triplet<SAMPLE> operator() (int v1, int v2, int v3)
            {
                  Triplet<SAMPLE> result = _inverseTransform(v1 << _shift, v2 << _shift, v3 << _shift);
                  
                  return Triplet<SAMPLE>(result.R >> _shift, result.G >> _shift, result.B >> _shift);
            }

            inlinehint Quad<SAMPLE> operator() (int v1, int v2, int v3, int v4)
            {
                  Triplet<SAMPLE> result = _inverseTransform(v1 << _shift, v2 << _shift, v3 << _shift);
                  
                  return Quad<SAMPLE>(result.R >> _shift, result.G >> _shift, result.B >> _shift, v4);
            }

            int _shift;
            typename TRANSFORM::INVERSE _inverseTransform;
      };
      
      TransformShifted(const TransformShifted& transform) :
            _shift(transform._shift),
            _colortransform(transform._colortransform)
      {
      }

      TransformShifted(int shift) :
             _shift(shift)
      {
      }

      inlinehint Triplet<SAMPLE> operator() (int R, int G, int B)
      {
            Triplet<SAMPLE> result = _colortransform(R << _shift, G << _shift, B << _shift);

            return Triplet<SAMPLE>(result.R >> _shift, result.G >> _shift, result.B >> _shift);
      }

      inlinehint Quad<SAMPLE> operator() (int R, int G, int B, int A)
      {
            Triplet<SAMPLE> result = _colortransform(R << _shift, G << _shift, B << _shift);

            return Quad<SAMPLE>(result.R >> _shift, result.G >> _shift, result.B >> _shift, A);
      }

      int _shift;
      TRANSFORM _colortransform;
};



#endif

Generated by  Doxygen 1.6.0   Back to index