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.
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 */