#ifndef IZ_ENCODER_H #define IZ_ENCODER_H 1 #include #include "iz_p.h" namespace IZ { #define encodePixel(predictor) \ { \ Pixel<> pix, pp; \ \ pix.readFrom(p); \ pp.predict(p, bpp, bpr, predictor::predict); \ pix -= pp; \ pix.forwardTransform(); \ p += bpp; \ pix.toUnsigned(); \ \ int nl = pix.numBits(); \ cx = (cx << CONTEXT_BITS) + nl; \ this->writeBits(dBits[cx & bitMask(2 * CONTEXT_BITS)], dCount[cx & bitMask(2 * CONTEXT_BITS)]); \ pix.writeBits(*this, nl); \ } template < int bpp = 3, typename Predictor = Predictor3avgplane<>, typename Code = U32 > class ImageEncoder : public BitEncoder { public: ImageEncoder() { memcpy(dBits, staticdBits, sizeof(dBits)); memcpy(dCount, staticdCount, sizeof(dCount)); } void encodeImagePixels(const Image &im) __attribute__((always_inline)) { const int bpr = im.samplesPerLine(); const unsigned char *p = im.data(); int size = im.width() * im.height(); const unsigned char *pend = p + bpp * size; unsigned int cx = (7 << CONTEXT_BITS) + 7; /* first pixel in first line */ encodePixel(Predictor0<>); /* remaining pixels in first line */ const unsigned char *endline = p + bpr - bpp; while (p != endline) { encodePixel(Predictor1x<>); } while (p != pend) { /* first pixel in remaining lines */ encodePixel(Predictor1y<>); /* remaining pixels in remaining lines */ const unsigned char *endline = p + bpr - bpp; while (p != endline) { encodePixel(Predictor); } } } void encodeImageSize(const Image &im) { int w = im.width() - 1; int h = im.height() - 1; int b = IZ::numBits(w | h); this->writeBits(b, 4); this->writeBits(w, b); this->writeBits(h, b); this->flushCache(); } private: unsigned int dBits[1 << (2 * CONTEXT_BITS)]; unsigned int dCount[1 << (2 * CONTEXT_BITS)]; }; } // namespace IZ #endif