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.
- checksums.yaml +5 -5
- data/HISTORY.ja.md +39 -0
- data/LICENSE +6 -6
- data/README.md +26 -45
- data/contrib/zstd/CHANGELOG +555 -0
- data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
- data/contrib/zstd/CONTRIBUTING.md +392 -0
- data/contrib/zstd/COPYING +339 -0
- data/contrib/zstd/LICENSE +13 -9
- data/contrib/zstd/Makefile +414 -0
- data/contrib/zstd/README.md +170 -45
- data/contrib/zstd/TESTING.md +44 -0
- data/contrib/zstd/appveyor.yml +289 -0
- data/contrib/zstd/lib/BUCK +234 -0
- data/contrib/zstd/lib/Makefile +354 -0
- data/contrib/zstd/lib/README.md +179 -0
- data/contrib/zstd/{common → lib/common}/bitstream.h +170 -130
- data/contrib/zstd/lib/common/compiler.h +175 -0
- data/contrib/zstd/lib/common/cpu.h +215 -0
- data/contrib/zstd/lib/common/debug.c +24 -0
- data/contrib/zstd/lib/common/debug.h +114 -0
- data/contrib/zstd/{common → lib/common}/entropy_common.c +79 -94
- data/contrib/zstd/lib/common/error_private.c +55 -0
- data/contrib/zstd/lib/common/error_private.h +80 -0
- data/contrib/zstd/{common → lib/common}/fse.h +153 -93
- data/contrib/zstd/{common → lib/common}/fse_decompress.c +37 -82
- data/contrib/zstd/lib/common/huf.h +340 -0
- data/contrib/zstd/{common → lib/common}/mem.h +154 -78
- data/contrib/zstd/lib/common/pool.c +344 -0
- data/contrib/zstd/lib/common/pool.h +84 -0
- data/contrib/zstd/lib/common/threading.c +121 -0
- data/contrib/zstd/lib/common/threading.h +155 -0
- data/contrib/zstd/{common → lib/common}/xxhash.c +85 -75
- data/contrib/zstd/{common → lib/common}/xxhash.h +85 -73
- data/contrib/zstd/lib/common/zstd_common.c +83 -0
- data/contrib/zstd/lib/common/zstd_errors.h +94 -0
- data/contrib/zstd/lib/common/zstd_internal.h +447 -0
- data/contrib/zstd/{compress → lib/compress}/fse_compress.c +194 -303
- data/contrib/zstd/lib/compress/hist.c +183 -0
- data/contrib/zstd/lib/compress/hist.h +75 -0
- data/contrib/zstd/lib/compress/huf_compress.c +798 -0
- data/contrib/zstd/lib/compress/zstd_compress.c +4278 -0
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +1125 -0
- data/contrib/zstd/lib/compress/zstd_compress_literals.c +158 -0
- data/contrib/zstd/lib/compress/zstd_compress_literals.h +29 -0
- data/contrib/zstd/lib/compress/zstd_compress_sequences.c +419 -0
- data/contrib/zstd/lib/compress/zstd_compress_sequences.h +54 -0
- data/contrib/zstd/lib/compress/zstd_compress_superblock.c +845 -0
- data/contrib/zstd/lib/compress/zstd_compress_superblock.h +32 -0
- data/contrib/zstd/lib/compress/zstd_cwksp.h +525 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.c +521 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.h +38 -0
- data/contrib/zstd/lib/compress/zstd_fast.c +496 -0
- data/contrib/zstd/lib/compress/zstd_fast.h +37 -0
- data/contrib/zstd/lib/compress/zstd_lazy.c +1138 -0
- data/contrib/zstd/lib/compress/zstd_lazy.h +67 -0
- data/contrib/zstd/lib/compress/zstd_ldm.c +619 -0
- data/contrib/zstd/lib/compress/zstd_ldm.h +110 -0
- data/contrib/zstd/lib/compress/zstd_opt.c +1200 -0
- data/contrib/zstd/lib/compress/zstd_opt.h +56 -0
- data/contrib/zstd/lib/compress/zstdmt_compress.c +2143 -0
- data/contrib/zstd/lib/compress/zstdmt_compress.h +192 -0
- data/contrib/zstd/lib/decompress/huf_decompress.c +1248 -0
- data/contrib/zstd/lib/decompress/zstd_ddict.c +244 -0
- data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
- data/contrib/zstd/lib/decompress/zstd_decompress.c +1885 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1432 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_block.h +59 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +189 -0
- data/contrib/zstd/{common → lib/deprecated}/zbuff.h +86 -69
- data/contrib/zstd/lib/deprecated/zbuff_common.c +26 -0
- data/contrib/zstd/lib/deprecated/zbuff_compress.c +147 -0
- data/contrib/zstd/lib/deprecated/zbuff_decompress.c +75 -0
- data/contrib/zstd/lib/dictBuilder/cover.c +1236 -0
- data/contrib/zstd/lib/dictBuilder/cover.h +157 -0
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.c +3 -3
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.h +5 -5
- data/contrib/zstd/lib/dictBuilder/fastcover.c +757 -0
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/zdict.c +437 -347
- data/contrib/zstd/lib/dictBuilder/zdict.h +305 -0
- data/contrib/zstd/lib/legacy/zstd_legacy.h +415 -0
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.c +272 -292
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.h +26 -32
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.c +162 -392
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.h +26 -32
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.c +162 -391
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.h +27 -33
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.c +195 -604
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.h +26 -32
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.c +300 -575
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.h +22 -31
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.c +165 -592
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.h +54 -67
- data/contrib/zstd/lib/legacy/zstd_v07.c +4541 -0
- data/contrib/zstd/lib/legacy/zstd_v07.h +187 -0
- data/contrib/zstd/lib/libzstd.pc.in +15 -0
- data/contrib/zstd/lib/zstd.h +2090 -0
- data/ext/depend +2 -0
- data/ext/extconf.rb +18 -5
- data/ext/extzstd.c +296 -214
- data/ext/extzstd.h +81 -36
- data/ext/extzstd_nogvls.h +0 -117
- data/ext/extzstd_stream.c +622 -0
- data/ext/libzstd_conf.h +8 -0
- data/ext/zstd_common.c +11 -0
- data/ext/zstd_compress.c +15 -0
- data/ext/zstd_decompress.c +6 -0
- data/ext/zstd_dictbuilder.c +10 -0
- data/ext/zstd_dictbuilder_fastcover.c +3 -0
- data/ext/zstd_legacy_v01.c +3 -1
- data/ext/zstd_legacy_v02.c +3 -1
- data/ext/zstd_legacy_v03.c +3 -1
- data/ext/zstd_legacy_v04.c +3 -1
- data/ext/zstd_legacy_v05.c +3 -1
- data/ext/zstd_legacy_v06.c +3 -1
- data/ext/zstd_legacy_v07.c +3 -0
- data/gemstub.rb +27 -21
- data/lib/extzstd.rb +82 -161
- data/lib/extzstd/version.rb +1 -1
- data/test/test_basic.rb +19 -6
- metadata +127 -59
- data/contrib/zstd/common/error_private.h +0 -125
- data/contrib/zstd/common/error_public.h +0 -77
- data/contrib/zstd/common/huf.h +0 -228
- data/contrib/zstd/common/zstd.h +0 -475
- data/contrib/zstd/common/zstd_common.c +0 -91
- data/contrib/zstd/common/zstd_internal.h +0 -238
- data/contrib/zstd/compress/huf_compress.c +0 -577
- data/contrib/zstd/compress/zbuff_compress.c +0 -327
- data/contrib/zstd/compress/zstd_compress.c +0 -3074
- data/contrib/zstd/compress/zstd_opt.h +0 -1046
- data/contrib/zstd/decompress/huf_decompress.c +0 -894
- data/contrib/zstd/decompress/zbuff_decompress.c +0 -294
- data/contrib/zstd/decompress/zstd_decompress.c +0 -1362
- data/contrib/zstd/dictBuilder/zdict.h +0 -113
- data/contrib/zstd/legacy/zstd_legacy.h +0 -140
- data/ext/extzstd_buffered.c +0 -265
- data/ext/zstd_amalgam.c +0 -18
|
@@ -1,36 +1,15 @@
|
|
|
1
1
|
/* ******************************************************************
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
*
|
|
69
|
-
*
|
|
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
|
-
|
|
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 (
|
|
139
|
+
MEM_STATIC unsigned BIT_highbit32 (U32 val)
|
|
155
140
|
{
|
|
141
|
+
assert(val != 0);
|
|
142
|
+
{
|
|
156
143
|
# if defined(_MSC_VER) /* Visual */
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
147
|
+
return __builtin_clz (val) ^ 31;
|
|
148
|
+
# elif defined(__ICCARM__) /* IAR Intrinsic */
|
|
149
|
+
return 31 - __CLZ(val);
|
|
162
150
|
# else /* Software version */
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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[] = {
|
|
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(
|
|
180
|
+
* `dstCapacity` must be > sizeof(size_t)
|
|
183
181
|
* @return : 0 if success,
|
|
184
|
-
|
|
185
|
-
MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
|
|
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->
|
|
192
|
-
if (dstCapacity <= sizeof(bitC->
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
|
|
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_,
|
|
207
|
-
|
|
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;
|
|
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.
|
|
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;
|
|
248
|
+
bitC->bitContainer >>= nbBytes*8;
|
|
235
249
|
}
|
|
236
250
|
|
|
237
251
|
/*! BIT_closeCStream() :
|
|
238
252
|
* @return : size of CStream, in bytes,
|
|
239
|
-
|
|
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
|
-
*
|
|
264
|
+
* bitStream decoding
|
|
253
265
|
**********************************************************/
|
|
254
266
|
/*! BIT_initDStream() :
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
*
|
|
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
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
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
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
331
|
-
|
|
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
|
-
*
|
|
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
|
|
340
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
362
|
-
MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD,
|
|
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
|
-
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
|
|
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
|
-
|
|
377
|
-
|
|
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->
|
|
380
|
-
|
|
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
|
-
*
|
|
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));
|