// // (C) Jan de Vaan 2007-2010, 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 struct TransformNoneImpl { typedef sample SAMPLE; inlinehint Triplet operator() (int v1, int v2, int v3) { return Triplet(v1, v2, v3); } }; template struct TransformNone : public TransformNoneImpl { typedef struct TransformNoneImpl INVERSE; }; template struct TransformHp1 { enum { RANGE = 1 << sizeof(sample)*8 }; typedef sample SAMPLE; struct INVERSE { INVERSE(const TransformHp1&) {}; inlinehint Triplet operator() (int v1, int v2, int v3) { return Triplet(v1 + v2 - RANGE/2, v2, v3 + v2 - RANGE/2); } }; inlinehint Triplet operator() (int R, int G, int B) { Triplet hp1; hp1.v2 = SAMPLE(G); hp1.v1 = SAMPLE(R - G + RANGE/2); hp1.v3 = SAMPLE(B - G + RANGE/2); return hp1; } }; template struct TransformHp2 { enum { RANGE = 1 << sizeof(sample)*8 }; typedef sample SAMPLE; struct INVERSE { INVERSE(const TransformHp2&) {}; inlinehint Triplet operator() (int v1, int v2, int v3) { Triplet 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 operator() (int R, int G, int B) { return Triplet(R - G + RANGE/2, G, B - ((R+G )>>1) - RANGE/2); } }; template struct TransformHp3 { enum { RANGE = 1 << sizeof(sample)*8 }; typedef sample SAMPLE; struct INVERSE { INVERSE(const TransformHp3&) {}; inlinehint Triplet operator() (int v1, int v2, int v3) { int G = v1 - ((v3 + v2)>>2) + RANGE/4; Triplet 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 operator() (int R, int G, int B) { Triplet 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 struct TransformShifted { typedef typename TRANSFORM::SAMPLE SAMPLE; struct INVERSE { INVERSE(const TransformShifted& transform) : _shift(transform._shift), _inverseTransform(transform._colortransform) {} inlinehint Triplet operator() (int v1, int v2, int v3) { Triplet result = _inverseTransform(v1 << _shift, v2 << _shift, v3 << _shift); return Triplet(result.R >> _shift, result.G >> _shift, result.B >> _shift); } inlinehint Quad operator() (int v1, int v2, int v3, int v4) { Triplet result = _inverseTransform(v1 << _shift, v2 << _shift, v3 << _shift); return Quad(result.R >> _shift, result.G >> _shift, result.B >> _shift, v4); } int _shift; typename TRANSFORM::INVERSE _inverseTransform; }; TransformShifted(int shift) : _shift(shift) { } inlinehint Triplet operator() (int R, int G, int B) { Triplet result = _colortransform(R << _shift, G << _shift, B << _shift); return Triplet(result.R >> _shift, result.G >> _shift, result.B >> _shift); } inlinehint Quad operator() (int R, int G, int B, int A) { Triplet result = _colortransform(R << _shift, G << _shift, B << _shift); return Quad(result.R >> _shift, result.G >> _shift, result.B >> _shift, A); } int _shift; TRANSFORM _colortransform; }; #endif