This repository has been archived by the owner on Sep 14, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 22
/
encoder.h
82 lines (71 loc) · 2.47 KB
/
encoder.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#ifndef IZ_ENCODER_H
#define IZ_ENCODER_H 1
#include <cstring>
#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<Code>
{
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 = ::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