libmspack 0.10.1.2 → 0.11.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 +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 */
|