extzstd 0.0.3.CONCEPT → 0.3.1

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 (138) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.ja.md +39 -0
  3. data/LICENSE +6 -6
  4. data/README.md +26 -45
  5. data/contrib/zstd/CHANGELOG +555 -0
  6. data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
  7. data/contrib/zstd/CONTRIBUTING.md +392 -0
  8. data/contrib/zstd/COPYING +339 -0
  9. data/contrib/zstd/LICENSE +13 -9
  10. data/contrib/zstd/Makefile +414 -0
  11. data/contrib/zstd/README.md +170 -45
  12. data/contrib/zstd/TESTING.md +44 -0
  13. data/contrib/zstd/appveyor.yml +289 -0
  14. data/contrib/zstd/lib/BUCK +234 -0
  15. data/contrib/zstd/lib/Makefile +354 -0
  16. data/contrib/zstd/lib/README.md +179 -0
  17. data/contrib/zstd/{common → lib/common}/bitstream.h +170 -130
  18. data/contrib/zstd/lib/common/compiler.h +175 -0
  19. data/contrib/zstd/lib/common/cpu.h +215 -0
  20. data/contrib/zstd/lib/common/debug.c +24 -0
  21. data/contrib/zstd/lib/common/debug.h +114 -0
  22. data/contrib/zstd/{common → lib/common}/entropy_common.c +79 -94
  23. data/contrib/zstd/lib/common/error_private.c +55 -0
  24. data/contrib/zstd/lib/common/error_private.h +80 -0
  25. data/contrib/zstd/{common → lib/common}/fse.h +153 -93
  26. data/contrib/zstd/{common → lib/common}/fse_decompress.c +37 -82
  27. data/contrib/zstd/lib/common/huf.h +340 -0
  28. data/contrib/zstd/{common → lib/common}/mem.h +154 -78
  29. data/contrib/zstd/lib/common/pool.c +344 -0
  30. data/contrib/zstd/lib/common/pool.h +84 -0
  31. data/contrib/zstd/lib/common/threading.c +121 -0
  32. data/contrib/zstd/lib/common/threading.h +155 -0
  33. data/contrib/zstd/{common → lib/common}/xxhash.c +85 -75
  34. data/contrib/zstd/{common → lib/common}/xxhash.h +85 -73
  35. data/contrib/zstd/lib/common/zstd_common.c +83 -0
  36. data/contrib/zstd/lib/common/zstd_errors.h +94 -0
  37. data/contrib/zstd/lib/common/zstd_internal.h +447 -0
  38. data/contrib/zstd/{compress → lib/compress}/fse_compress.c +194 -303
  39. data/contrib/zstd/lib/compress/hist.c +183 -0
  40. data/contrib/zstd/lib/compress/hist.h +75 -0
  41. data/contrib/zstd/lib/compress/huf_compress.c +798 -0
  42. data/contrib/zstd/lib/compress/zstd_compress.c +4278 -0
  43. data/contrib/zstd/lib/compress/zstd_compress_internal.h +1125 -0
  44. data/contrib/zstd/lib/compress/zstd_compress_literals.c +158 -0
  45. data/contrib/zstd/lib/compress/zstd_compress_literals.h +29 -0
  46. data/contrib/zstd/lib/compress/zstd_compress_sequences.c +419 -0
  47. data/contrib/zstd/lib/compress/zstd_compress_sequences.h +54 -0
  48. data/contrib/zstd/lib/compress/zstd_compress_superblock.c +845 -0
  49. data/contrib/zstd/lib/compress/zstd_compress_superblock.h +32 -0
  50. data/contrib/zstd/lib/compress/zstd_cwksp.h +525 -0
  51. data/contrib/zstd/lib/compress/zstd_double_fast.c +521 -0
  52. data/contrib/zstd/lib/compress/zstd_double_fast.h +38 -0
  53. data/contrib/zstd/lib/compress/zstd_fast.c +496 -0
  54. data/contrib/zstd/lib/compress/zstd_fast.h +37 -0
  55. data/contrib/zstd/lib/compress/zstd_lazy.c +1138 -0
  56. data/contrib/zstd/lib/compress/zstd_lazy.h +67 -0
  57. data/contrib/zstd/lib/compress/zstd_ldm.c +619 -0
  58. data/contrib/zstd/lib/compress/zstd_ldm.h +110 -0
  59. data/contrib/zstd/lib/compress/zstd_opt.c +1200 -0
  60. data/contrib/zstd/lib/compress/zstd_opt.h +56 -0
  61. data/contrib/zstd/lib/compress/zstdmt_compress.c +2143 -0
  62. data/contrib/zstd/lib/compress/zstdmt_compress.h +192 -0
  63. data/contrib/zstd/lib/decompress/huf_decompress.c +1248 -0
  64. data/contrib/zstd/lib/decompress/zstd_ddict.c +244 -0
  65. data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
  66. data/contrib/zstd/lib/decompress/zstd_decompress.c +1885 -0
  67. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1432 -0
  68. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +59 -0
  69. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +189 -0
  70. data/contrib/zstd/{common → lib/deprecated}/zbuff.h +86 -69
  71. data/contrib/zstd/lib/deprecated/zbuff_common.c +26 -0
  72. data/contrib/zstd/lib/deprecated/zbuff_compress.c +147 -0
  73. data/contrib/zstd/lib/deprecated/zbuff_decompress.c +75 -0
  74. data/contrib/zstd/lib/dictBuilder/cover.c +1236 -0
  75. data/contrib/zstd/lib/dictBuilder/cover.h +157 -0
  76. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.c +3 -3
  77. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.h +5 -5
  78. data/contrib/zstd/lib/dictBuilder/fastcover.c +757 -0
  79. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/zdict.c +437 -347
  80. data/contrib/zstd/lib/dictBuilder/zdict.h +305 -0
  81. data/contrib/zstd/lib/legacy/zstd_legacy.h +415 -0
  82. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.c +272 -292
  83. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.h +26 -32
  84. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.c +162 -392
  85. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.h +26 -32
  86. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.c +162 -391
  87. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.h +27 -33
  88. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.c +195 -604
  89. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.h +26 -32
  90. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.c +300 -575
  91. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.h +22 -31
  92. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.c +165 -592
  93. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.h +54 -67
  94. data/contrib/zstd/lib/legacy/zstd_v07.c +4541 -0
  95. data/contrib/zstd/lib/legacy/zstd_v07.h +187 -0
  96. data/contrib/zstd/lib/libzstd.pc.in +15 -0
  97. data/contrib/zstd/lib/zstd.h +2090 -0
  98. data/ext/depend +2 -0
  99. data/ext/extconf.rb +18 -5
  100. data/ext/extzstd.c +296 -214
  101. data/ext/extzstd.h +81 -36
  102. data/ext/extzstd_nogvls.h +0 -117
  103. data/ext/extzstd_stream.c +622 -0
  104. data/ext/libzstd_conf.h +8 -0
  105. data/ext/zstd_common.c +11 -0
  106. data/ext/zstd_compress.c +15 -0
  107. data/ext/zstd_decompress.c +6 -0
  108. data/ext/zstd_dictbuilder.c +10 -0
  109. data/ext/zstd_dictbuilder_fastcover.c +3 -0
  110. data/ext/zstd_legacy_v01.c +3 -1
  111. data/ext/zstd_legacy_v02.c +3 -1
  112. data/ext/zstd_legacy_v03.c +3 -1
  113. data/ext/zstd_legacy_v04.c +3 -1
  114. data/ext/zstd_legacy_v05.c +3 -1
  115. data/ext/zstd_legacy_v06.c +3 -1
  116. data/ext/zstd_legacy_v07.c +3 -0
  117. data/gemstub.rb +27 -21
  118. data/lib/extzstd.rb +82 -161
  119. data/lib/extzstd/version.rb +1 -1
  120. data/test/test_basic.rb +19 -6
  121. metadata +127 -59
  122. data/contrib/zstd/common/error_private.h +0 -125
  123. data/contrib/zstd/common/error_public.h +0 -77
  124. data/contrib/zstd/common/huf.h +0 -228
  125. data/contrib/zstd/common/zstd.h +0 -475
  126. data/contrib/zstd/common/zstd_common.c +0 -91
  127. data/contrib/zstd/common/zstd_internal.h +0 -238
  128. data/contrib/zstd/compress/huf_compress.c +0 -577
  129. data/contrib/zstd/compress/zbuff_compress.c +0 -327
  130. data/contrib/zstd/compress/zstd_compress.c +0 -3074
  131. data/contrib/zstd/compress/zstd_opt.h +0 -1046
  132. data/contrib/zstd/decompress/huf_decompress.c +0 -894
  133. data/contrib/zstd/decompress/zbuff_decompress.c +0 -294
  134. data/contrib/zstd/decompress/zstd_decompress.c +0 -1362
  135. data/contrib/zstd/dictBuilder/zdict.h +0 -113
  136. data/contrib/zstd/legacy/zstd_legacy.h +0 -140
  137. data/ext/extzstd_buffered.c +0 -265
  138. data/ext/zstd_amalgam.c +0 -18
