Go to the documentation of this file.00001 #ifndef IZ_PIXEL_H
00002 #define IZ_PIXEL_H 1
00003
00004 #include "intmacros.h"
00005 #include "predict.h"
00006
00007 namespace IZ
00008 {
00009 template<typename U = unsigned char>
00010 class Pixel
00011 {
00012 enum Components
00013 {
00014 R = 0,
00015 G = 1,
00016 B = 2,
00017 Count = 3,
00018 C0 = G,
00019 C1 = R,
00020 C2 = B
00021 };
00022
00023 public:
00024 void readFrom(const U* p)
00025 {
00026 c[0] = p[C0];
00027 c[1] = p[C1];
00028 c[2] = p[C2];
00029 }
00030
00031 void writeTo(U* p) const
00032 {
00033 p[C0] = c[0];
00034 p[C1] = c[1];
00035 p[C2] = c[2];
00036 }
00037
00038 void predict(const U* p, int bpp, int bpr, int (* predictor)(int, int, int)) __attribute__((always_inline))
00039 {
00040 c[0] = predictor(p[C0 - bpp], p[C0 - bpr], p[C0 - bpp - bpr]);
00041 c[1] = predictor(p[C1 - bpp], p[C1 - bpr], p[C1 - bpp - bpr]);
00042 c[2] = predictor(p[C2 - bpp], p[C2 - bpr], p[C2 - bpp - bpr]);
00043 }
00044
00045 void operator-=(const Pixel<U>& other)
00046 {
00047 c[0] -= other.c[0];
00048 c[1] -= other.c[1];
00049 c[2] -= other.c[2];
00050 }
00051
00052 void operator+=(const Pixel<U>& other)
00053 {
00054 c[0] += other.c[0];
00055 c[1] += other.c[1];
00056 c[2] += other.c[2];
00057 }
00058
00059 bool operator==(const Pixel<U>& other) const
00060 {
00061 return c[0] == other.c[0] && c[1] == other.c[1] && c[2] == other.c[2];
00062 }
00063
00064 void forwardTransform()
00065 {
00066 c[1] -= c[0];
00067 c[2] -= c[0];
00068 }
00069
00070 void reverseTransform()
00071 {
00072 c[1] += c[0];
00073 c[2] += c[0];
00074 }
00075
00076 void toUnsigned()
00077 {
00078 if (sizeof(U) == sizeof(signed char))
00079 {
00080 c[0] = s2u((signed char) c[0]);
00081 c[1] = s2u((signed char) c[1]);
00082 c[2] = s2u((signed char) c[2]);
00083 }
00084 else if (sizeof(U) == sizeof(signed short))
00085 {
00086 c[0] = s2u((signed short) c[0]);
00087 c[1] = s2u((signed short) c[1]);
00088 c[2] = s2u((signed short) c[2]);
00089 }
00090 else
00091 {
00092 c[0] = s2u(c[0]);
00093 c[1] = s2u(c[1]);
00094 c[2] = s2u(c[2]);
00095 }
00096 }
00097
00098 void toSigned()
00099 {
00100 c[0] = u2s(c[0]);
00101 c[1] = u2s(c[1]);
00102 c[2] = u2s(c[2]);
00103 }
00104
00105 unsigned int numBits() const
00106 {
00107 return IZ::numBits(c[0] | c[1] | c[2]);
00108 }
00109
00110 void writeBits(BitEncoder<>& bc, int numBits) const
00111 {
00112 bc.writeBits(c[0], numBits);
00113 bc.writeBits(c[1], numBits);
00114 bc.writeBits(c[2], numBits);
00115 bc.flushCache();
00116 }
00117
00118 void readBits(BitDecoder<>& bc, int numBits)
00119 {
00120 c[0] = bc.readBits(numBits);
00121 c[1] = bc.readBits(numBits);
00122 c[2] = bc.readBits(numBits);
00123 }
00124
00125 int c[Count];
00126 };
00127
00128 }
00129
00130 #endif