extzstd 0.0.3.CONCEPT → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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));