@@ -1,36 +1,15 @@
1
1
  /* ******************************************************************
2
- bitstream
3
- Part of FSE library
4
- header file (to include)
5
- Copyright (C) 2013-2016, Yann Collet.
6
-
7
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
8
-
9
- Redistribution and use in source and binary forms, with or without
10
- modification, are permitted provided that the following conditions are
11
- met:
12
-
13
- * Redistributions of source code must retain the above copyright
14
- notice, this list of conditions and the following disclaimer.
15
- * Redistributions in binary form must reproduce the above
16
- copyright notice, this list of conditions and the following disclaimer
17
- in the documentation and/or other materials provided with the
18
- distribution.
19
-
20
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
-
32
- You can contact the author at :
33
- - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
2
+ * bitstream
3
+ * Part of FSE library
4
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
5
+ *
6
+ * You can contact the author at :
7
+ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
8
+ *
9
+ * This source code is licensed under both the BSD-style license (found in the
10
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11
+ * in the COPYING file in the root directory of this source tree).
12
+ * You may select, at your option, one of the above-listed licenses.
34
13
  ****************************************************************** */
35
14
  #ifndef BITSTREAM_H_MODULE
36
15
  #define BITSTREAM_H_MODULE
@@ -39,7 +18,6 @@
39
18
  extern "C" {
40
19
  #endif
41
20
 
42
-
43
21
  /*
44
22
  * This API consists of small unitary functions, which must be inlined for best performance.
45
23
  * Since link-time-optimization is not available for all compilers,
@@ -50,6 +28,8 @@ extern "C" {
50
28
  * Dependencies
51
29
  ******************************************/
52
30
  #include "mem.h" /* unaligned access routines */
31
+ #include "compiler.h" /* UNLIKELY() */
32
+ #include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */
53
33
  #include "error_private.h" /* error codes and messages */
54
34
 
55
35
 
@@ -58,20 +38,25 @@ extern "C" {
58
38
  =========================================*/
59
39
  #if defined(__BMI__) && defined(__GNUC__)
60
40
  # include <immintrin.h> /* support for bextr (experimental) */
41
+ #elif defined(__ICCARM__)
42
+ # include <intrinsics.h>
61
43
  #endif
62
44
 
45
+ #define STREAM_ACCUMULATOR_MIN_32 25
46
+ #define STREAM_ACCUMULATOR_MIN_64 57
47
+ #define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
48
+
63
49
 
64
50
  /*-******************************************
65
51
  * bitStream encoding API (write forward)
66
52
  ********************************************/
67
53
  /* bitStream can mix input from multiple sources.
68
- * A critical property of these streams is that they encode and decode in **reverse** direction.
69
- * So the first bit sequence you add will be the last to be read, like a LIFO stack.
70
- */
71
- typedef struct
72
- {
54
+ * A critical property of these streams is that they encode and decode in **reverse** direction.
55
+ * So the first bit sequence you add will be the last to be read, like a LIFO stack.
56
+ */
57
+ typedef struct {
73
58
  size_t bitContainer;
74
- int bitPos;
59
+ unsigned bitPos;
75
60
  char* startPtr;
76
61
  char* ptr;
77
62
  char* endPtr;
@@ -103,12 +88,12 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
103
88
  /*-********************************************
104
89
  * bitStream decoding API (read backward)
105
90
  **********************************************/
106
- typedef struct
107
- {
91
+ typedef struct {
108
92
  size_t bitContainer;
109
93
  unsigned bitsConsumed;
110
94
  const char* ptr;
111
95
  const char* start;
96
+ const char* limitPtr;
112
97
  } BIT_DStream_t;
113
98
 
114
99
  typedef enum { BIT_DStream_unfinished = 0,
@@ -151,140 +136,181 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
151
136
  /*-**************************************************************
152
137
  * Internal functions
153
138
  ****************************************************************/
154
- MEM_STATIC unsigned BIT_highbit32 (register U32 val)
139
+ MEM_STATIC unsigned BIT_highbit32 (U32 val)
155
140
  {
141
+ assert(val != 0);
142
+ {
156
143
  # if defined(_MSC_VER) /* Visual */
157
- unsigned long r=0;
158
- _BitScanReverse ( &r, val );
159
- return (unsigned) r;
144
+ unsigned long r=0;
145
+ return _BitScanReverse ( &r, val ) ? (unsigned)r : 0;
160
146
  # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
161
- return 31 - __builtin_clz (val);
147
+ return __builtin_clz (val) ^ 31;
148
+ # elif defined(__ICCARM__) /* IAR Intrinsic */
149
+ return 31 - __CLZ(val);
162
150
  # else /* Software version */
163
- static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
164
- U32 v = val;
165
- v |= v >> 1;
166
- v |= v >> 2;
167
- v |= v >> 4;
168
- v |= v >> 8;
169
- v |= v >> 16;
170
- return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
151
+ static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
152
+ 11, 14, 16, 18, 22, 25, 3, 30,
153
+ 8, 12, 20, 28, 15, 17, 24, 7,
154
+ 19, 27, 23, 6, 26, 5, 4, 31 };
155
+ U32 v = val;
156
+ v |= v >> 1;
157
+ v |= v >> 2;
158
+ v |= v >> 4;
159
+ v |= v >> 8;
160
+ v |= v >> 16;
161
+ return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
171
162
  # endif
163
+ }
172
164
  }
173
165
 
174
166
  /*===== Local Constants =====*/
175
- static const unsigned BIT_mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF }; /* up to 26 bits */
176
-
167
+ static const unsigned BIT_mask[] = {
168
+ 0, 1, 3, 7, 0xF, 0x1F,
169
+ 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF,
170
+ 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF,
171
+ 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF,
172
+ 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF,
173
+ 0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */
174
+ #define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0]))
177
175
 
178
176
  /*-**************************************************************
179
177
  * bitStream encoding
180
178
  ****************************************************************/
181
179
  /*! BIT_initCStream() :
182
- * `dstCapacity` must be > sizeof(void*)
180
+ * `dstCapacity` must be > sizeof(size_t)
183
181
  * @return : 0 if success,
184
- otherwise an error code (can be tested using ERR_isError() ) */
185
- MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* startPtr, size_t dstCapacity)
182
+ * otherwise an error code (can be tested using ERR_isError()) */
183
+ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
184
+ void* startPtr, size_t dstCapacity)
186
185
  {
187
186
  bitC->bitContainer = 0;
188
187
  bitC->bitPos = 0;
189
188
  bitC->startPtr = (char*)startPtr;
190
189
  bitC->ptr = bitC->startPtr;
191
- bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->ptr);
192
- if (dstCapacity <= sizeof(bitC->ptr)) return ERROR(dstSize_tooSmall);
190
+ bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer);
191
+ if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall);
193
192
  return 0;
194
193
  }
