blob: 85279b35acd3cc5fbae5f74ffb4e8d9b2323e69f (
plain)
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
|
#pragma once
namespace Cryo {
class BitReaderBase {
public:
unsigned char *_data; //NB! never override this - used by decompressor
unsigned int _queue;
unsigned int _queueLeft;
public:
BitReaderBase(void *data, unsigned int dataSize = 0) {
_data = static_cast<unsigned char *>(data);
_queue = _queueLeft = 0;
}
unsigned char GetBit() {
return 0; // to be overriden
}
};
// used to decompress HSQ files
class BitReader16 : BitReaderBase {
public:
unsigned char GetBit() {
if (!_queueLeft) {
_queue = (_data[1] << 8) | _data[0];
_data += 2;
_queueLeft += 16;
}
unsigned char bit = _queue & 1;
_queue >>= 1;
_queueLeft--;
return bit;
}
};
// used by HNM decoder
class BitReader32 : BitReaderBase {
public:
unsigned char GetBit() {
if (!_queueLeft) {
_queue = (_data[3] << 24) | (_data[2] << 16) | (_data[1] << 8) | _data[0];
_data += 4;
_queueLeft += 32;
}
unsigned char bit = (_queue >> (_queueLeft - 1)) & 1;
_queueLeft--;
return bit;
}
};
template <class BitReader>
class LempelZivBase : BitReader {
public:
LempelZivBase(void *input, unsigned int inputSize) : BitReader(input, inputSize)
unsigned int UnpackBuffer(void *output, unsigned int maxOutputSize) {
unsigned char *out = static_cast<unsigned char *>(output);
for (;;) {
if (GetBit()) {
*out++ = *_data++;
} else {
int length, offset;
if (GetBit()) {
length = *_data & 7;
offset = ((_data[1] << 8) | _data[0]) >> 3;
_data += 2;
offset -= 8192;
if (!length)
length = *_data++;
if (!length)
break;
} else {
length = GetBit() * 2 + GetBit();
offset = *(_data++) - 256;
}
length += 2;
while (length--) {
*out = *(out + offset);
out++;
}
}
}
return out - static_cast<unsigned char *>(output);
}
};
}
|