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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/ext/libmspack/ChangeLog +145 -0
  4. data/ext/libmspack/INSTALL +3 -3
  5. data/ext/libmspack/Makefile.am +7 -4
  6. data/ext/libmspack/Makefile.in +265 -147
  7. data/ext/libmspack/README +3 -2
  8. data/ext/libmspack/aclocal.m4 +111 -113
  9. data/ext/libmspack/ar-lib +10 -9
  10. data/ext/libmspack/compile +9 -8
  11. data/ext/libmspack/config.guess +887 -613
  12. data/ext/libmspack/config.h.in +6 -9
  13. data/ext/libmspack/config.sub +1349 -1260
  14. data/ext/libmspack/configure +3035 -2490
  15. data/ext/libmspack/configure.ac +3 -3
  16. data/ext/libmspack/depcomp +4 -4
  17. data/ext/libmspack/install-sh +107 -74
  18. data/ext/libmspack/libmscabd.la +1 -1
  19. data/ext/libmspack/libmschmd.la +1 -1
  20. data/ext/libmspack/libmspack.la +1 -1
  21. data/ext/libmspack/ltmain.sh +156 -61
  22. data/ext/libmspack/m4/libtool.m4 +19 -12
  23. data/ext/libmspack/missing +8 -8
  24. data/ext/libmspack/mspack/cabd.c +21 -19
  25. data/ext/libmspack/mspack/chm.h +3 -2
  26. data/ext/libmspack/mspack/chmd.c +137 -57
  27. data/ext/libmspack/mspack/kwajd.c +29 -29
  28. data/ext/libmspack/mspack/lzx.h +0 -1
  29. data/ext/libmspack/mspack/lzxd.c +30 -154
  30. data/ext/libmspack/mspack/macros.h +64 -0
  31. data/ext/libmspack/mspack/mszipd.c +7 -18
  32. data/ext/libmspack/mspack/qtmd.c +3 -5
  33. data/ext/libmspack/mspack/readbits.h +14 -5
  34. data/ext/libmspack/mspack/readhuff.h +26 -21
  35. data/ext/libmspack/mspack/system.c +0 -5
  36. data/ext/libmspack/mspack/system.h +20 -67
  37. data/ext/libmspack/test-driver +16 -11
  38. data/ext/x86_64-linux/libmspack.so +0 -0
  39. data/ext/x86_64-windows/mspack.dll +0 -0
  40. data/lib/libmspack/version.rb +1 -1
  41. metadata +4 -3
@@ -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 */
@@ -1,5 +1,5 @@
1
1
  /* This file is part of libmspack.
2
- * (C) 2003-2013 Stuart Caie.
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
- /* bit buffer and huffman symbol decode variables */
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, (size_t) window_size);
319
- lzx->inbuf = (unsigned char *) system->alloc(system, (size_t) input_buffer_size);
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
- /* bitstream and huffman reading variables */
396
- register unsigned int bit_buffer;
397
- register int bits_left, i=0;
398
- unsigned char *i_ptr, *i_end;
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] | (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);
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; 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;
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 > 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 */
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 > 0) { /* extra==1, extra==2 */
698
- /* verbatim bits only */
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
- if (match_offset > lzx->offset &&
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, (size_t) i);
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 <= 32768) && (frame_size > 10))
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->intel_curpos;
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 = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
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-2010 Stuart Caie.
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
- /* for the bit buffer and huffman decoding */
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
- unsigned int last_block, block_type, distance, length, this_run, i;
159
-
160
- /* for the bit buffer and huffman decoding */
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, (size_t) input_buffer_size);
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
- /* for the bit buffer */
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 */
@@ -1,5 +1,5 @@
1
1
  /* This file is part of libmspack.
2
- * (C) 2003-2004 Stuart Caie.
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, *i_ptr, *i_end, *runsrc, *rundest;
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(bit_buffer) * CHAR_BIT)
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)), (bits_left += (nbits)))
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
- sym = HUFF_TABLE(tbl, PEEK_BITS(TABLEBITS(tbl))); \
37
- if (sym >= MAXSYMBOLS(tbl)) HUFF_TRAVERSE(tbl); \
38
- (var) = sym; \
39
- i = HUFF_LEN(tbl, sym); \
40
- REMOVE_BITS(i); \
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
- i = TABLEBITS(tbl) - 1; \
46
- do { \
47
- if (i++ > HUFF_MAXBITS) HUFF_ERROR; \
48
- sym = HUFF_TABLE(tbl, \
49
- (sym << 1) | ((bit_buffer >> i) & 1)); \
50
- } while (sym >= MAXSYMBOLS(tbl)); \
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
- i = 1 << (BITBUF_WIDTH - TABLEBITS(tbl)); \
55
- do { \
56
- if ((i >>= 1) == 0) HUFF_ERROR; \
57
- sym = HUFF_TABLE(tbl, \
58
- (sym << 1) | ((bit_buffer & i) ? 1 : 0)); \
59
- } while (sym >= MAXSYMBOLS(tbl)); \
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
 
@@ -13,11 +13,6 @@
13
13
 
14
14
  #include <system.h>
15
15
 
16
- #if !LARGEFILE_SUPPORT
17
- const char *largefile_msg = "library not compiled to support large files.";
18
- #endif
19
-
20
-
21
16
  int mspack_version(int entity) {
22
17
  switch (entity) {
23
18
  /* CHM decoder version 1 -> 2 changes:
@@ -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
- #include <string.h>
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 */