195
194
 
196
195
  /*! BIT_addBits() :
197
- can add up to 26 bits into `bitC`.
198
- Does not check for register overflow ! */
199
- MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
196
+ * can add up to 31 bits into `bitC`.
197
+ * Note : does not check for register overflow ! */
198
+ MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
199
+ size_t value, unsigned nbBits)
200
200
  {
201
+ MEM_STATIC_ASSERT(BIT_MASK_SIZE == 32);
202
+ assert(nbBits < BIT_MASK_SIZE);
203
+ assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
201
204
  bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
202
205
  bitC->bitPos += nbBits;
203
206
  }
204
207
 
205
208
  /*! BIT_addBitsFast() :
206
- * works only if `value` is _clean_, meaning all high bits above nbBits are 0 */
207
- MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
209
+ * works only if `value` is _clean_,
210
+ * meaning all high bits above nbBits are 0 */
211
+ MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC,
212
+ size_t value, unsigned nbBits)
208
213
  {
214
+ assert((value>>nbBits) == 0);
215
+ assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
209
216
  bitC->bitContainer |= value << bitC->bitPos;
210
217
  bitC->bitPos += nbBits;
211
218
  }
212
219
 
213
220
  /*! BIT_flushBitsFast() :
221
+ * assumption : bitContainer has not overflowed
214
222
  * unsafe version; does not check buffer overflow */
