libmspack 0.10.1.2 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/ext/libmspack/ChangeLog +145 -0
- data/ext/libmspack/INSTALL +3 -3
- data/ext/libmspack/Makefile.am +7 -4
- data/ext/libmspack/Makefile.in +265 -147
- data/ext/libmspack/README +3 -2
- data/ext/libmspack/aclocal.m4 +111 -113
- data/ext/libmspack/ar-lib +10 -9
- data/ext/libmspack/compile +9 -8
- data/ext/libmspack/config.guess +887 -613
- data/ext/libmspack/config.h.in +6 -9
- data/ext/libmspack/config.sub +1349 -1260
- data/ext/libmspack/configure +3035 -2490
- data/ext/libmspack/configure.ac +3 -3
- data/ext/libmspack/depcomp +4 -4
- data/ext/libmspack/install-sh +107 -74
- data/ext/libmspack/libmscabd.la +1 -1
- data/ext/libmspack/libmschmd.la +1 -1
- data/ext/libmspack/libmspack.la +1 -1
- data/ext/libmspack/ltmain.sh +156 -61
- data/ext/libmspack/m4/libtool.m4 +19 -12
- data/ext/libmspack/missing +8 -8
- data/ext/libmspack/mspack/cabd.c +21 -19
- data/ext/libmspack/mspack/chm.h +3 -2
- data/ext/libmspack/mspack/chmd.c +137 -57
- data/ext/libmspack/mspack/kwajd.c +29 -29
- data/ext/libmspack/mspack/lzx.h +0 -1
- data/ext/libmspack/mspack/lzxd.c +30 -154
- data/ext/libmspack/mspack/macros.h +64 -0
- data/ext/libmspack/mspack/mszipd.c +7 -18
- data/ext/libmspack/mspack/qtmd.c +3 -5
- data/ext/libmspack/mspack/readbits.h +14 -5
- data/ext/libmspack/mspack/readhuff.h +26 -21
- data/ext/libmspack/mspack/system.c +0 -5
- data/ext/libmspack/mspack/system.h +20 -67
- data/ext/libmspack/test-driver +16 -11
- data/ext/x86_64-linux/libmspack.so +0 -0
- data/ext/x86_64-windows/mspack.dll +0 -0
- data/lib/libmspack/version.rb +1 -1
- metadata +4 -3
data/ext/libmspack/mspack/lzx.h
CHANGED
@@ -67,7 +67,6 @@ struct lzxd_stream {
|
|
67
67
|
unsigned int block_remaining; /* uncompressed bytes still left to decode */
|
68
68
|
|
69
69
|
signed int intel_filesize; /* magic header value used for transform */
|
70
|
-
signed int intel_curpos; /* current offset in transform space */
|
71
70
|
|
72
71
|
unsigned char intel_started; /* has intel E8 decoding started? */
|
73
72
|
unsigned char block_type; /* type of the current block */
|
data/ext/libmspack/mspack/lzxd.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/* This file is part of libmspack.
|
2
|
-
* (C) 2003-
|
2
|
+
* (C) 2003-2023 Stuart Caie.
|
3
3
|
*
|
4
4
|
* The LZX method was created by Jonathan Forbes and Tomi Poutanen, adapted
|
5
5
|
* by Microsoft Corporation.
|
@@ -138,12 +138,7 @@
|
|
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
|
-
|
142
|
-
register unsigned int bit_buffer;
|
143
|
-
register int bits_left, i;
|
144
|
-
register unsigned short sym;
|
145
|
-
unsigned char *i_ptr, *i_end;
|
146
|
-
|
141
|
+
DECLARE_HUFF_VARS;
|
147
142
|
unsigned int x, y;
|
148
143
|
int z;
|
149
144
|
|
@@ -315,8 +310,8 @@ struct lzxd_stream *lzxd_init(struct mspack_system *system,
|
|
315
310
|
}
|
316
311
|
|
317
312
|
/* allocate decompression window and input buffer */
|
318
|
-
lzx->window = (unsigned char *) system->alloc(system,
|
319
|
-
lzx->inbuf = (unsigned char *) system->alloc(system,
|
313
|
+
lzx->window = (unsigned char *) system->alloc(system, window_size);
|
314
|
+
lzx->inbuf = (unsigned char *) system->alloc(system, input_buffer_size);
|
320
315
|
if (!lzx->window || !lzx->inbuf) {
|
321
316
|
system->free(lzx->window);
|
322
317
|
system->free(lzx->inbuf);
|
@@ -339,7 +334,6 @@ struct lzxd_stream *lzxd_init(struct mspack_system *system,
|
|
339
334
|
lzx->frame = 0;
|
340
335
|
lzx->reset_interval = reset_interval;
|
341
336
|
lzx->intel_filesize = 0;
|
342
|
-
lzx->intel_curpos = 0;
|
343
337
|
lzx->intel_started = 0;
|
344
338
|
lzx->error = MSPACK_ERR_OK;
|
345
339
|
lzx->num_offsets = position_slots[window_bits - 15] << 3;
|
@@ -392,17 +386,10 @@ void lzxd_set_output_length(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
392
386
|
}
|
393
387
|
|
394
388
|
int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
register unsigned short sym;
|
400
|
-
|
401
|
-
int match_length, length_footer, extra, verbatim_bits, bytes_todo;
|
402
|
-
int this_run, main_element, aligned_bits, j, warned = 0;
|
403
|
-
unsigned char *window, *runsrc, *rundest, buf[12];
|
404
|
-
unsigned int frame_size=0, end_frame, match_offset, window_posn;
|
405
|
-
unsigned int R0, R1, R2;
|
389
|
+
DECLARE_HUFF_VARS;
|
390
|
+
unsigned char *window, *runsrc, *rundest, buf[12], warned = 0;
|
391
|
+
unsigned int frame_size, end_frame, window_posn, R0, R1, R2;
|
392
|
+
int bytes_todo, this_run, i, j;
|
406
393
|
|
407
394
|
/* easy answers */
|
408
395
|
if (!lzx || (out_bytes < 0)) return MSPACK_ERR_ARGS;
|
@@ -524,9 +511,9 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
524
511
|
READ_IF_NEEDED;
|
525
512
|
*rundest++ = *i_ptr++;
|
526
513
|
}
|
527
|
-
R0 = buf[0]
|
528
|
-
R1 = buf[4]
|
529
|
-
R2 =
|
514
|
+
R0 = EndGetI32(&buf[0]);
|
515
|
+
R1 = EndGetI32(&buf[4]);
|
516
|
+
R2 = EndGetI32(&buf[8]);
|
530
517
|
break;
|
531
518
|
|
532
519
|
default:
|
@@ -546,8 +533,12 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
546
533
|
|
547
534
|
/* decode at least this_run bytes */
|
548
535
|
switch (lzx->block_type) {
|
536
|
+
case LZX_BLOCKTYPE_ALIGNED:
|
549
537
|
case LZX_BLOCKTYPE_VERBATIM:
|
550
538
|
while (this_run > 0) {
|
539
|
+
int main_element, length_footer, verbatim_bits, aligned_bits, extra;
|
540
|
+
int match_length;
|
541
|
+
unsigned int match_offset;
|
551
542
|
READ_HUFFSYM(MAINTREE, main_element);
|
552
543
|
if (main_element < LZX_NUM_CHARS) {
|
553
544
|
/* literal: 0 to LZX_NUM_CHARS-1 */
|
@@ -572,137 +563,24 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
572
563
|
|
573
564
|
/* get match offset */
|
574
565
|
switch ((match_offset = (main_element >> 3))) {
|
575
|
-
case 0: match_offset = R0;
|
576
|
-
case 1: match_offset = R1; R1=R0;
|
577
|
-
case 2: match_offset = R2; R2=R0;
|
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;
|
651
|
-
|
652
|
-
case LZX_BLOCKTYPE_ALIGNED:
|
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) {
|
667
|
-
if (lzx->LENGTH_empty) {
|
668
|
-
D(("LENGTH symbol needed but tree is empty"))
|
669
|
-
return lzx->error = MSPACK_ERR_DECRUNCH;
|
670
|
-
}
|
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;
|
566
|
+
case 0: match_offset = R0; break;
|
567
|
+
case 1: match_offset = R1; R1=R0; R0 = match_offset; break;
|
568
|
+
case 2: match_offset = R2; R2=R0; R0 = match_offset; break;
|
681
569
|
default:
|
682
570
|
extra = (match_offset >= 36) ? 17 : extra_bits[match_offset];
|
683
571
|
match_offset = position_base[match_offset] - 2;
|
684
|
-
if (extra
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
READ_HUFFSYM(ALIGNED, aligned_bits);
|
690
|
-
match_offset += aligned_bits;
|
691
|
-
}
|
692
|
-
else if (extra == 3) {
|
693
|
-
/* aligned bits only */
|
572
|
+
if (extra >= 3 && lzx->block_type == LZX_BLOCKTYPE_ALIGNED) {
|
573
|
+
if (extra > 3) {
|
574
|
+
READ_BITS(verbatim_bits, extra - 3); /* 1-14 bits */
|
575
|
+
match_offset += verbatim_bits << 3;
|
576
|
+
}
|
694
577
|
READ_HUFFSYM(ALIGNED, aligned_bits);
|
695
578
|
match_offset += aligned_bits;
|
696
579
|
}
|
697
|
-
else if (extra
|
698
|
-
/*
|
699
|
-
READ_BITS(verbatim_bits, extra);
|
580
|
+
else if (extra) {
|
581
|
+
READ_BITS(verbatim_bits, extra); /* 1-17 bits */
|
700
582
|
match_offset += verbatim_bits;
|
701
583
|
}
|
702
|
-
else /* extra == 0 */ {
|
703
|
-
/* ??? not defined in LZX specification! */
|
704
|
-
match_offset = 1;
|
705
|
-
}
|
706
584
|
/* update repeated offset LRU queue */
|
707
585
|
R2 = R1; R1 = R0; R0 = match_offset;
|
708
586
|
}
|
@@ -742,7 +620,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
742
620
|
i = match_length;
|
743
621
|
/* does match offset wrap the window? */
|
744
622
|
if (match_offset > window_posn) {
|
745
|
-
|
623
|
+
if ((off_t)match_offset > lzx->offset &&
|
746
624
|
(match_offset - window_posn) > lzx->ref_data_size)
|
747
625
|
{
|
748
626
|
D(("match offset beyond LZX stream"))
|
@@ -784,7 +662,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
784
662
|
}
|
785
663
|
else {
|
786
664
|
if (i > this_run) i = this_run;
|
787
|
-
lzx->sys->copy(i_ptr, rundest,
|
665
|
+
lzx->sys->copy(i_ptr, rundest, i);
|
788
666
|
rundest += i;
|
789
667
|
i_ptr += i;
|
790
668
|
this_run -= i;
|
@@ -827,11 +705,11 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
827
705
|
|
828
706
|
/* does this intel block _really_ need decoding? */
|
829
707
|
if (lzx->intel_started && lzx->intel_filesize &&
|
830
|
-
(lzx->frame
|
708
|
+
(lzx->frame < 32768) && (frame_size > 10))
|
831
709
|
{
|
832
710
|
unsigned char *data = &lzx->e8_buf[0];
|
833
711
|
unsigned char *dataend = &lzx->e8_buf[frame_size - 10];
|
834
|
-
signed int curpos = lzx->
|
712
|
+
signed int curpos = (int) lzx->offset;
|
835
713
|
signed int filesize = lzx->intel_filesize;
|
836
714
|
signed int abs_off, rel_off;
|
837
715
|
|
@@ -841,7 +719,7 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
841
719
|
|
842
720
|
while (data < dataend) {
|
843
721
|
if (*data++ != 0xE8) { curpos++; continue; }
|
844
|
-
abs_off =
|
722
|
+
abs_off = EndGetI32(data);
|
845
723
|
if ((abs_off >= -curpos) && (abs_off < filesize)) {
|
846
724
|
rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
|
847
725
|
data[0] = (unsigned char) rel_off;
|
@@ -852,11 +730,9 @@ int lzxd_decompress(struct lzxd_stream *lzx, off_t out_bytes) {
|
|
852
730
|
data += 4;
|
853
731
|
curpos += 5;
|
854
732
|
}
|
855
|
-
lzx->intel_curpos += frame_size;
|
856
733
|
}
|
857
734
|
else {
|
858
735
|
lzx->o_ptr = &lzx->window[lzx->frame_posn];
|
859
|
-
if (lzx->intel_filesize) lzx->intel_curpos += frame_size;
|
860
736
|
}
|
861
737
|
lzx->o_end = &lzx->o_ptr[frame_size];
|
862
738
|
|
@@ -0,0 +1,64 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* (C) 2003-2020 Stuart Caie.
|
3
|
+
*
|
4
|
+
* libmspack is free software; you can redistribute it and/or modify it under
|
5
|
+
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
6
|
+
*
|
7
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
8
|
+
*/
|
9
|
+
|
10
|
+
#ifndef MSPACK_MACROS_H
|
11
|
+
#define MSPACK_MACROS_H 1
|
12
|
+
|
13
|
+
/* define LD and LU as printf-format for signed and unsigned long offsets */
|
14
|
+
#if HAVE_INTTYPES_H
|
15
|
+
# include <inttypes.h>
|
16
|
+
#else
|
17
|
+
# define PRId64 "lld"
|
18
|
+
# define PRIu64 "llu"
|
19
|
+
# define PRId32 "ld"
|
20
|
+
# define PRIu32 "lu"
|
21
|
+
#endif
|
22
|
+
|
23
|
+
#if SIZEOF_OFF_T >= 8
|
24
|
+
# define LD PRId64
|
25
|
+
# define LU PRIu64
|
26
|
+
#else
|
27
|
+
# define LD PRId32
|
28
|
+
# define LU PRIu32
|
29
|
+
#endif
|
30
|
+
|
31
|
+
/* endian-neutral reading of little-endian data */
|
32
|
+
#define __egi32(a,n) (((unsigned int) ((unsigned char *)(a))[n+3] << 24) | \
|
33
|
+
((unsigned int) ((unsigned char *)(a))[n+2] << 16) | \
|
34
|
+
((unsigned int) ((unsigned char *)(a))[n+1] << 8) | \
|
35
|
+
((unsigned int) ((unsigned char *)(a))[n]))
|
36
|
+
#define EndGetI64(a) (((unsigned long long int) __egi32(a,4) << 32) | __egi32(a,0))
|
37
|
+
#define EndGetI32(a) __egi32(a,0)
|
38
|
+
#define EndGetI16(a) ((((a)[1])<<8)|((a)[0]))
|
39
|
+
|
40
|
+
/* endian-neutral reading of big-endian data */
|
41
|
+
#define EndGetM32(a) (((unsigned int) ((unsigned char *)(a))[0] << 24) | \
|
42
|
+
((unsigned int) ((unsigned char *)(a))[1] << 16) | \
|
43
|
+
((unsigned int) ((unsigned char *)(a))[2] << 8) | \
|
44
|
+
((unsigned int) ((unsigned char *)(a))[3]))
|
45
|
+
#define EndGetM16(a) ((((a)[0])<<8)|((a)[1]))
|
46
|
+
|
47
|
+
/* D(("formatstring", args)) prints debug messages if DEBUG defined */
|
48
|
+
#if DEBUG
|
49
|
+
/* http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html */
|
50
|
+
# if __STDC_VERSION__ < 199901L
|
51
|
+
# if __GNUC__ >= 2
|
52
|
+
# define __func__ __FUNCTION__
|
53
|
+
# else
|
54
|
+
# define __func__ "<unknown>"
|
55
|
+
# endif
|
56
|
+
# endif
|
57
|
+
# include <stdio.h>
|
58
|
+
# define D(x) do { printf("%s:%d (%s) ",__FILE__, __LINE__, __func__); \
|
59
|
+
printf x ; fputc('\n', stdout); fflush(stdout);} while (0);
|
60
|
+
#else
|
61
|
+
# define D(x)
|
62
|
+
#endif
|
63
|
+
|
64
|
+
#endif
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/* This file is part of libmspack.
|
2
|
-
* (C) 2003-
|
2
|
+
* (C) 2003-2023 Stuart Caie.
|
3
3
|
*
|
4
4
|
* The deflate method was created by Phil Katz. MSZIP is equivalent to the
|
5
5
|
* deflate method.
|
@@ -89,10 +89,7 @@ static const unsigned char bitlen_order[19] = {
|
|
89
89
|
#define INF_ERR_HUFFSYM (-14) /* out of bits decoding huffman symbol */
|
90
90
|
|
91
91
|
static int zip_read_lens(struct mszipd_stream *zip) {
|
92
|
-
|
93
|
-
register unsigned int bit_buffer;
|
94
|
-
register int bits_left;
|
95
|
-
unsigned char *i_ptr, *i_end;
|
92
|
+
DECLARE_BIT_VARS;
|
96
93
|
|
97
94
|
/* bitlen Huffman codes -- immediate lookup, 7 bit max code length */
|
98
95
|
unsigned short bl_table[(1 << 7)];
|
@@ -155,13 +152,9 @@ static int zip_read_lens(struct mszipd_stream *zip) {
|
|
155
152
|
|
156
153
|
/* a clean implementation of RFC 1951 / inflate */
|
157
154
|
static int inflate(struct mszipd_stream *zip) {
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
register unsigned int bit_buffer;
|
162
|
-
register int bits_left;
|
163
|
-
register unsigned short sym;
|
164
|
-
unsigned char *i_ptr, *i_end;
|
155
|
+
DECLARE_HUFF_VARS;
|
156
|
+
unsigned int last_block, block_type, distance, length, this_run;
|
157
|
+
int i;
|
165
158
|
|
166
159
|
RESTORE_BITS;
|
167
160
|
|
@@ -359,7 +352,7 @@ struct mszipd_stream *mszipd_init(struct mspack_system *system,
|
|
359
352
|
}
|
360
353
|
|
361
354
|
/* allocate input buffer */
|
362
|
-
zip->inbuf = (unsigned char *) system->alloc(system,
|
355
|
+
zip->inbuf = (unsigned char *) system->alloc(system, input_buffer_size);
|
363
356
|
if (!zip->inbuf) {
|
364
357
|
system->free(zip);
|
365
358
|
return NULL;
|
@@ -467,11 +460,7 @@ int mszipd_decompress(struct mszipd_stream *zip, off_t out_bytes) {
|
|
467
460
|
}
|
468
461
|
|
469
462
|
int mszipd_decompress_kwaj(struct mszipd_stream *zip) {
|
470
|
-
|
471
|
-
register unsigned int bit_buffer;
|
472
|
-
register int bits_left;
|
473
|
-
unsigned char *i_ptr, *i_end;
|
474
|
-
|
463
|
+
DECLARE_BIT_VARS;
|
475
464
|
int i, error, block_len;
|
476
465
|
|
477
466
|
/* unpack blocks until block_len == 0 */
|
data/ext/libmspack/mspack/qtmd.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/* This file is part of libmspack.
|
2
|
-
* (C) 2003-
|
2
|
+
* (C) 2003-2023 Stuart Caie.
|
3
3
|
*
|
4
4
|
* The Quantum method was created by David Stafford, adapted by Microsoft
|
5
5
|
* Corporation.
|
@@ -254,14 +254,12 @@ struct qtmd_stream *qtmd_init(struct mspack_system *system,
|
|
254
254
|
}
|
255
255
|
|
256
256
|
int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes) {
|
257
|
+
DECLARE_BIT_VARS;
|
257
258
|
unsigned int frame_todo, frame_end, window_posn, match_offset, range;
|
258
|
-
unsigned char *window, *
|
259
|
+
unsigned char *window, *runsrc, *rundest;
|
259
260
|
int i, j, selector, extra, sym, match_length;
|
260
261
|
unsigned short H, L, C, symf;
|
261
262
|
|
262
|
-
register unsigned int bit_buffer;
|
263
|
-
register unsigned char bits_left;
|
264
|
-
|
265
263
|
/* easy answers */
|
266
264
|
if (!qtm || (out_bytes < 0)) return MSPACK_ERR_ARGS;
|
267
265
|
if (qtm->error) return qtm->error;
|
@@ -13,6 +13,7 @@
|
|
13
13
|
/* this header defines macros that read data streams by
|
14
14
|
* the individual bits
|
15
15
|
*
|
16
|
+
* DECLARE_BIT_VARS declares local variables
|
16
17
|
* INIT_BITS initialises bitstream state in state structure
|
17
18
|
* STORE_BITS stores bitstream state in state structure
|
18
19
|
* RESTORE_BITS restores bitstream state from state structure
|
@@ -92,13 +93,20 @@
|
|
92
93
|
# endif
|
93
94
|
#endif
|
94
95
|
|
96
|
+
typedef unsigned int bitbuf_type;
|
97
|
+
|
95
98
|
#if HAVE_LIMITS_H
|
96
99
|
# include <limits.h>
|
97
100
|
#endif
|
98
101
|
#ifndef CHAR_BIT
|
99
102
|
# define CHAR_BIT (8)
|
100
103
|
#endif
|
101
|
-
#define BITBUF_WIDTH (sizeof(
|
104
|
+
#define BITBUF_WIDTH (sizeof(bitbuf_type) * CHAR_BIT)
|
105
|
+
|
106
|
+
#define DECLARE_BIT_VARS \
|
107
|
+
unsigned char *i_ptr, *i_end; \
|
108
|
+
register bitbuf_type bit_buffer; \
|
109
|
+
register int bits_left
|
102
110
|
|
103
111
|
#define INIT_BITS do { \
|
104
112
|
BITS_VAR->i_ptr = &BITS_VAR->inbuf[0]; \
|
@@ -136,7 +144,7 @@
|
|
136
144
|
unsigned char needed = (bits), bitrun; \
|
137
145
|
(val) = 0; \
|
138
146
|
while (needed > 0) { \
|
139
|
-
if (bits_left <= (BITBUF_WIDTH - 16)) READ_BYTES;
|
147
|
+
if (bits_left <= (int)(BITBUF_WIDTH - 16)) READ_BYTES; \
|
140
148
|
bitrun = (bits_left < needed) ? bits_left : needed; \
|
141
149
|
(val) = ((val) << bitrun) | PEEK_BITS(bitrun); \
|
142
150
|
REMOVE_BITS(bitrun); \
|
@@ -148,12 +156,13 @@
|
|
148
156
|
# define PEEK_BITS(nbits) (bit_buffer >> (BITBUF_WIDTH - (nbits)))
|
149
157
|
# define REMOVE_BITS(nbits) ((bit_buffer <<= (nbits)), (bits_left -= (nbits)))
|
150
158
|
# define INJECT_BITS(bitdata,nbits) ((bit_buffer |= \
|
151
|
-
(bitdata) << (BITBUF_WIDTH - (nbits) - bits_left)),
|
159
|
+
(bitbuf_type)(bitdata) << (BITBUF_WIDTH - (nbits) - bits_left)), \
|
160
|
+
(bits_left += (nbits)))
|
152
161
|
#else /* BITS_ORDER_LSB */
|
153
|
-
# define PEEK_BITS(nbits) (bit_buffer & ((1 << (nbits))-1))
|
162
|
+
# define PEEK_BITS(nbits) (bit_buffer & ((bitbuf_type)(1 << (nbits))-1))
|
154
163
|
# define REMOVE_BITS(nbits) ((bit_buffer >>= (nbits)), (bits_left -= (nbits)))
|
155
164
|
# define INJECT_BITS(bitdata,nbits) ((bit_buffer |= \
|
156
|
-
(bitdata) << bits_left), (bits_left += (nbits)))
|
165
|
+
(bitbuf_type)(bitdata) << bits_left), (bits_left += (nbits)))
|
157
166
|
#endif
|
158
167
|
|
159
168
|
#ifdef BITS_LSB_TABLE
|
@@ -28,35 +28,40 @@
|
|
28
28
|
# define HUFF_MAXBITS 16
|
29
29
|
#endif
|
30
30
|
|
31
|
+
#define DECLARE_HUFF_VARS \
|
32
|
+
DECLARE_BIT_VARS; \
|
33
|
+
register int huff_idx; \
|
34
|
+
register unsigned short huff_sym
|
35
|
+
|
31
36
|
/* Decodes the next huffman symbol from the input bitstream into var.
|
32
37
|
* Do not use this macro on a table unless build_decode_table() succeeded.
|
33
38
|
*/
|
34
|
-
#define READ_HUFFSYM(tbl, var) do {
|
35
|
-
ENSURE_BITS(HUFF_MAXBITS);
|
36
|
-
|
37
|
-
if (
|
38
|
-
(var) =
|
39
|
-
|
40
|
-
REMOVE_BITS(
|
39
|
+
#define READ_HUFFSYM(tbl, var) do { \
|
40
|
+
ENSURE_BITS(HUFF_MAXBITS); \
|
41
|
+
huff_sym = HUFF_TABLE(tbl, PEEK_BITS(TABLEBITS(tbl))); \
|
42
|
+
if (huff_sym >= MAXSYMBOLS(tbl)) HUFF_TRAVERSE(tbl); \
|
43
|
+
(var) = huff_sym; \
|
44
|
+
huff_idx = HUFF_LEN(tbl, huff_sym); \
|
45
|
+
REMOVE_BITS(huff_idx); \
|
41
46
|
} while (0)
|
42
47
|
|
43
48
|
#ifdef BITS_ORDER_LSB
|
44
|
-
# define HUFF_TRAVERSE(tbl) do {
|
45
|
-
|
46
|
-
do {
|
47
|
-
if (
|
48
|
-
|
49
|
-
(
|
50
|
-
} while (
|
49
|
+
# define HUFF_TRAVERSE(tbl) do { \
|
50
|
+
huff_idx = TABLEBITS(tbl) - 1; \
|
51
|
+
do { \
|
52
|
+
if (huff_idx++ > HUFF_MAXBITS) HUFF_ERROR; \
|
53
|
+
huff_sym = HUFF_TABLE(tbl, \
|
54
|
+
(huff_sym << 1) | ((bit_buffer >> huff_idx) & 1)); \
|
55
|
+
} while (huff_sym >= MAXSYMBOLS(tbl)); \
|
51
56
|
} while (0)
|
52
57
|
#else
|
53
|
-
#define HUFF_TRAVERSE(tbl) do {
|
54
|
-
|
55
|
-
do {
|
56
|
-
if ((
|
57
|
-
|
58
|
-
(
|
59
|
-
} while (
|
58
|
+
#define HUFF_TRAVERSE(tbl) do { \
|
59
|
+
huff_idx = 1 << (BITBUF_WIDTH - TABLEBITS(tbl)); \
|
60
|
+
do { \
|
61
|
+
if ((huff_idx >>= 1) == 0) HUFF_ERROR; \
|
62
|
+
huff_sym = HUFF_TABLE(tbl, \
|
63
|
+
(huff_sym << 1) | ((bit_buffer & huff_idx) ? 1 : 0)); \
|
64
|
+
} while (huff_sym >= MAXSYMBOLS(tbl)); \
|
60
65
|
} while (0)
|
61
66
|
#endif
|
62
67
|
|
@@ -18,11 +18,29 @@ extern "C" {
|
|
18
18
|
#ifdef HAVE_CONFIG_H
|
19
19
|
# include <config.h>
|
20
20
|
#endif
|
21
|
-
|
22
21
|
#include <mspack.h>
|
22
|
+
#include <macros.h>
|
23
23
|
|
24
24
|
/* assume <string.h> exists */
|
25
|
-
#
|
25
|
+
#ifndef MSPACK_NO_DEFAULT_SYSTEM
|
26
|
+
# include <string.h>
|
27
|
+
#else
|
28
|
+
/* but if no default system wanted, avoid using <string.h> entirely,
|
29
|
+
* to avoid linking to even these standard C library functions */
|
30
|
+
static inline int memcmp(const void *s1, const void *s2, size_t n) {
|
31
|
+
const unsigned char *a = s1, *b = s2;
|
32
|
+
while (n--) if (*a++ != *b++) return a[-1] - b[-1];
|
33
|
+
return 0;
|
34
|
+
}
|
35
|
+
static inline void *memset(void *s, int c, size_t n) {
|
36
|
+
unsigned char *s2 = s, c2 = (unsigned char) c;
|
37
|
+
while (n--) *s2++ = c2;
|
38
|
+
return s;
|
39
|
+
}
|
40
|
+
static inline size_t strlen(const char *s) {
|
41
|
+
size_t c = 0; while (*s++) c++; return c;
|
42
|
+
}
|
43
|
+
#endif
|
26
44
|
|
27
45
|
/* fix for problem with GCC 4 and glibc (thanks to Ville Skytta)
|
28
46
|
* http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=150429
|
@@ -31,71 +49,6 @@ extern "C" {
|
|
31
49
|
# undef read
|
32
50
|
#endif
|
33
51
|
|
34
|
-
/* Old GCCs don't have __func__, but __FUNCTION__:
|
35
|
-
* http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
|
36
|
-
*/
|
37
|
-
#if __STDC_VERSION__ < 199901L
|
38
|
-
# if __GNUC__ >= 2
|
39
|
-
# define __func__ __FUNCTION__
|
40
|
-
# else
|
41
|
-
# define __func__ "<unknown>"
|
42
|
-
# endif
|
43
|
-
#endif
|
44
|
-
|
45
|
-
#if DEBUG
|
46
|
-
# include <stdio.h>
|
47
|
-
# define D(x) do { printf("%s:%d (%s) ",__FILE__, __LINE__, __func__); \
|
48
|
-
printf x ; fputc('\n', stdout); fflush(stdout);} while (0);
|
49
|
-
#else
|
50
|
-
# define D(x)
|
51
|
-
#endif
|
52
|
-
|
53
|
-
/* CAB supports searching through files over 4GB in size, and the CHM file
|
54
|
-
* format actively uses 64-bit offsets. These can only be fully supported
|
55
|
-
* if the system the code runs on supports large files. If not, the library
|
56
|
-
* will work as normal using only 32-bit arithmetic, but if an offset
|
57
|
-
* greater than 2GB is detected, an error message indicating the library
|
58
|
-
* can't support the file should be printed.
|
59
|
-
*/
|
60
|
-
#if HAVE_INTTYPES_H
|
61
|
-
# include <inttypes.h>
|
62
|
-
#else
|
63
|
-
# define PRId64 "lld"
|
64
|
-
# define PRIu64 "llu"
|
65
|
-
# define PRId32 "ld"
|
66
|
-
# define PRIu32 "lu"
|
67
|
-
#endif
|
68
|
-
|
69
|
-
#include <limits.h>
|
70
|
-
#if ((defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS >= 64) || \
|
71
|
-
(defined(FILESIZEBITS) && FILESIZEBITS >= 64) || \
|
72
|
-
defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) || \
|
73
|
-
SIZEOF_OFF_T >= 8)
|
74
|
-
# define LARGEFILE_SUPPORT 1
|
75
|
-
# define LD PRId64
|
76
|
-
# define LU PRIu64
|
77
|
-
#else
|
78
|
-
extern const char *largefile_msg;
|
79
|
-
# define LD PRId32
|
80
|
-
# define LU PRIu32
|
81
|
-
#endif
|
82
|
-
|
83
|
-
/* endian-neutral reading of little-endian data */
|
84
|
-
#define __egi32(a,n) (((unsigned int) ((unsigned char *)(a))[n+3] << 24) | \
|
85
|
-
((unsigned int) ((unsigned char *)(a))[n+2] << 16) | \
|
86
|
-
((unsigned int) ((unsigned char *)(a))[n+1] << 8) | \
|
87
|
-
((unsigned int) ((unsigned char *)(a))[n]))
|
88
|
-
#define EndGetI64(a) (((unsigned long long int) __egi32(a,4) << 32) | __egi32(a,0))
|
89
|
-
#define EndGetI32(a) __egi32(a,0)
|
90
|
-
#define EndGetI16(a) ((((a)[1])<<8)|((a)[0]))
|
91
|
-
|
92
|
-
/* endian-neutral reading of big-endian data */
|
93
|
-
#define EndGetM32(a) (((unsigned int) ((unsigned char *)(a))[0] << 24) | \
|
94
|
-
((unsigned int) ((unsigned char *)(a))[1] << 16) | \
|
95
|
-
((unsigned int) ((unsigned char *)(a))[2] << 8) | \
|
96
|
-
((unsigned int) ((unsigned char *)(a))[3]))
|
97
|
-
#define EndGetM16(a) ((((a)[0])<<8)|((a)[1]))
|
98
|
-
|
99
52
|
extern struct mspack_system *mspack_default_system;
|
100
53
|
|
101
54
|
/* returns the length of a file opened for reading */
|