oodle-kraken-ruby 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|