215
223
  MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
216
224
  {
217
225
  size_t const nbBytes = bitC->bitPos >> 3;
226
+ assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
227
+ assert(bitC->ptr <= bitC->endPtr);
218
228
  MEM_writeLEST(bitC->ptr, bitC->bitContainer);
219
229
  bitC->ptr += nbBytes;
220
230
  bitC->bitPos &= 7;
221
- bitC->bitContainer >>= nbBytes*8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
231
+ bitC->bitContainer >>= nbBytes*8;
222
232
  }
223
233
 
224
234
  /*! BIT_flushBits() :
235
+ * assumption : bitContainer has not overflowed
225
236
  * safe version; check for buffer overflow, and prevents it.
226
- * note : does not signal buffer overflow. This will be revealed later on using BIT_closeCStream() */
237
+ * note : does not signal buffer overflow.
238
+ * overflow will be revealed later on using BIT_closeCStream() */
227
239
  MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
228
240
  {
229
241
  size_t const nbBytes = bitC->bitPos >> 3;
242
+ assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
243
+ assert(bitC->ptr <= bitC->endPtr);
230
244
  MEM_writeLEST(bitC->ptr, bitC->bitContainer);
231
245
  bitC->ptr += nbBytes;
232
246
  if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
233
247
  bitC->bitPos &= 7;
234
- bitC->bitContainer >>= nbBytes*8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
248
+ bitC->bitContainer >>= nbBytes*8;
235
249
  }
