oodle-kraken-ruby 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +14 -0
- data/ext/oodle-kraken/extconf.rb +11 -0
- data/ext/oodle-kraken/oodle_kraken_c.c +38 -0
- data/ext/oodle-kraken/ooz/LICENSE +15 -0
- data/ext/oodle-kraken/ooz/README.md +23 -0
- data/ext/oodle-kraken/ooz/bitknit.cpp +429 -0
- data/ext/oodle-kraken/ooz/kraken.cpp +4153 -0
- data/ext/oodle-kraken/ooz/kraken.h +33 -0
- data/ext/oodle-kraken/ooz/lzna.cpp +617 -0
- data/ext/oodle-kraken/ooz/ooz.cpp +342 -0
- data/ext/oodle-kraken/ooz/stdafx.cpp +8 -0
- data/ext/oodle-kraken/ooz/stdafx.h +68 -0
- data/ext/oodle-kraken/ooz/targetver.h +8 -0
- data/lib/oodle-kraken-ruby.rb +2 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c1e6d630f19de2c2de3888643967ddbd39ef42d7187b7f9f60e4d871e4811648
|
4
|
+
data.tar.gz: 6e675ea78dcdfe739fa78c47e36ba61ab9aae9b7033ce20ae8483bad68cadfea
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7ee8347d55b228dc8b86aa1e75c3c9a5123e54ec14b9c7363400635449119019f2db795b9e0f4b8f7e9cd8b49804a9c8e0d8e81441dfb6af26a3c1635880dc8a
|
7
|
+
data.tar.gz: 3876de0ddc9a0babcb20710eace1d86f3f9bf75a699d0b52c79f5b554ee893ec9b1d8fd075b4b03bfbbbf3d51a4fa3f0bbfaafd4ece59ee5621072c15ce132c5
|
data/LICENSE
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Copyright (C) 2022, Kerilk
|
2
|
+
|
3
|
+
This program is free software: you can redistribute it and/or modify
|
4
|
+
it under the terms of the GNU General Public License as published by
|
5
|
+
the Free Software Foundation, either version 3 of the License, or
|
6
|
+
(at your option) any later version.
|
7
|
+
|
8
|
+
This program is distributed in the hope that it will be useful,
|
9
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
GNU General Public License for more details.
|
12
|
+
|
13
|
+
You should have received a copy of the GNU General Public License
|
14
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include "kraken.h"
|
3
|
+
#include <stdlib.h>
|
4
|
+
|
5
|
+
VALUE mOodleKraken;
|
6
|
+
|
7
|
+
#define SAFE_SPACE 64
|
8
|
+
|
9
|
+
static VALUE decompress_p(VALUE self, VALUE in_str, VALUE decompressed_size) {
|
10
|
+
(void)self;
|
11
|
+
VALUE out_str = Qnil;
|
12
|
+
Check_Type(in_str, T_STRING);
|
13
|
+
size_t out_sz = NUM2ULL(decompressed_size);
|
14
|
+
size_t in_sz = RSTRING_LEN(in_str);
|
15
|
+
const uint8_t *in_ptr = RSTRING_PTR(in_str);
|
16
|
+
|
17
|
+
uint8_t *out_ptr = malloc((long)out_sz + SAFE_SPACE);
|
18
|
+
if (!out_ptr)
|
19
|
+
rb_raise(rb_eRuntimeError, "Decompression Error");
|
20
|
+
ssize_t out_bytes = Kraken_Decompress(in_ptr, in_sz, out_ptr, out_sz);
|
21
|
+
if (out_bytes < 0 || (size_t)out_bytes != out_sz)
|
22
|
+
rb_raise(rb_eRuntimeError, "Decompression Error");
|
23
|
+
out_str = rb_str_buf_new((long)out_sz);
|
24
|
+
rb_str_cat(out_str, out_ptr, out_sz);
|
25
|
+
return out_str;
|
26
|
+
}
|
27
|
+
|
28
|
+
void Init_oodle_kraken_c() {
|
29
|
+
mOodleKraken = rb_define_module("OodleKraken");
|
30
|
+
/**
|
31
|
+
* @overload decompress(str, decompressed_size)
|
32
|
+
* decompress an Oodle compressed string
|
33
|
+
* @param str [String] the string to decompress
|
34
|
+
* @param decompressed_size [Integer] the size of the decompressed data
|
35
|
+
* @return [String] the decompressed string
|
36
|
+
*/
|
37
|
+
rb_define_module_function(mOodleKraken, "decompress", decompress_p, 2);
|
38
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Copyright (C) 2016, Powzix
|
2
|
+
Copyright (C) 2019, rarten
|
3
|
+
|
4
|
+
This program is free software: you can redistribute it and/or modify
|
5
|
+
it under the terms of the GNU General Public License as published by
|
6
|
+
the Free Software Foundation, either version 3 of the License, or
|
7
|
+
(at your option) any later version.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it will be useful,
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
GNU General Public License for more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License
|
15
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# ooz
|
2
|
+
Open source Kraken / Mermaid / Selkie / Leviathan / LZNA / Bitknit decompressor
|
3
|
+
|
4
|
+
Also supports using oo2core_7_win32.dll / oo2core_7_win64.dll which can be acquired from the free game Warframe on steam.
|
5
|
+
|
6
|
+
```
|
7
|
+
ooz v7.0
|
8
|
+
|
9
|
+
Usage: ooz [options] input [output]
|
10
|
+
-c --stdout write to stdout
|
11
|
+
-d --decompress decompress (default)
|
12
|
+
-z --compress compress (requires oo2core_7_win64.dll)
|
13
|
+
-b just benchmark, don't overwrite anything
|
14
|
+
-f force overwrite existing file
|
15
|
+
--dll decompress with the dll
|
16
|
+
--verify decompress and verify that it matches output
|
17
|
+
--verify=<folder> verify with files in this folder
|
18
|
+
-<1-9> --level=<-4..10> compression level
|
19
|
+
-m<k> [k|m|s|l|h] compressor selection
|
20
|
+
--kraken --mermaid --selkie --leviathan --hydra compressor selection
|
21
|
+
|
22
|
+
(Warning! not fuzz safe, so please trust the input)
|
23
|
+
```
|
@@ -0,0 +1,429 @@
|
|
1
|
+
/*
|
2
|
+
Copyright (C) 2016, Powzix
|
3
|
+
Copyright (C) 2019, rarten
|
4
|
+
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU General Public License
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include "stdafx.h"
|
20
|
+
|
21
|
+
struct BitknitLiteral {
|
22
|
+
uint16 lookup[512 + 4];
|
23
|
+
uint16 a[300 + 1];
|
24
|
+
uint16 freq[300];
|
25
|
+
uint32 adapt_interval;
|
26
|
+
};
|
27
|
+
|
28
|
+
struct BitknitDistanceLsb {
|
29
|
+
uint16 lookup[64 + 4];
|
30
|
+
uint16 a[40 + 1];
|
31
|
+
uint16 freq[40];
|
32
|
+
uint32 adapt_interval;
|
33
|
+
};
|
34
|
+
|
35
|
+
struct BitknitDistanceBits {
|
36
|
+
uint16 lookup[64 + 4];
|
37
|
+
uint16 a[21 + 1];
|
38
|
+
uint16 freq[21];
|
39
|
+
uint32 adapt_interval;
|
40
|
+
};
|
41
|
+
|
42
|
+
|
43
|
+
struct BitknitState {
|
44
|
+
uint32 recent_dist[8];
|
45
|
+
uint32 last_match_dist;
|
46
|
+
uint32 recent_dist_mask;
|
47
|
+
uint32 bits, bits2;
|
48
|
+
|
49
|
+
BitknitLiteral literals[4];
|
50
|
+
BitknitDistanceLsb distance_lsb[4];
|
51
|
+
BitknitDistanceBits distance_bits;
|
52
|
+
};
|
53
|
+
|
54
|
+
void BitknitLiteral_Init(BitknitLiteral *model) {
|
55
|
+
size_t i;
|
56
|
+
uint16 *p, *p_end;
|
57
|
+
|
58
|
+
for (i = 0; i < 264; i++)
|
59
|
+
model->a[i] = (0x8000 - 300 + 264) * i / 264;
|
60
|
+
for (; i <= 300; i++)
|
61
|
+
model->a[i] = (0x8000 - 300) + i;
|
62
|
+
|
63
|
+
model->adapt_interval = 1024;
|
64
|
+
for (i = 0; i < 300; i++)
|
65
|
+
model->freq[i] = 1;
|
66
|
+
|
67
|
+
for (i = 0, p = model->lookup; i < 300; i++) {
|
68
|
+
p_end = &model->lookup[(model->a[i + 1] - 1) >> 6];
|
69
|
+
do {
|
70
|
+
p[0] = p[1] = p[2] = p[3] = i;
|
71
|
+
p += 4;
|
72
|
+
} while (p <= p_end);
|
73
|
+
p = p_end + 1;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
void BitknitDistanceLsb_Init(BitknitDistanceLsb *model) {
|
78
|
+
size_t i;
|
79
|
+
uint16 *p, *p_end;
|
80
|
+
|
81
|
+
for (i = 0; i <= 40; i++)
|
82
|
+
model->a[i] = 0x8000 * i / 40;
|
83
|
+
|
84
|
+
model->adapt_interval = 1024;
|
85
|
+
for (i = 0; i < 40; i++)
|
86
|
+
model->freq[i] = 1;
|
87
|
+
|
88
|
+
for (i = 0, p = model->lookup; i < 40; i++) {
|
89
|
+
p_end = &model->lookup[(model->a[i + 1] - 1) >> 9];
|
90
|
+
do {
|
91
|
+
p[0] = p[1] = p[2] = p[3] = i;
|
92
|
+
p += 4;
|
93
|
+
} while (p <= p_end);
|
94
|
+
p = p_end + 1;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
void BitknitDistanceBits_Init(BitknitDistanceBits *model) {
|
99
|
+
size_t i;
|
100
|
+
uint16 *p, *p_end;
|
101
|
+
|
102
|
+
for (i = 0; i <= 21; i++)
|
103
|
+
model->a[i] = 0x8000 * i / 21;
|
104
|
+
|
105
|
+
model->adapt_interval = 1024;
|
106
|
+
for (i = 0; i < 21; i++)
|
107
|
+
model->freq[i] = 1;
|
108
|
+
|
109
|
+
for (i = 0, p = model->lookup; i < 21; i++) {
|
110
|
+
p_end = &model->lookup[(model->a[i + 1] - 1) >> 9];
|
111
|
+
do {
|
112
|
+
p[0] = p[1] = p[2] = p[3] = i;
|
113
|
+
p += 4;
|
114
|
+
} while (p <= p_end);
|
115
|
+
p = p_end + 1;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
void BitknitState_Init(BitknitState *bk) {
|
120
|
+
size_t i;
|
121
|
+
|
122
|
+
bk->last_match_dist = 1;
|
123
|
+
for (i = 0; i < 8; i++)
|
124
|
+
bk->recent_dist[i] = 1;
|
125
|
+
|
126
|
+
bk->recent_dist_mask =
|
127
|
+
(7 << (7 * 3)) | (6 << (6 * 3)) |
|
128
|
+
(5 << (5 * 3)) | (4 << (4 * 3)) |
|
129
|
+
(3 << (3 * 3)) | (2 << (2 * 3)) |
|
130
|
+
(1 << (1 * 3)) | (0 << (0 * 3));
|
131
|
+
|
132
|
+
for (i = 0; i < 4; i++)
|
133
|
+
BitknitLiteral_Init(&bk->literals[i]);
|
134
|
+
|
135
|
+
for (i = 0; i < 4; i++)
|
136
|
+
BitknitDistanceLsb_Init(&bk->distance_lsb[i]);
|
137
|
+
|
138
|
+
BitknitDistanceBits_Init(&bk->distance_bits);
|
139
|
+
|
140
|
+
}
|
141
|
+
|
142
|
+
void BitknitLiteral_Adaptive(BitknitLiteral *model, uint32 sym) {
|
143
|
+
size_t i;
|
144
|
+
uint32 sum;
|
145
|
+
uint16 *p, *p_end;
|
146
|
+
|
147
|
+
model->adapt_interval = 1024;
|
148
|
+
model->freq[sym] += 725;
|
149
|
+
|
150
|
+
sum = 0;
|
151
|
+
for (i = 0; i < 300; i++) {
|
152
|
+
sum += model->freq[i];
|
153
|
+
model->freq[i] = 1;
|
154
|
+
model->a[i + 1] = model->a[i + 1] + ((sum - model->a[i + 1]) >> 1);
|
155
|
+
}
|
156
|
+
|
157
|
+
for (i = 0, p = model->lookup; i < 300; i++) {
|
158
|
+
p_end = &model->lookup[(model->a[i + 1] - 1) >> 6];
|
159
|
+
do {
|
160
|
+
p[0] = p[1] = p[2] = p[3] = i;
|
161
|
+
p += 4;
|
162
|
+
} while (p <= p_end);
|
163
|
+
p = p_end + 1;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
uint32 BitknitLiteral_Lookup(BitknitLiteral *model, uint32 *bits) {
|
168
|
+
uint32 masked = *bits & 0x7FFF;
|
169
|
+
size_t sym = model->lookup[masked >> 6];
|
170
|
+
sym += masked > model->a[sym + 1];
|
171
|
+
while (masked >= model->a[sym + 1])
|
172
|
+
sym += 1;
|
173
|
+
*bits = masked + (*bits >> 15) * (model->a[sym + 1] - model->a[sym]) - model->a[sym];
|
174
|
+
model->freq[sym] += 31;
|
175
|
+
if (--model->adapt_interval == 0)
|
176
|
+
BitknitLiteral_Adaptive(model, sym);
|
177
|
+
return sym;
|
178
|
+
}
|
179
|
+
|
180
|
+
void BitknitDistanceLsb_Adaptive(BitknitDistanceLsb *model, uint32 sym) {
|
181
|
+
size_t i;
|
182
|
+
uint32 sum;
|
183
|
+
uint16 *p, *p_end;
|
184
|
+
|
185
|
+
model->adapt_interval = 1024;
|
186
|
+
model->freq[sym] += 985;
|
187
|
+
|
188
|
+
sum = 0;
|
189
|
+
for (i = 0; i < 40; i++) {
|
190
|
+
sum += model->freq[i];
|
191
|
+
model->freq[i] = 1;
|
192
|
+
model->a[i + 1] = model->a[i + 1] + ((sum - model->a[i + 1]) >> 1);
|
193
|
+
}
|
194
|
+
|
195
|
+
for (i = 0, p = model->lookup; i < 40; i++) {
|
196
|
+
p_end = &model->lookup[(model->a[i + 1] - 1) >> 9];
|
197
|
+
do {
|
198
|
+
p[0] = p[1] = p[2] = p[3] = i;
|
199
|
+
p += 4;
|
200
|
+
} while (p <= p_end);
|
201
|
+
p = p_end + 1;
|
202
|
+
}
|
203
|
+
}
|
204
|
+
|
205
|
+
uint32 BitknitDistanceLsb_Lookup(BitknitDistanceLsb *model, uint32 *bits) {
|
206
|
+
uint32 masked = *bits & 0x7FFF;
|
207
|
+
size_t sym = model->lookup[masked >> 9];
|
208
|
+
sym += masked > model->a[sym + 1];
|
209
|
+
while (masked >= model->a[sym + 1])
|
210
|
+
sym += 1;
|
211
|
+
*bits = masked + (*bits >> 15) * (model->a[sym + 1] - model->a[sym]) - model->a[sym];
|
212
|
+
model->freq[sym] += 31;
|
213
|
+
if (--model->adapt_interval == 0)
|
214
|
+
BitknitDistanceLsb_Adaptive(model, sym);
|
215
|
+
return sym;
|
216
|
+
}
|
217
|
+
|
218
|
+
|
219
|
+
void BitknitDistanceBits_Adaptive(BitknitDistanceBits *model, uint32 sym) {
|
220
|
+
size_t i;
|
221
|
+
uint32 sum;
|
222
|
+
uint16 *p, *p_end;
|
223
|
+
|
224
|
+
model->adapt_interval = 1024;
|
225
|
+
model->freq[sym] += 1004;
|
226
|
+
|
227
|
+
sum = 0;
|
228
|
+
for (i = 0; i < 21; i++) {
|
229
|
+
sum += model->freq[i];
|
230
|
+
model->freq[i] = 1;
|
231
|
+
model->a[i + 1] = model->a[i + 1] + ((sum - model->a[i + 1]) >> 1);
|
232
|
+
}
|
233
|
+
|
234
|
+
for (i = 0, p = model->lookup; i < 21; i++) {
|
235
|
+
p_end = &model->lookup[(model->a[i + 1] - 1) >> 9];
|
236
|
+
do {
|
237
|
+
p[0] = p[1] = p[2] = p[3] = i;
|
238
|
+
p += 4;
|
239
|
+
} while (p <= p_end);
|
240
|
+
p = p_end + 1;
|
241
|
+
}
|
242
|
+
}
|
243
|
+
|
244
|
+
uint32 BitknitDistanceBits_Lookup(BitknitDistanceBits *model, uint32 *bits) {
|
245
|
+
uint32 masked = *bits & 0x7FFF;
|
246
|
+
size_t sym = model->lookup[masked >> 9];
|
247
|
+
sym += masked > model->a[sym + 1];
|
248
|
+
while (masked >= model->a[sym + 1])
|
249
|
+
sym += 1;
|
250
|
+
*bits = masked + (*bits >> 15) * (model->a[sym + 1] - model->a[sym]) - model->a[sym];
|
251
|
+
model->freq[sym] += 31;
|
252
|
+
if (--model->adapt_interval == 0)
|
253
|
+
BitknitDistanceBits_Adaptive(model, sym);
|
254
|
+
return sym;
|
255
|
+
}
|
256
|
+
|
257
|
+
|
258
|
+
#define RENORMALIZE() { if (bits < 0x10000) bits = (bits << 16) | *(uint16*)src, src += 2; bitst = bits; bits = bits2; bits2 = bitst; }
|
259
|
+
|
260
|
+
|
261
|
+
static void BitknitCopyLongDist(byte *dst, size_t dist, size_t length) {
|
262
|
+
const byte *src = dst - dist;
|
263
|
+
((uint64*)dst)[0] = ((uint64*)src)[0];
|
264
|
+
((uint64*)dst)[1] = ((uint64*)src)[1];
|
265
|
+
if (length > 16) {
|
266
|
+
do {
|
267
|
+
((uint64*)dst)[2] = ((uint64*)src)[2];
|
268
|
+
dst += 8;
|
269
|
+
src += 8;
|
270
|
+
length -= 8;
|
271
|
+
} while (length > 16);
|
272
|
+
}
|
273
|
+
}
|
274
|
+
|
275
|
+
static void BitknitCopyShortDist(byte *dst, size_t dist, size_t length) {
|
276
|
+
const byte *src = dst - dist;
|
277
|
+
if (dist >= 4) {
|
278
|
+
((uint32*)dst)[0] = ((uint32*)src)[0];
|
279
|
+
((uint32*)dst)[1] = ((uint32*)src)[1];
|
280
|
+
((uint32*)dst)[2] = ((uint32*)src)[2];
|
281
|
+
if (length > 12) {
|
282
|
+
((uint32*)dst)[3] = ((uint32*)src)[3];
|
283
|
+
if (length > 16) {
|
284
|
+
do {
|
285
|
+
((uint32*)dst)[4] = ((uint32*)src)[4];
|
286
|
+
length -= 4;
|
287
|
+
dst += 4;
|
288
|
+
src += 4;
|
289
|
+
} while (length > 16);
|
290
|
+
}
|
291
|
+
}
|
292
|
+
} else if (dist == 1) {
|
293
|
+
memset(dst, *src, length);
|
294
|
+
} else {
|
295
|
+
((byte*)dst)[0] = ((byte*)src)[0];
|
296
|
+
((byte*)dst)[1] = ((byte*)src)[1];
|
297
|
+
((byte*)dst)[2] = ((byte*)src)[2];
|
298
|
+
((byte*)dst)[3] = ((byte*)src)[3];
|
299
|
+
((byte*)dst)[4] = ((byte*)src)[4];
|
300
|
+
((byte*)dst)[5] = ((byte*)src)[5];
|
301
|
+
((byte*)dst)[6] = ((byte*)src)[6];
|
302
|
+
((byte*)dst)[7] = ((byte*)src)[7];
|
303
|
+
((byte*)dst)[8] = ((byte*)src)[8];
|
304
|
+
while (length > 9) {
|
305
|
+
((byte*)dst)[9] = ((byte*)src)[9];
|
306
|
+
dst += 1;
|
307
|
+
src += 1;
|
308
|
+
length -= 1;
|
309
|
+
}
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
313
|
+
|
314
|
+
size_t Bitknit_Decode(const byte *src, const byte *src_end, byte *dst, byte *dst_end, byte *dst_start, BitknitState *bk) {
|
315
|
+
const byte *src_in = src;
|
316
|
+
BitknitLiteral *litmodel[4];
|
317
|
+
BitknitDistanceLsb *distancelsb[4];
|
318
|
+
size_t i;
|
319
|
+
intptr_t last_match_negative;
|
320
|
+
uint32 bits, bits2, bitst;
|
321
|
+
uint32 v, a, n;
|
322
|
+
uint32 copy_length;
|
323
|
+
uint32 recent_dist_mask;
|
324
|
+
uint32 match_dist;
|
325
|
+
|
326
|
+
for (i = 0; i < 4; i++)
|
327
|
+
litmodel[i] = &bk->literals[(i - (intptr_t)dst_start) & 3];
|
328
|
+
|
329
|
+
for (i = 0; i < 4; i++)
|
330
|
+
distancelsb[i] = &bk->distance_lsb[(i - (intptr_t)dst_start) & 3];
|
331
|
+
|
332
|
+
|
333
|
+
recent_dist_mask = bk->recent_dist_mask;
|
334
|
+
bits = 0x10000;
|
335
|
+
bits2 = 0x10000;
|
336
|
+
last_match_negative = -(intptr_t)bk->last_match_dist;
|
337
|
+
|
338
|
+
v = *(uint32*)src, src += 4;
|
339
|
+
if (v < 0x10000)
|
340
|
+
return 0;
|
341
|
+
|
342
|
+
a = v >> 4;
|
343
|
+
n = v & 0xF;
|
344
|
+
if (a < 0x10000)
|
345
|
+
a = (a << 16) | *(uint16*)src, src += 2;
|
346
|
+
bits = a >> n;
|
347
|
+
if (bits < 0x10000)
|
348
|
+
bits = (bits << 16) | *(uint16*)src, src += 2;
|
349
|
+
a = (a << 16) | *(uint16*)src, src += 2;
|
350
|
+
|
351
|
+
bits2 = (1 << (n + 16)) | (a & ((1 << (n + 16)) - 1));
|
352
|
+
|
353
|
+
if (dst == dst_start) {
|
354
|
+
*dst++ = bits;
|
355
|
+
bits >>= 8;
|
356
|
+
RENORMALIZE();
|
357
|
+
}
|
358
|
+
|
359
|
+
while (dst + 4 < dst_end) {
|
360
|
+
uint32 sym = BitknitLiteral_Lookup(litmodel[(intptr_t)dst & 3], &bits);
|
361
|
+
RENORMALIZE();
|
362
|
+
|
363
|
+
if (sym < 256) {
|
364
|
+
*dst = sym + dst[last_match_negative];
|
365
|
+
dst++;
|
366
|
+
|
367
|
+
if (dst + 4 >= dst_end)
|
368
|
+
break;
|
369
|
+
|
370
|
+
sym = BitknitLiteral_Lookup(litmodel[(intptr_t)dst & 3], &bits);
|
371
|
+
RENORMALIZE();
|
372
|
+
|
373
|
+
if (sym < 256) {
|
374
|
+
*dst = sym + dst[last_match_negative];
|
375
|
+
dst++;
|
376
|
+
continue;
|
377
|
+
}
|
378
|
+
}
|
379
|
+
|
380
|
+
if (sym >= 288) {
|
381
|
+
uint32 nb = sym - 287;
|
382
|
+
sym = (bits & ((1 << nb) - 1)) + (1 << nb) + 286;
|
383
|
+
bits >>= nb;
|
384
|
+
RENORMALIZE();
|
385
|
+
}
|
386
|
+
|
387
|
+
copy_length = sym - 254;
|
388
|
+
|
389
|
+
sym = BitknitDistanceLsb_Lookup(distancelsb[(intptr_t)dst & 3], &bits);
|
390
|
+
RENORMALIZE();
|
391
|
+
|
392
|
+
if (sym >= 8) {
|
393
|
+
uint32 nb = BitknitDistanceBits_Lookup(&bk->distance_bits, &bits);
|
394
|
+
RENORMALIZE();
|
395
|
+
|
396
|
+
match_dist = bits & ((1 << (nb & 0xF)) - 1);
|
397
|
+
bits >>= (nb & 0xF);
|
398
|
+
RENORMALIZE();
|
399
|
+
if (nb >= 0x10)
|
400
|
+
match_dist = (match_dist << 16) | *(uint16*)src, src += 2;
|
401
|
+
match_dist = (32 << nb) + (match_dist << 5) + sym - 39;
|
402
|
+
|
403
|
+
bk->recent_dist[(recent_dist_mask >> 21) & 7] = bk->recent_dist[(recent_dist_mask >> 18) & 7];
|
404
|
+
bk->recent_dist[(recent_dist_mask >> 18) & 7] = match_dist;
|
405
|
+
|
406
|
+
} else {
|
407
|
+
size_t idx = (recent_dist_mask >> (3 * sym)) & 7;
|
408
|
+
uint32 mask = ~7 << (3 * sym);
|
409
|
+
match_dist = bk->recent_dist[idx];
|
410
|
+
recent_dist_mask = (recent_dist_mask & mask) | ((idx + 8 * recent_dist_mask) & ~mask);
|
411
|
+
}
|
412
|
+
|
413
|
+
if (match_dist >= 8) {
|
414
|
+
BitknitCopyLongDist(dst, match_dist, copy_length);
|
415
|
+
} else {
|
416
|
+
BitknitCopyShortDist(dst, match_dist, copy_length);
|
417
|
+
}
|
418
|
+
|
419
|
+
dst += copy_length;
|
420
|
+
|
421
|
+
last_match_negative = -(intptr_t)match_dist;
|
422
|
+
}
|
423
|
+
*(uint32*)dst = (uint16)bits | bits2 << 16;
|
424
|
+
|
425
|
+
bk->last_match_dist = -last_match_negative;
|
426
|
+
bk->recent_dist_mask = recent_dist_mask;
|
427
|
+
return src - src_in;
|
428
|
+
}
|
429
|
+
|