00001 // 00002 // (C) Jan de Vaan 2007-2010, all rights reserved. See the accompanying "License.txt" for licensed use. 00003 // 00004 00005 00006 00007 #ifndef CHARLS_LOSSLESSTRAITS 00008 #define CHARLS_LOSSLESSTRAITS 00009 00010 // 00011 // optimized trait classes for lossless compression of 8 bit color and 8/16 bit monochrome images. 00012 // This class is assumes MAXVAL correspond to a whole number of bits, and no custom RESET value is set when encoding. 00013 // The point of this is to have the most optimized code for the most common and most demanding scenario. 00014 00015 template <class sample, LONG bitsperpixel> 00016 struct LosslessTraitsImplT 00017 { 00018 typedef sample SAMPLE; 00019 enum { 00020 NEAR = 0, 00021 bpp = bitsperpixel, 00022 qbpp = bitsperpixel, 00023 RANGE = (1 << bpp), 00024 MAXVAL= (1 << bpp) - 1, 00025 LIMIT = 2 * (bitsperpixel + MAX(8,bitsperpixel)), 00026 RESET = BASIC_RESET 00027 }; 00028 00029 static inlinehint LONG ComputeErrVal(LONG d) 00030 { return ModRange(d); } 00031 00032 static inlinehint bool IsNear(LONG lhs, LONG rhs) 00033 { return lhs == rhs; } 00034 00035 static inlinehint LONG ModRange(LONG Errval) 00036 { 00037 return LONG(Errval << (LONG_BITCOUNT - bpp)) >> (LONG_BITCOUNT - bpp); 00038 } 00039 00040 static inlinehint SAMPLE ComputeReconstructedSample(LONG Px, LONG ErrVal) 00041 { 00042 return SAMPLE(MAXVAL & (Px + ErrVal)); 00043 } 00044 00045 static inlinehint LONG CorrectPrediction(LONG Pxc) 00046 { 00047 if ((Pxc & MAXVAL) == Pxc) 00048 return Pxc; 00049 00050 return (~(Pxc >> (LONG_BITCOUNT-1))) & MAXVAL; 00051 } 00052 00053 }; 00054 00055 // For some weird reason MSVC6 doesn't like these templates 00056 #if defined(_MSC_VER) && _MSC_VER <= 1200 00057 # define DISABLE_SPECIALIZATIONS 00058 #else 00059 00060 template <class SAMPLE, LONG bpp> 00061 struct LosslessTraitsT : public LosslessTraitsImplT<SAMPLE, bpp> 00062 { 00063 typedef SAMPLE PIXEL; 00064 }; 00065 00066 00067 00068 template<> 00069 struct LosslessTraitsT<BYTE,8> : public LosslessTraitsImplT<BYTE, 8> 00070 { 00071 typedef SAMPLE PIXEL; 00072 00073 static inlinehint signed char ModRange(LONG Errval) 00074 { return (signed char)Errval; } 00075 00076 static inlinehint LONG ComputeErrVal(LONG d) 00077 { return (signed char)(d); } 00078 00079 static inlinehint BYTE ComputeReconstructedSample(LONG Px, LONG ErrVal) 00080 { return BYTE(Px + ErrVal); } 00081 00082 }; 00083 00084 00085 00086 template<> 00087 struct LosslessTraitsT<USHORT,16> : public LosslessTraitsImplT<USHORT,16> 00088 { 00089 typedef SAMPLE PIXEL; 00090 00091 static inlinehint short ModRange(LONG Errval) 00092 { return short(Errval); } 00093 00094 static inlinehint LONG ComputeErrVal(LONG d) 00095 { return short(d); } 00096 00097 static inlinehint SAMPLE ComputeReconstructedSample(LONG Px, LONG ErrVal) 00098 { return SAMPLE(Px + ErrVal); } 00099 00100 }; 00101 00102 00103 00104 00105 template<class SAMPLE, LONG bpp> 00106 struct LosslessTraitsT<Triplet<SAMPLE>,bpp> : public LosslessTraitsImplT<SAMPLE,bpp> 00107 { 00108 typedef Triplet<SAMPLE> PIXEL; 00109 00110 static inlinehint bool IsNear(LONG lhs, LONG rhs) 00111 { return lhs == rhs; } 00112 00113 static inlinehint bool IsNear(PIXEL lhs, PIXEL rhs) 00114 { return lhs == rhs; } 00115 00116 00117 static inlinehint SAMPLE ComputeReconstructedSample(LONG Px, LONG ErrVal) 00118 { return SAMPLE(Px + ErrVal); } 00119 00120 00121 }; 00122 #endif 00123 00124 #endif