236
250
 
237
251
  /*! BIT_closeCStream() :
238
252
  * @return : size of CStream, in bytes,
239
- or 0 if it could not fit into dstBuffer */
253
+ * or 0 if it could not fit into dstBuffer */
240
254
  MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
241
255
  {
242
256
  BIT_addBitsFast(bitC, 1, 1); /* endMark */
243
257
  BIT_flushBits(bitC);
244
-
245
- if (bitC->ptr >= bitC->endPtr) return 0; /* doesn't fit within authorized budget : cancel */
246
-
258
+ if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */
247
259
  return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
248
260
  }
249
261
 
250
262
 
251
263
  /*-********************************************************
252
- * bitStream decoding
264
+ * bitStream decoding
253
265
  **********************************************************/
254
266
  /*! BIT_initDStream() :
255
- * Initialize a BIT_DStream_t.
256
- * `bitD` : a pointer to an already allocated BIT_DStream_t structure.
257
- * `srcSize` must be the *exact* size of the bitStream, in bytes.
258
- * @return : size of stream (== srcSize) or an errorCode if a problem is detected
259
- */
267
+ * Initialize a BIT_DStream_t.
268
+ * `bitD` : a pointer to an already allocated BIT_DStream_t structure.
269
+ * `srcSize` must be the *exact* size of the bitStream, in bytes.
270
+ * @return : size of stream (== srcSize), or an errorCode if a problem is detected
271
+ */
260
272
  MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
