1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifndef BITSTREAM_H_MODULE
15#define BITSTREAM_H_MODULE
16
17
18
19
20
21
22
23
24
25
26#include "mem.h"
27#include "compiler.h"
28#include "debug.h"
29#include "error_private.h"
30
31
32
33
34
35
36#define STREAM_ACCUMULATOR_MIN_32 25
37#define STREAM_ACCUMULATOR_MIN_64 57
38#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
39
40
41
42
43
44
45
46
47
48typedef struct {
49 size_t bitContainer;
50 unsigned bitPos;
51 char* startPtr;
52 char* ptr;
53 char* endPtr;
54} BIT_CStream_t;
55
56MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity);
57MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
58MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC);
59MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82typedef struct {
83 size_t bitContainer;
84 unsigned bitsConsumed;
85 const char* ptr;
86 const char* start;
87 const char* limitPtr;
88} BIT_DStream_t;
89
90typedef enum { BIT_DStream_unfinished = 0,
91 BIT_DStream_endOfBuffer = 1,
92 BIT_DStream_completed = 2,
93 BIT_DStream_overflow = 3 } BIT_DStream_status;
94
95
96MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
97MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
98MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);
99MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
117
118
119MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);
120
121
122MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
123
124
125
126
127
128
129
130MEM_STATIC unsigned BIT_highbit32 (U32 val)
131{
132 assert(val != 0);
133 {
134# if (__GNUC__ >= 3)
135 return __builtin_clz (val) ^ 31;
136# else
137 static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
138 11, 14, 16, 18, 22, 25, 3, 30,
139 8, 12, 20, 28, 15, 17, 24, 7,
140 19, 27, 23, 6, 26, 5, 4, 31 };
141 U32 v = val;
142 v |= v >> 1;
143 v |= v >> 2;
144 v |= v >> 4;
145 v |= v >> 8;
146 v |= v >> 16;
147 return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
148# endif
149 }
150}
151
152
153static const unsigned BIT_mask[] = {
154 0, 1, 3, 7, 0xF, 0x1F,
155 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF,
156 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF,
157 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF,
158 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF,
159 0x3FFFFFFF, 0x7FFFFFFF};
160#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0]))
161
162
163
164
165
166
167
168
169MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
170 void* startPtr, size_t dstCapacity)
171{
172 bitC->bitContainer = 0;
173 bitC->bitPos = 0;
174 bitC->startPtr = (char*)startPtr;
175 bitC->ptr = bitC->startPtr;
176 bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer);
177 if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall);
178 return 0;
179}
180
181
182
183
184MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
185 size_t value, unsigned nbBits)
186{
187 DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32);
188 assert(nbBits < BIT_MASK_SIZE);
189 assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
190 bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
191 bitC->bitPos += nbBits;
192}
193
194
195
196
197MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC,
198 size_t value, unsigned nbBits)
199{
200 assert((value>>nbBits) == 0);
201 assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
202 bitC->bitContainer |= value << bitC->bitPos;
203 bitC->bitPos += nbBits;
204}
205
206
207
208
209MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
210{
211 size_t const nbBytes = bitC->bitPos >> 3;
212 assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
213 assert(bitC->ptr <= bitC->endPtr);
214 MEM_writeLEST(bitC->ptr, bitC->bitContainer);
215 bitC->ptr += nbBytes;
216 bitC->bitPos &= 7;
217 bitC->bitContainer >>= nbBytes*8;
218}
219
220
221
222
223
224
225MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
226{
227 size_t const nbBytes = bitC->bitPos >> 3;
228 assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
229 assert(bitC->ptr <= bitC->endPtr);
230 MEM_writeLEST(bitC->ptr, bitC->bitContainer);
231 bitC->ptr += nbBytes;
232 if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
233 bitC->bitPos &= 7;
234 bitC->bitContainer >>= nbBytes*8;
235}
236
237
238
239
240MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
241{
242 BIT_addBitsFast(bitC, 1, 1);
243 BIT_flushBits(bitC);
244 if (bitC->ptr >= bitC->endPtr) return 0;
245 return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
246}
247
248
249
250
251
252
253
254
255
256
257
258MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
259{
260 if (srcSize < 1) { ZSTD_memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
261
262 bitD->start = (const char*)srcBuffer;
263 bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer);
264
265 if (srcSize >= sizeof(bitD->bitContainer)) {
266 bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
267 bitD->bitContainer = MEM_readLEST(bitD->ptr);
268 { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
269 bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
270 if (lastByte == 0) return ERROR(GENERIC); }
271 } else {
272 bitD->ptr = bitD->start;
273 bitD->bitContainer = *(const BYTE*)(bitD->start);
274 switch(srcSize)
275 {
276 case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
277 ZSTD_FALLTHROUGH;
278
279 case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
280 ZSTD_FALLTHROUGH;
281
282 case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
283 ZSTD_FALLTHROUGH;
284
285 case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
286 ZSTD_FALLTHROUGH;
287
288 case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
289 ZSTD_FALLTHROUGH;
290
291 case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
292 ZSTD_FALLTHROUGH;
293
294 default: break;
295 }
296 { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
297 bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
298 if (lastByte == 0) return ERROR(corruption_detected);
299 }
300 bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
301 }
302
303 return srcSize;
304}
305
306MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
307{
308 return bitContainer >> start;
309}
310
311MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
312{
313 U32 const regMask = sizeof(bitContainer)*8 - 1;
314
315 assert(nbBits < BIT_MASK_SIZE);
316 return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
317}
318
319MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
320{
321 assert(nbBits < BIT_MASK_SIZE);
322 return bitContainer & BIT_mask[nbBits];
323}
324
325
326
327
328
329
330
331MEM_STATIC FORCE_INLINE_ATTR size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
332{
333
334#if 1
335
336
337 return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
338#else
339
340 U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
341 return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask);
342#endif
343}
344
345
346
347MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
348{
349 U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
350 assert(nbBits >= 1);
351 return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);
352}
353
354MEM_STATIC FORCE_INLINE_ATTR void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
355{
356 bitD->bitsConsumed += nbBits;
357}
358
359
360
361
362
363MEM_STATIC FORCE_INLINE_ATTR size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
364{
365 size_t const value = BIT_lookBits(bitD, nbBits);
366 BIT_skipBits(bitD, nbBits);
367 return value;
368}
369
370
371
372MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
373{
374 size_t const value = BIT_lookBitsFast(bitD, nbBits);
375 assert(nbBits >= 1);
376 BIT_skipBits(bitD, nbBits);
377 return value;
378}
379
380
381
382
383
384
385
386MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD)
387{
388 if (UNLIKELY(bitD->ptr < bitD->limitPtr))
389 return BIT_DStream_overflow;
390 assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8);
391 bitD->ptr -= bitD->bitsConsumed >> 3;
392 bitD->bitsConsumed &= 7;
393 bitD->bitContainer = MEM_readLEST(bitD->ptr);
394 return BIT_DStream_unfinished;
395}
396
397
398
399
400
401
402MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
403{
404 if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))
405 return BIT_DStream_overflow;
406
407 if (bitD->ptr >= bitD->limitPtr) {
408 return BIT_reloadDStreamFast(bitD);
409 }
410 if (bitD->ptr == bitD->start) {
411 if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
412 return BIT_DStream_completed;
413 }
414
415 { U32 nbBytes = bitD->bitsConsumed >> 3;
416 BIT_DStream_status result = BIT_DStream_unfinished;
417 if (bitD->ptr - nbBytes < bitD->start) {
418 nbBytes = (U32)(bitD->ptr - bitD->start);
419 result = BIT_DStream_endOfBuffer;
420 }
421 bitD->ptr -= nbBytes;
422 bitD->bitsConsumed -= nbBytes*8;
423 bitD->bitContainer = MEM_readLEST(bitD->ptr);
424 return result;
425 }
426}
427
428
429
430
431MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
432{
433 return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
434}
435
436
437#endif
438