libmspack 0.0.5 → 0.10.1.2
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 +5 -5
- data/.github/workflows/rake.yml +37 -0
- data/.gitignore +2 -0
- data/.yardopts +1 -1
- data/README.md +1 -1
- data/Rakefile +11 -5
- data/ext/Rakefile +1 -1
- data/ext/libmspack/AUTHORS +1 -0
- data/ext/libmspack/ChangeLog +321 -4
- data/ext/libmspack/INSTALL +368 -0
- data/ext/libmspack/Makefile.am +86 -95
- data/ext/libmspack/Makefile.in +1729 -0
- data/ext/libmspack/README +30 -30
- data/ext/libmspack/acinclude.m4 +99 -0
- data/ext/libmspack/aclocal.m4 +1218 -0
- data/ext/libmspack/ar-lib +270 -0
- data/ext/libmspack/compile +347 -0
- data/ext/libmspack/config.guess +1480 -0
- data/ext/libmspack/config.h.in +129 -0
- data/ext/libmspack/config.sub +1801 -0
- data/ext/libmspack/configure +15487 -0
- data/ext/libmspack/configure.ac +11 -13
- data/ext/libmspack/depcomp +791 -0
- data/ext/libmspack/install-sh +508 -0
- data/ext/libmspack/libmscabd.la +41 -0
- data/ext/libmspack/libmschmd.la +41 -0
- data/ext/libmspack/libmspack.la +41 -0
- data/ext/libmspack/ltmain.sh +11156 -0
- data/ext/libmspack/m4/libtool.m4 +8387 -0
- data/ext/libmspack/m4/ltoptions.m4 +437 -0
- data/ext/libmspack/m4/ltsugar.m4 +124 -0
- data/ext/libmspack/m4/ltversion.m4 +23 -0
- data/ext/libmspack/m4/lt~obsolete.m4 +99 -0
- data/ext/libmspack/missing +215 -0
- data/ext/libmspack/mspack/cab.h +20 -7
- data/ext/libmspack/mspack/cabd.c +301 -236
- data/ext/libmspack/mspack/chmd.c +304 -319
- data/ext/libmspack/mspack/crc32.c +52 -52
- data/ext/libmspack/mspack/crc32.h +1 -1
- data/ext/libmspack/mspack/kwajd.c +178 -172
- data/ext/libmspack/mspack/lzss.h +4 -4
- data/ext/libmspack/mspack/lzssd.c +42 -42
- data/ext/libmspack/mspack/lzx.h +11 -11
- data/ext/libmspack/mspack/lzxd.c +370 -361
- data/ext/libmspack/mspack/mspack.h +109 -77
- data/ext/libmspack/mspack/mszip.h +6 -6
- data/ext/libmspack/mspack/mszipd.c +140 -139
- data/ext/libmspack/mspack/oab.h +1 -0
- data/ext/libmspack/mspack/oabd.c +71 -73
- data/ext/libmspack/mspack/qtm.h +4 -4
- data/ext/libmspack/mspack/qtmd.c +118 -117
- data/ext/libmspack/mspack/readbits.h +52 -52
- data/ext/libmspack/mspack/readhuff.h +61 -61
- data/ext/libmspack/mspack/system.c +15 -9
- data/ext/libmspack/mspack/system.h +38 -50
- data/ext/libmspack/mspack/szddd.c +35 -35
- data/ext/libmspack/test-driver +148 -0
- data/ext/x86_64-linux/libmspack.so +0 -0
- data/ext/x86_64-windows/mspack.dll +0 -0
- data/lib/libmspack/version.rb +2 -1
- data/lib/libmspack.rb +1 -1
- data/libmspack.gemspec +4 -4
- data/spec/libmspack_spec.rb +5 -4
- metadata +38 -105
- data/.travis.yml +0 -5
- data/ext/i386-windows/libmspack.dll +0 -0
- data/ext/libmspack/cleanup.sh +0 -9
- data/ext/libmspack/debian/changelog +0 -6
- data/ext/libmspack/debian/control +0 -14
- data/ext/libmspack/debian/rules +0 -101
- data/ext/libmspack/doc/Doxyfile.in +0 -22
- data/ext/libmspack/doc/Makefile.in +0 -14
- data/ext/libmspack/doc/szdd_kwaj_format.html +0 -331
- data/ext/libmspack/mspack/mspack.def +0 -28
- data/ext/libmspack/mspack/qtmc.c +0 -18
- data/ext/libmspack/rebuild.sh +0 -8
- data/ext/libmspack/test/cabd_c10 +0 -19
- data/ext/libmspack/test/cabd_compare +0 -34
- data/ext/libmspack/test/cabd_md5.c +0 -161
- data/ext/libmspack/test/cabd_memory.c +0 -179
- data/ext/libmspack/test/cabd_test.c +0 -386
- data/ext/libmspack/test/cabrip.c +0 -81
- data/ext/libmspack/test/chmd_compare +0 -38
- data/ext/libmspack/test/chmd_find.c +0 -95
- data/ext/libmspack/test/chmd_md5.c +0 -67
- data/ext/libmspack/test/chmd_order.c +0 -144
- data/ext/libmspack/test/chminfo.c +0 -284
- data/ext/libmspack/test/chmx.c +0 -216
- data/ext/libmspack/test/error.h +0 -22
- data/ext/libmspack/test/expand.c +0 -79
- data/ext/libmspack/test/md5.c +0 -457
- data/ext/libmspack/test/md5.h +0 -165
- data/ext/libmspack/test/md5_fh.h +0 -123
- data/ext/libmspack/test/msdecompile_md5 +0 -24
- data/ext/libmspack/test/msexpand_md5 +0 -39
- data/ext/libmspack/test/multifh.c +0 -435
- data/ext/libmspack/test/oabx.c +0 -41
- data/ext/libmspack/test/test_files/cabd/1.pl +0 -84
- data/ext/libmspack/test/test_files/cabd/2.pl +0 -75
- data/ext/libmspack/test/test_files/cabd/bad_folderindex.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_nofiles.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_nofolders.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_signature.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt1.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt2.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt3.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt4.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt5.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/normal_255c_filename.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/normal_2files_1folder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nodata.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nofiles.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nofolder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortextheader.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfile1.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfile2.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfolder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortheader.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nofname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_noninfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nonname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nopinfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nopname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortfname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortninfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortnname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortpinfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortpname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_---.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_--D.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_-F-.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_-FD.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_H--.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_H-D.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_HF-.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_HFD.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/search_basic.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/search_tricky1.cab +0 -0
- data/ext/libmspack/winbuild.sh +0 -26
- data/ext/libmspack.h +0 -259
- data/ext/x86_64-windows/libmspack.dll +0 -0
data/ext/libmspack/mspack/lzxd.c
CHANGED
|
@@ -83,11 +83,11 @@
|
|
|
83
83
|
#define BITS_TYPE struct lzxd_stream
|
|
84
84
|
#define BITS_VAR lzx
|
|
85
85
|
#define BITS_ORDER_MSB
|
|
86
|
-
#define READ_BYTES do {
|
|
87
|
-
unsigned char b0, b1;
|
|
88
|
-
READ_IF_NEEDED; b0 = *i_ptr++;
|
|
89
|
-
READ_IF_NEEDED; b1 = *i_ptr++;
|
|
90
|
-
INJECT_BITS((b1 << 8) | b0, 16);
|
|
86
|
+
#define READ_BYTES do { \
|
|
87
|
+
unsigned char b0, b1; \
|
|
88
|
+
READ_IF_NEEDED; b0 = *i_ptr++; \
|
|
89
|
+
READ_IF_NEEDED; b1 = *i_ptr++; \
|
|
90
|
+
INJECT_BITS((b1 << 8) | b0, 16); \
|
|
91
91
|
} while (0)
|
|
92
92
|
#include <readbits.h>
|
|
93
93
|
|
|
@@ -100,43 +100,43 @@
|
|
|
100
100
|
#include <readhuff.h>
|
|
101
101
|
|
|
102
102
|
/* BUILD_TABLE(tbl) builds a huffman lookup table from code lengths */
|
|
103
|
-
#define BUILD_TABLE(tbl)
|
|
104
|
-
if (make_decode_table(MAXSYMBOLS(tbl), TABLEBITS(tbl),
|
|
105
|
-
|
|
106
|
-
{
|
|
107
|
-
D(("failed to build %s table", #tbl))
|
|
108
|
-
|
|
103
|
+
#define BUILD_TABLE(tbl) \
|
|
104
|
+
if (make_decode_table(MAXSYMBOLS(tbl), TABLEBITS(tbl), \
|
|
105
|
+
&HUFF_LEN(tbl,0), &HUFF_TABLE(tbl,0))) \
|
|
106
|
+
{ \
|
|
107
|
+
D(("failed to build %s table", #tbl)) \
|
|
108
|
+
return lzx->error = MSPACK_ERR_DECRUNCH; \
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
#define BUILD_TABLE_MAYBE_EMPTY(tbl) do {
|
|
112
|
-
lzx->tbl##_empty = 0;
|
|
113
|
-
if (make_decode_table(MAXSYMBOLS(tbl), TABLEBITS(tbl),
|
|
114
|
-
&HUFF_LEN(tbl,0), &HUFF_TABLE(tbl,0)))
|
|
115
|
-
{
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
111
|
+
#define BUILD_TABLE_MAYBE_EMPTY(tbl) do { \
|
|
112
|
+
lzx->tbl##_empty = 0; \
|
|
113
|
+
if (make_decode_table(MAXSYMBOLS(tbl), TABLEBITS(tbl), \
|
|
114
|
+
&HUFF_LEN(tbl,0), &HUFF_TABLE(tbl,0))) \
|
|
115
|
+
{ \
|
|
116
|
+
for (i = 0; i < MAXSYMBOLS(tbl); i++) { \
|
|
117
|
+
if (HUFF_LEN(tbl, i) > 0) { \
|
|
118
|
+
D(("failed to build %s table", #tbl)) \
|
|
119
|
+
return lzx->error = MSPACK_ERR_DECRUNCH; \
|
|
120
|
+
} \
|
|
121
|
+
} \
|
|
122
|
+
/* empty tree - allow it, but don't decode symbols with it */ \
|
|
123
|
+
lzx->tbl##_empty = 1; \
|
|
124
|
+
} \
|
|
125
125
|
} while (0)
|
|
126
126
|
|
|
127
127
|
/* READ_LENGTHS(tablename, first, last) reads in code lengths for symbols
|
|
128
128
|
* first to last in the given table. The code lengths are stored in their
|
|
129
129
|
* own special LZX way.
|
|
130
130
|
*/
|
|
131
|
-
#define READ_LENGTHS(tbl, first, last) do {
|
|
132
|
-
STORE_BITS;
|
|
133
|
-
if (lzxd_read_lens(lzx, &HUFF_LEN(tbl, 0), (first),
|
|
134
|
-
(unsigned int)(last))) return lzx->error;
|
|
135
|
-
RESTORE_BITS;
|
|
131
|
+
#define READ_LENGTHS(tbl, first, last) do { \
|
|
132
|
+
STORE_BITS; \
|
|
133
|
+
if (lzxd_read_lens(lzx, &HUFF_LEN(tbl, 0), (first), \
|
|
134
|
+
(unsigned int)(last))) return lzx->error; \
|
|
135
|
+
RESTORE_BITS; \
|
|
136
136
|
} while (0)
|
|
137
137
|
|
|
138
138
|
static int lzxd_read_lens(struct lzxd_stream *lzx, unsigned char *lens,
|
|
139
|
-
|
|
139
|
+
unsigned int first, unsigned int last)
|
|
140
140
|
{
|
|
141
141
|
/* bit buffer and huffman symbol decode variables */
|
|
142
142
|
register unsigned int bit_buffer;
|
|
@@ -277,13 +277,13 @@ static void lzxd_reset_state(struct lzxd_stream *lzx) {
|
|
|
277
277
|
/*-------- main LZX code --------*/
|
|
278
278
|
|
|
279
279
|
struct lzxd_stream *lzxd_init(struct mspack_system *system,
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
280
|
+
struct mspack_file *input,
|
|
281
|
+
struct mspack_file *output,
|
|
282
|
+
int window_bits,
|
|
283
|
+
int reset_interval,
|
|
284
|
+
int input_buffer_size,
|
|
285
|
+
off_t output_length,
|
|
286
|
+
char is_delta)
|
|
287
287
|
{
|
|
288
288
|
unsigned int window_size = 1 << window_bits;
|
|
289
289
|
struct lzxd_stream *lzx;
|
|
@@ -300,8 +300,14 @@ struct lzxd_stream *lzxd_init(struct mspack_system *system,
|
|
|
300
300
|
if (window_bits < 15 || window_bits > 21) return NULL;
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
+
if (reset_interval < 0 || output_length < 0) {
|
|
304
|
+
D(("reset interval or output length < 0"))
|
|
305
|
+
return NULL;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/* round up input buffer size to multiple of two */
|
|
303
309
|
input_buffer_size = (input_buffer_size + 1) & -2;
|
|
304
|
-
if (
|
|
310
|
+
if (input_buffer_size < 2) return NULL;
|
|
305
311
|
|
|
306
312
|
/* allocate decompression state */
|
|
307
313
|
if (!(lzx = (struct lzxd_stream *) system->alloc(system, sizeof(struct lzxd_stream)))) {
|
|
@@ -346,9 +352,9 @@ struct lzxd_stream *lzxd_init(struct mspack_system *system,
|
|
|
346
352
|
}
|
|
347
353
|
|
|
348
354
|
int lzxd_set_reference_data(struct lzxd_stream *lzx,
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
355
|
+
struct mspack_system *system,
|
|
356
|
+
struct mspack_file *input,
|
|
357
|
+
unsigned int length)
|
|
352
358
|
{
|
|
353
359
|
if (!lzx) return MSPACK_ERR_ARGS;
|
|
354
360
|
|
|
@@ -357,12 +363,12 @@ int lzxd_set_reference_data(struct lzxd_stream *lzx,
|
|
|
357
363
|
return MSPACK_ERR_ARGS;
|
|
358
364
|
}
|
|
359
365
|
if (lzx->offset) {
|
|
360
|
-
|
|
361
|
-
|
|
366
|
+
D(("too late to set reference data after decoding starts"))
|
|
367
|
+
return MSPACK_ERR_ARGS;
|
|
362
368
|
}
|
|
363
369
|
if (length > lzx->window_size) {
|
|
364
|
-
|
|
365
|
-
|
|
370
|
+
D(("reference length (%u) is longer than the window", length))
|
|
371
|
+
return MSPACK_ERR_ARGS;
|
|
366
372
|
}
|
|
367
373
|
if (length > 0 && (!system || !input)) {
|
|
368
374
|
D(("length > 0 but no system or input"))
|
|
@@ -373,16 +379,16 @@ int lzxd_set_reference_data(struct lzxd_stream *lzx,
|
|
|
373
379
|
if (length > 0) {
|
|
374
380
|
/* copy reference data */
|
|
375
381
|
unsigned char *pos = &lzx->window[lzx->window_size - length];
|
|
376
|
-
|
|
382
|
+
int bytes = system->read(input, pos, length);
|
|
377
383
|
/* length can't be more than 2^25, so no signedness problem */
|
|
378
|
-
|
|
384
|
+
if (bytes < (int)length) return MSPACK_ERR_READ;
|
|
379
385
|
}
|
|
380
386
|
lzx->ref_data_size = length;
|
|
381
387
|
return MSPACK_ERR_OK;
|
|
382
388
|
}
|
|
383
389
|
|
|
384
390
|
void lzxd_set_output_length(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
385
|
-
if (lzx) lzx->length = out_bytes;
|
|
391
|
+
if (lzx && out_bytes > 0) lzx->length = out_bytes;
|
|
386
392
|
}
|
|
387
393
|
|
|
388
394
|
int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
@@ -393,7 +399,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
|
393
399
|
register unsigned short sym;
|
|
394
400
|
|
|
395
401
|
int match_length, length_footer, extra, verbatim_bits, bytes_todo;
|
|
396
|
-
int this_run, main_element, aligned_bits, j;
|
|
402
|
+
int this_run, main_element, aligned_bits, j, warned = 0;
|
|
397
403
|
unsigned char *window, *runsrc, *rundest, buf[12];
|
|
398
404
|
unsigned int frame_size=0, end_frame, match_offset, window_posn;
|
|
399
405
|
unsigned int R0, R1, R2;
|
|
@@ -429,8 +435,12 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
|
429
435
|
/* have we reached the reset interval? (if there is one?) */
|
|
430
436
|
if (lzx->reset_interval && ((lzx->frame % lzx->reset_interval) == 0)) {
|
|
431
437
|
if (lzx->block_remaining) {
|
|
432
|
-
|
|
433
|
-
|
|
438
|
+
/* this is a file format error, we can make a best effort to extract what we can */
|
|
439
|
+
D(("%d bytes remaining at reset interval", lzx->block_remaining))
|
|
440
|
+
if (!warned) {
|
|
441
|
+
lzx->sys->message(NULL, "WARNING; invalid reset interval detected during LZX decompression");
|
|
442
|
+
warned++;
|
|
443
|
+
}
|
|
434
444
|
}
|
|
435
445
|
|
|
436
446
|
/* re-read the intel header and reset the huffman lengths */
|
|
@@ -468,62 +478,61 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
|
468
478
|
while (bytes_todo > 0) {
|
|
469
479
|
/* initialise new block, if one is needed */
|
|
470
480
|
if (lzx->block_remaining == 0) {
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
}
|
|
481
|
+
/* realign if previous block was an odd-sized UNCOMPRESSED block */
|
|
482
|
+
if ((lzx->block_type == LZX_BLOCKTYPE_UNCOMPRESSED) &&
|
|
483
|
+
(lzx->block_length & 1))
|
|
484
|
+
{
|
|
485
|
+
READ_IF_NEEDED;
|
|
486
|
+
i_ptr++;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/* read block type (3 bits) and block length (24 bits) */
|
|
490
|
+
READ_BITS(lzx->block_type, 3);
|
|
491
|
+
READ_BITS(i, 16); READ_BITS(j, 8);
|
|
492
|
+
lzx->block_remaining = lzx->block_length = (i << 8) | j;
|
|
493
|
+
/*D(("new block t%d len %u", lzx->block_type, lzx->block_length))*/
|
|
494
|
+
|
|
495
|
+
/* read individual block headers */
|
|
496
|
+
switch (lzx->block_type) {
|
|
497
|
+
case LZX_BLOCKTYPE_ALIGNED:
|
|
498
|
+
/* read lengths of and build aligned huffman decoding tree */
|
|
499
|
+
for (i = 0; i < 8; i++) { READ_BITS(j, 3); lzx->ALIGNED_len[i] = j; }
|
|
500
|
+
BUILD_TABLE(ALIGNED);
|
|
501
|
+
/* rest of aligned header is same as verbatim */ /*@fallthrough@*/
|
|
502
|
+
case LZX_BLOCKTYPE_VERBATIM:
|
|
503
|
+
/* read lengths of and build main huffman decoding tree */
|
|
504
|
+
READ_LENGTHS(MAINTREE, 0, 256);
|
|
505
|
+
READ_LENGTHS(MAINTREE, 256, LZX_NUM_CHARS + lzx->num_offsets);
|
|
506
|
+
BUILD_TABLE(MAINTREE);
|
|
507
|
+
/* if the literal 0xE8 is anywhere in the block... */
|
|
508
|
+
if (lzx->MAINTREE_len[0xE8] != 0) lzx->intel_started = 1;
|
|
509
|
+
/* read lengths of and build lengths huffman decoding tree */
|
|
510
|
+
READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS);
|
|
511
|
+
BUILD_TABLE_MAYBE_EMPTY(LENGTH);
|
|
512
|
+
break;
|
|
513
|
+
|
|
514
|
+
case LZX_BLOCKTYPE_UNCOMPRESSED:
|
|
515
|
+
/* because we can't assume otherwise */
|
|
516
|
+
lzx->intel_started = 1;
|
|
517
|
+
|
|
518
|
+
/* read 1-16 (not 0-15) bits to align to bytes */
|
|
519
|
+
if (bits_left == 0) ENSURE_BITS(16);
|
|
520
|
+
bits_left = 0; bit_buffer = 0;
|
|
521
|
+
|
|
522
|
+
/* read 12 bytes of stored R0 / R1 / R2 values */
|
|
523
|
+
for (rundest = &buf[0], i = 0; i < 12; i++) {
|
|
524
|
+
READ_IF_NEEDED;
|
|
525
|
+
*rundest++ = *i_ptr++;
|
|
526
|
+
}
|
|
527
|
+
R0 = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
|
528
|
+
R1 = buf[4] | (buf[5] << 8) | (buf[6] << 16) | (buf[7] << 24);
|
|
529
|
+
R2 = buf[8] | (buf[9] << 8) | (buf[10] << 16) | (buf[11] << 24);
|
|
530
|
+
break;
|
|
531
|
+
|
|
532
|
+
default:
|
|
533
|
+
D(("bad block type"))
|
|
534
|
+
return lzx->error = MSPACK_ERR_DECRUNCH;
|
|
535
|
+
}
|
|
527
536
|
}
|
|
528
537
|
|
|
529
538
|
/* decode more of the block:
|
|
@@ -538,270 +547,270 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
|
538
547
|
/* decode at least this_run bytes */
|
|
539
548
|
switch (lzx->block_type) {
|
|
540
549
|
case LZX_BLOCKTYPE_VERBATIM:
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
550
|
+
while (this_run > 0) {
|
|
551
|
+
READ_HUFFSYM(MAINTREE, main_element);
|
|
552
|
+
if (main_element < LZX_NUM_CHARS) {
|
|
553
|
+
/* literal: 0 to LZX_NUM_CHARS-1 */
|
|
554
|
+
window[window_posn++] = main_element;
|
|
555
|
+
this_run--;
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
/* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
|
|
559
|
+
main_element -= LZX_NUM_CHARS;
|
|
560
|
+
|
|
561
|
+
/* get match length */
|
|
562
|
+
match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
|
|
563
|
+
if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
|
|
564
|
+
if (lzx->LENGTH_empty) {
|
|
556
565
|
D(("LENGTH symbol needed but tree is empty"))
|
|
557
566
|
return lzx->error = MSPACK_ERR_DECRUNCH;
|
|
558
567
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
568
|
+
READ_HUFFSYM(LENGTH, length_footer);
|
|
569
|
+
match_length += length_footer;
|
|
570
|
+
}
|
|
571
|
+
match_length += LZX_MIN_MATCH;
|
|
572
|
+
|
|
573
|
+
/* get match offset */
|
|
574
|
+
switch ((match_offset = (main_element >> 3))) {
|
|
575
|
+
case 0: match_offset = R0; break;
|
|
576
|
+
case 1: match_offset = R1; R1=R0; R0 = match_offset; break;
|
|
577
|
+
case 2: match_offset = R2; R2=R0; R0 = match_offset; break;
|
|
578
|
+
case 3: match_offset = 1; R2=R1; R1=R0; R0 = match_offset; break;
|
|
579
|
+
default:
|
|
580
|
+
extra = (match_offset >= 36) ? 17 : extra_bits[match_offset];
|
|
581
|
+
READ_BITS(verbatim_bits, extra);
|
|
582
|
+
match_offset = position_base[match_offset] - 2 + verbatim_bits;
|
|
583
|
+
R2 = R1; R1 = R0; R0 = match_offset;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/* LZX DELTA uses max match length to signal even longer match */
|
|
587
|
+
if (match_length == LZX_MAX_MATCH && lzx->is_delta) {
|
|
588
|
+
int extra_len = 0;
|
|
589
|
+
ENSURE_BITS(3); /* 4 entry huffman tree */
|
|
590
|
+
if (PEEK_BITS(1) == 0) {
|
|
591
|
+
REMOVE_BITS(1); /* '0' -> 8 extra length bits */
|
|
592
|
+
READ_BITS(extra_len, 8);
|
|
593
|
+
}
|
|
594
|
+
else if (PEEK_BITS(2) == 2) {
|
|
595
|
+
REMOVE_BITS(2); /* '10' -> 10 extra length bits + 0x100 */
|
|
596
|
+
READ_BITS(extra_len, 10);
|
|
597
|
+
extra_len += 0x100;
|
|
598
|
+
}
|
|
599
|
+
else if (PEEK_BITS(3) == 6) {
|
|
600
|
+
REMOVE_BITS(3); /* '110' -> 12 extra length bits + 0x500 */
|
|
601
|
+
READ_BITS(extra_len, 12);
|
|
602
|
+
extra_len += 0x500;
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
REMOVE_BITS(3); /* '111' -> 15 extra length bits */
|
|
606
|
+
READ_BITS(extra_len, 15);
|
|
607
|
+
}
|
|
608
|
+
match_length += extra_len;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
if ((window_posn + match_length) > lzx->window_size) {
|
|
612
|
+
D(("match ran over window wrap"))
|
|
613
|
+
return lzx->error = MSPACK_ERR_DECRUNCH;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/* copy match */
|
|
617
|
+
rundest = &window[window_posn];
|
|
618
|
+
i = match_length;
|
|
619
|
+
/* does match offset wrap the window? */
|
|
620
|
+
if (match_offset > window_posn) {
|
|
621
|
+
if (match_offset > lzx->offset &&
|
|
622
|
+
(match_offset - window_posn) > lzx->ref_data_size)
|
|
623
|
+
{
|
|
624
|
+
D(("match offset beyond LZX stream"))
|
|
625
|
+
return lzx->error = MSPACK_ERR_DECRUNCH;
|
|
626
|
+
}
|
|
627
|
+
/* j = length from match offset to end of window */
|
|
628
|
+
j = match_offset - window_posn;
|
|
629
|
+
if (j > (int) lzx->window_size) {
|
|
630
|
+
D(("match offset beyond window boundaries"))
|
|
631
|
+
return lzx->error = MSPACK_ERR_DECRUNCH;
|
|
632
|
+
}
|
|
633
|
+
runsrc = &window[lzx->window_size - j];
|
|
634
|
+
if (j < i) {
|
|
635
|
+
/* if match goes over the window edge, do two copy runs */
|
|
636
|
+
i -= j; while (j-- > 0) *rundest++ = *runsrc++;
|
|
637
|
+
runsrc = window;
|
|
638
|
+
}
|
|
639
|
+
while (i-- > 0) *rundest++ = *runsrc++;
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
runsrc = rundest - match_offset;
|
|
643
|
+
while (i-- > 0) *rundest++ = *runsrc++;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
this_run -= match_length;
|
|
647
|
+
window_posn += match_length;
|
|
648
|
+
}
|
|
649
|
+
} /* while (this_run > 0) */
|
|
650
|
+
break;
|
|
642
651
|
|
|
643
652
|
case LZX_BLOCKTYPE_ALIGNED:
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
653
|
+
while (this_run > 0) {
|
|
654
|
+
READ_HUFFSYM(MAINTREE, main_element);
|
|
655
|
+
if (main_element < LZX_NUM_CHARS) {
|
|
656
|
+
/* literal: 0 to LZX_NUM_CHARS-1 */
|
|
657
|
+
window[window_posn++] = main_element;
|
|
658
|
+
this_run--;
|
|
659
|
+
}
|
|
660
|
+
else {
|
|
661
|
+
/* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
|
|
662
|
+
main_element -= LZX_NUM_CHARS;
|
|
663
|
+
|
|
664
|
+
/* get match length */
|
|
665
|
+
match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
|
|
666
|
+
if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
|
|
658
667
|
if (lzx->LENGTH_empty) {
|
|
659
668
|
D(("LENGTH symbol needed but tree is empty"))
|
|
660
669
|
return lzx->error = MSPACK_ERR_DECRUNCH;
|
|
661
670
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
671
|
+
READ_HUFFSYM(LENGTH, length_footer);
|
|
672
|
+
match_length += length_footer;
|
|
673
|
+
}
|
|
674
|
+
match_length += LZX_MIN_MATCH;
|
|
675
|
+
|
|
676
|
+
/* get match offset */
|
|
677
|
+
switch ((match_offset = (main_element >> 3))) {
|
|
678
|
+
case 0: match_offset = R0; break;
|
|
679
|
+
case 1: match_offset = R1; R1 = R0; R0 = match_offset; break;
|
|
680
|
+
case 2: match_offset = R2; R2 = R0; R0 = match_offset; break;
|
|
681
|
+
default:
|
|
682
|
+
extra = (match_offset >= 36) ? 17 : extra_bits[match_offset];
|
|
683
|
+
match_offset = position_base[match_offset] - 2;
|
|
684
|
+
if (extra > 3) {
|
|
685
|
+
/* verbatim and aligned bits */
|
|
686
|
+
extra -= 3;
|
|
687
|
+
READ_BITS(verbatim_bits, extra);
|
|
688
|
+
match_offset += (verbatim_bits << 3);
|
|
689
|
+
READ_HUFFSYM(ALIGNED, aligned_bits);
|
|
690
|
+
match_offset += aligned_bits;
|
|
691
|
+
}
|
|
692
|
+
else if (extra == 3) {
|
|
693
|
+
/* aligned bits only */
|
|
694
|
+
READ_HUFFSYM(ALIGNED, aligned_bits);
|
|
695
|
+
match_offset += aligned_bits;
|
|
696
|
+
}
|
|
697
|
+
else if (extra > 0) { /* extra==1, extra==2 */
|
|
698
|
+
/* verbatim bits only */
|
|
699
|
+
READ_BITS(verbatim_bits, extra);
|
|
700
|
+
match_offset += verbatim_bits;
|
|
701
|
+
}
|
|
702
|
+
else /* extra == 0 */ {
|
|
703
|
+
/* ??? not defined in LZX specification! */
|
|
704
|
+
match_offset = 1;
|
|
705
|
+
}
|
|
706
|
+
/* update repeated offset LRU queue */
|
|
707
|
+
R2 = R1; R1 = R0; R0 = match_offset;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/* LZX DELTA uses max match length to signal even longer match */
|
|
711
|
+
if (match_length == LZX_MAX_MATCH && lzx->is_delta) {
|
|
712
|
+
int extra_len = 0;
|
|
713
|
+
ENSURE_BITS(3); /* 4 entry huffman tree */
|
|
714
|
+
if (PEEK_BITS(1) == 0) {
|
|
715
|
+
REMOVE_BITS(1); /* '0' -> 8 extra length bits */
|
|
716
|
+
READ_BITS(extra_len, 8);
|
|
717
|
+
}
|
|
718
|
+
else if (PEEK_BITS(2) == 2) {
|
|
719
|
+
REMOVE_BITS(2); /* '10' -> 10 extra length bits + 0x100 */
|
|
720
|
+
READ_BITS(extra_len, 10);
|
|
721
|
+
extra_len += 0x100;
|
|
722
|
+
}
|
|
723
|
+
else if (PEEK_BITS(3) == 6) {
|
|
724
|
+
REMOVE_BITS(3); /* '110' -> 12 extra length bits + 0x500 */
|
|
725
|
+
READ_BITS(extra_len, 12);
|
|
726
|
+
extra_len += 0x500;
|
|
727
|
+
}
|
|
728
|
+
else {
|
|
729
|
+
REMOVE_BITS(3); /* '111' -> 15 extra length bits */
|
|
730
|
+
READ_BITS(extra_len, 15);
|
|
731
|
+
}
|
|
732
|
+
match_length += extra_len;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
if ((window_posn + match_length) > lzx->window_size) {
|
|
736
|
+
D(("match ran over window wrap"))
|
|
737
|
+
return lzx->error = MSPACK_ERR_DECRUNCH;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/* copy match */
|
|
741
|
+
rundest = &window[window_posn];
|
|
742
|
+
i = match_length;
|
|
743
|
+
/* does match offset wrap the window? */
|
|
744
|
+
if (match_offset > window_posn) {
|
|
745
|
+
if (match_offset > lzx->offset &&
|
|
746
|
+
(match_offset - window_posn) > lzx->ref_data_size)
|
|
747
|
+
{
|
|
748
|
+
D(("match offset beyond LZX stream"))
|
|
749
|
+
return lzx->error = MSPACK_ERR_DECRUNCH;
|
|
750
|
+
}
|
|
751
|
+
/* j = length from match offset to end of window */
|
|
752
|
+
j = match_offset - window_posn;
|
|
753
|
+
if (j > (int) lzx->window_size) {
|
|
754
|
+
D(("match offset beyond window boundaries"))
|
|
755
|
+
return lzx->error = MSPACK_ERR_DECRUNCH;
|
|
756
|
+
}
|
|
757
|
+
runsrc = &window[lzx->window_size - j];
|
|
758
|
+
if (j < i) {
|
|
759
|
+
/* if match goes over the window edge, do two copy runs */
|
|
760
|
+
i -= j; while (j-- > 0) *rundest++ = *runsrc++;
|
|
761
|
+
runsrc = window;
|
|
762
|
+
}
|
|
763
|
+
while (i-- > 0) *rundest++ = *runsrc++;
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
runsrc = rundest - match_offset;
|
|
767
|
+
while (i-- > 0) *rundest++ = *runsrc++;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
this_run -= match_length;
|
|
771
|
+
window_posn += match_length;
|
|
772
|
+
}
|
|
773
|
+
} /* while (this_run > 0) */
|
|
774
|
+
break;
|
|
766
775
|
|
|
767
776
|
case LZX_BLOCKTYPE_UNCOMPRESSED:
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
777
|
+
/* as this_run is limited not to wrap a frame, this also means it
|
|
778
|
+
* won't wrap the window (as the window is a multiple of 32k) */
|
|
779
|
+
rundest = &window[window_posn];
|
|
780
|
+
window_posn += this_run;
|
|
781
|
+
while (this_run > 0) {
|
|
782
|
+
if ((i = i_end - i_ptr) == 0) {
|
|
783
|
+
READ_IF_NEEDED;
|
|
784
|
+
}
|
|
785
|
+
else {
|
|
786
|
+
if (i > this_run) i = this_run;
|
|
787
|
+
lzx->sys->copy(i_ptr, rundest, (size_t) i);
|
|
788
|
+
rundest += i;
|
|
789
|
+
i_ptr += i;
|
|
790
|
+
this_run -= i;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
break;
|
|
785
794
|
|
|
786
795
|
default:
|
|
787
|
-
|
|
796
|
+
return lzx->error = MSPACK_ERR_DECRUNCH; /* might as well */
|
|
788
797
|
}
|
|
789
798
|
|
|
790
799
|
/* did the final match overrun our desired this_run length? */
|
|
791
800
|
if (this_run < 0) {
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
801
|
+
if ((unsigned int)(-this_run) > lzx->block_remaining) {
|
|
802
|
+
D(("overrun went past end of block by %d (%d remaining)",
|
|
803
|
+
-this_run, lzx->block_remaining ))
|
|
804
|
+
return lzx->error = MSPACK_ERR_DECRUNCH;
|
|
805
|
+
}
|
|
806
|
+
lzx->block_remaining -= -this_run;
|
|
798
807
|
}
|
|
799
808
|
} /* while (bytes_todo > 0) */
|
|
800
809
|
|
|
801
810
|
/* streams don't extend over frame boundaries */
|
|
802
811
|
if ((window_posn - lzx->frame_posn) != frame_size) {
|
|
803
812
|
D(("decode beyond output frame limits! %d != %d",
|
|
804
|
-
|
|
813
|
+
window_posn - lzx->frame_posn, frame_size))
|
|
805
814
|
return lzx->error = MSPACK_ERR_DECRUNCH;
|
|
806
815
|
}
|
|
807
816
|
|
|
@@ -818,7 +827,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
|
818
827
|
|
|
819
828
|
/* does this intel block _really_ need decoding? */
|
|
820
829
|
if (lzx->intel_started && lzx->intel_filesize &&
|
|
821
|
-
|
|
830
|
+
(lzx->frame <= 32768) && (frame_size > 10))
|
|
822
831
|
{
|
|
823
832
|
unsigned char *data = &lzx->e8_buf[0];
|
|
824
833
|
unsigned char *dataend = &lzx->e8_buf[frame_size - 10];
|
|
@@ -831,17 +840,17 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
|
831
840
|
lzx->sys->copy(&lzx->window[lzx->frame_posn], data, frame_size);
|
|
832
841
|
|
|
833
842
|
while (data < dataend) {
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
843
|
+
if (*data++ != 0xE8) { curpos++; continue; }
|
|
844
|
+
abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
|
|
845
|
+
if ((abs_off >= -curpos) && (abs_off < filesize)) {
|
|
846
|
+
rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
|
|
847
|
+
data[0] = (unsigned char) rel_off;
|
|
848
|
+
data[1] = (unsigned char) (rel_off >> 8);
|
|
849
|
+
data[2] = (unsigned char) (rel_off >> 16);
|
|
850
|
+
data[3] = (unsigned char) (rel_off >> 24);
|
|
851
|
+
}
|
|
852
|
+
data += 4;
|
|
853
|
+
curpos += 5;
|
|
845
854
|
}
|
|
846
855
|
lzx->intel_curpos += frame_size;
|
|
847
856
|
}
|