261
273
  {
262
274
  if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
263
275
 
276
+ bitD->start = (const char*)srcBuffer;
277
+ bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer);
278
+
264
279
  if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */
265
- bitD->start = (const char*)srcBuffer;
266
280
  bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
267
281
  bitD->bitContainer = MEM_readLEST(bitD->ptr);
268
282
  { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
269
- bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
283
+ bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
270
284
  if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
271
285
  } else {
272
- bitD->start = (const char*)srcBuffer;
273
286
  bitD->ptr = bitD->start;
274
287
  bitD->bitContainer = *(const BYTE*)(bitD->start);
275
288
  switch(srcSize)
276
289
  {
277
- case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
278
- case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
279
- case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
280
- case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
281
- case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
282
- case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
283
- default:;
290
+ case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
291
+ /* fall-through */
292
+
293
+ case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
294
+ /* fall-through */
295
+
296
+ case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
297
+ /* fall-through */
298
+
299
+ case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
300
+ /* fall-through */
301
+
302
+ case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
303
+ /* fall-through */
304
+
305
+ case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
306
+ /* fall-through */
307
+
308
+ default: break;
309
+ }
310
+ { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
311
+ bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
312
+ if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */
284
313
  }
285
- { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
286
- bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
287
- if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
288
314
  bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
289
315
  }
290
316
 
@@ -298,20 +324,15 @@ MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
298
324
 
299
325
  MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
300
326
  {
301
- #if defined(__BMI__) && defined(__GNUC__) /* experimental */
302
- # if defined(__x86_64__)
303
- if (sizeof(bitContainer)==8)
304
- return _bextr_u64(bitContainer, start, nbBits);
305
- else
306
- # endif
307
- return _bextr_u32(bitContainer, start, nbBits);
308
- #else
309
- return (bitContainer >> start) & BIT_mask[nbBits];
310
- #endif
327
+ U32 const regMask = sizeof(bitContainer)*8 - 1;
328
+ /* if start > regMask, bitstream is corrupted, and result is undefined */
329
+ assert(nbBits < BIT_MASK_SIZE);
330
+ return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
311
331
  }
312
332
 
313
333
  MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
314
334
  {
335
+ assert(nbBits < BIT_MASK_SIZE);
315
336
  return bitContainer & BIT_mask[nbBits];
316
337
  }
317
338
 
@@ -320,24 +341,28 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
320
341
  * local register is not modified.
321
342
  * On 32-bits, maxNbBits==24.
322
343
  * On 64-bits, maxNbBits==56.
323
- * @return : value extracted
324
- */
325
- MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
344
+ * @return : value extracted */
345
+ MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
326
346
  {
327
- #if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */
347
+ /* arbitrate between double-shift and shift+mask */
348
+ #if 1
349
+ /* if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8,
350
+ * bitstream is likely corrupted, and result is undefined */
328
351
  return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
329
352
  #else
330
- U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
331
- return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask);
353
+ /* this code path is slower on my os-x laptop */
354
+ U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
355
+ return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask);
332
356
  #endif
333
357
  }
334
358
 
335
359
  /*! BIT_lookBitsFast() :
336
- * unsafe version; only works only if nbBits >= 1 */
360
+ * unsafe version; only works if nbBits >= 1 */
337
361
  MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
338
362
  {
339
- U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
340
- return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask);
363
+ U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
364
+ assert(nbBits >= 1);
365
+ return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);
341
366
  }
342
367
 
343
368
  MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
