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
/
decoder.h
87 lines (75 loc) · 2.47 KB
/
decoder.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
83
84
85
86
87
#ifndef IZ_DECODER_H
#define IZ_DECODER_H 1
#include <cstring>
#include "iz_p.h"
namespace IZ {
#define decodePixel(predictor) \
{ \
Pixel<> pix, pp; \
\
this->fillCache(); \
int nl = decodeTable[pl][this->peekBits(MAX_CODE_LENGTH)]; \
this->skipBits(dCount[(pl << CONTEXT_BITS) + nl]); \
pl = nl; \
pix.readBits(*this, nl); \
\
pp.predict(p, bpp, bpr, predictor::predict); \
pix.toSigned(); \
pix.reverseTransform(); \
pix += pp; \
pix.writeTo(p); \
p += bpp; \
}
template <
int bpp = 3,
typename Predictor = Predictor3avgplane<>,
typename Code = U32
>
class ImageDecoder : public BitDecoder<Code>
{
public:
ImageDecoder() {
memcpy(dCount, staticdCount, sizeof(dCount));
}
void decodeImagePixels(Image<> &im) __attribute__((always_inline)) {
unsigned char *p = (unsigned char *) im.data();
const int bpr = bpp * im.width();
im.setSamplesPerLine(bpr);
const int size = im.width() * im.height();
unsigned char *pend = p + bpp * size;
int pl = 7;
/* first pixel in first line */
decodePixel(Predictor0<>);
/* remaining pixels in first line */
const unsigned char *endline = p + bpr - bpp;
while (p != endline) {
decodePixel(Predictor1x<>);
}
while (p != pend) {
/* first pixel in remaining lines */
decodePixel(Predictor1y<>);
/* remaining pixels in remaining lines */
const unsigned char *endline = p + bpr - bpp;
while (p != endline) {
decodePixel(Predictor);
}
}
}
void decodeImageSize(Image<> &im) {
this->fillCache();
int b = this->readBits(4);
int w = this->readBits(b) + 1;
int h = this->readBits(b) + 1;
im.setWidth(w);
im.setHeight(h);
}
void skipImageSize() {
this->fillCache();
int b = this->readBits(4);
this->skipBits(2 * b);
}
private:
unsigned int dCount[1 << (2 * CONTEXT_BITS)];
};
} // namespace IZ
#endif