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
/
pixel.h
113 lines (94 loc) · 2.5 KB
/
pixel.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#ifndef IZ_PIXEL_H
#define IZ_PIXEL_H 1
#include "intmacros.h"
#include "predict.h"
namespace IZ {
template<typename U = unsigned char>
class Pixel
{
enum Components {
R = 0,
G = 1,
B = 2,
Count = 3,
C0 = G,
C1 = R,
C2 = B
};
public:
void readFrom(const U *p) {
c[0] = p[C0];
c[1] = p[C1];
c[2] = p[C2];
}
void writeTo(U *p) const {
p[C0] = c[0];
p[C1] = c[1];
p[C2] = c[2];
}
void predict(const U *p, int bpp, int bpr, int (*predictor)(int, int, int)) __attribute__((always_inline)) {
c[0] = predictor(p[C0 - bpp], p[C0 - bpr], p[C0 - bpp - bpr]);
c[1] = predictor(p[C1 - bpp], p[C1 - bpr], p[C1 - bpp - bpr]);
c[2] = predictor(p[C2 - bpp], p[C2 - bpr], p[C2 - bpp - bpr]);
}
void operator-=(const Pixel<U> &other) {
c[0] -= other.c[0];
c[1] -= other.c[1];
c[2] -= other.c[2];
}
void operator+=(const Pixel<U> &other) {
c[0] += other.c[0];
c[1] += other.c[1];
c[2] += other.c[2];
}
bool operator==(const Pixel<U> &other) const {
return c[0] == other.c[0] && c[1] == other.c[1] && c[2] == other.c[2];
}
void forwardTransform()
{
c[1] -= c[0];
c[2] -= c[0];
}
void reverseTransform()
{
c[1] += c[0];
c[2] += c[0];
}
void toUnsigned() {
if (sizeof(U) == sizeof(signed char)) {
c[0] = s2u((signed char) c[0]);
c[1] = s2u((signed char) c[1]);
c[2] = s2u((signed char) c[2]);
} else if (sizeof(U) == sizeof(signed short)) {
c[0] = s2u((signed short) c[0]);
c[1] = s2u((signed short) c[1]);
c[2] = s2u((signed short) c[2]);
} else {
c[0] = s2u(c[0]);
c[1] = s2u(c[1]);
c[2] = s2u(c[2]);
}
}
void toSigned() {
c[0] = u2s(c[0]);
c[1] = u2s(c[1]);
c[2] = u2s(c[2]);
}
unsigned int numBits() const {
return ::numBits(c[0] | c[1] | c[2]);
}
void writeBits(BitEncoder<> &bc, int numBits) const {
bc.writeBits(c[0], numBits);
bc.writeBits(c[1], numBits);
bc.writeBits(c[2], numBits);
bc.flushCache();
}
void readBits(BitDecoder<> &bc, int numBits) {
c[0] = bc.readBits(numBits);
c[1] = bc.readBits(numBits);
c[2] = bc.readBits(numBits);
}
int c[Count];
};
} // namespace IZ
#endif