@@ -348,9 +373,8 @@ MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
348
373
  /*! BIT_readBits() :
349
374
  * Read (consume) next n bits from local register and update.
350
375
  * Pay attention to not read more than nbBits contained into local register.
351
- * @return : extracted value.
352
- */
353
- MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
376
+ * @return : extracted value. */
377
+ MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
354
378
  {
355
379
  size_t const value = BIT_lookBits(bitD, nbBits);
356
380
  BIT_skipBits(bitD, nbBits);
@@ -358,34 +382,50 @@ MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
358
382
  }
359
383
 
360
384
  /*! BIT_readBitsFast() :
361
- * unsafe version; only works only if nbBits >= 1 */
362
- MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
385
+ * unsafe version; only works only if nbBits >= 1 */
386
+ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
363
387
  {
364
388
  size_t const value = BIT_lookBitsFast(bitD, nbBits);
389
+ assert(nbBits >= 1);
365
390
  BIT_skipBits(bitD, nbBits);
366
391
  return value;
367
392
  }
368
393
 
394
+ /*! BIT_reloadDStreamFast() :
395
+ * Similar to BIT_reloadDStream(), but with two differences:
396
+ * 1. bitsConsumed <= sizeof(bitD->bitContainer)*8 must hold!
397
+ * 2. Returns BIT_DStream_overflow when bitD->ptr < bitD->limitPtr, at this
398
+ * point you must use BIT_reloadDStream() to reload.
399
+ */
400
+ MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD)
401
+ {
402
+ if (UNLIKELY(bitD->ptr < bitD->limitPtr))
403
+ return BIT_DStream_overflow;
404
+ assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8);
405
+ bitD->ptr -= bitD->bitsConsumed >> 3;
406
+ bitD->bitsConsumed &= 7;
407
+ bitD->bitContainer = MEM_readLEST(bitD->ptr);
408
+ return BIT_DStream_unfinished;
409
+ }
410
+
369
411
  /*! BIT_reloadDStream() :
370
- * Refill `BIT_DStream_t` from src buffer previously defined (see BIT_initDStream() ).
371
- * This function is safe, it guarantees it will not read beyond src buffer.
372
- * @return : status of `BIT_DStream_t` internal register.
373
- if status == unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
412
+ * Refill `bitD` from buffer previously set in BIT_initDStream() .
413
+ * This function is safe, it guarantees it will not read beyond src buffer.
414
+ * @return : status of `BIT_DStream_t` internal register.
415
+ * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */
374
416
  MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
375
417
  {
376
- if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should not happen => corruption detected */
377
- return BIT_DStream_overflow;
418
+ if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */
419
+ return BIT_DStream_overflow;
378
420
 
379
- if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
380
- bitD->ptr -= bitD->bitsConsumed >> 3;
381
- bitD->bitsConsumed &= 7;
382
- bitD->bitContainer = MEM_readLEST(bitD->ptr);
383
- return BIT_DStream_unfinished;
421
+ if (bitD->ptr >= bitD->limitPtr) {
422
+ return BIT_reloadDStreamFast(bitD);
384
423
  }
385
424
  if (bitD->ptr == bitD->start) {
386
425
  if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
387
426
  return BIT_DStream_completed;
388
427
  }
428
+ /* start < ptr < limitPtr */
389
429
  { U32 nbBytes = bitD->bitsConsumed >> 3;
390
430
  BIT_DStream_status result = BIT_DStream_unfinished;
391
431
  if (bitD->ptr - nbBytes < bitD->start) {
@@ -394,14 +434,14 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
394
434
  }
395
435
  bitD->ptr -= nbBytes;
396
436
  bitD->bitsConsumed -= nbBytes*8;
397
- bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */
437
+ bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */
398
438
  return result;
399
439
  }
400
440
  }
401
441
 
402
442
  /*! BIT_endOfDStream() :
403
- * @return Tells if DStream has exactly reached its end (all bits consumed).
404
- */
443
+ * @return : 1 if DStream has _exactly_ reached its end (all bits consumed).
444
+ */
405
445
  MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
406
446
  {
407
447
  return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));