1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * bitstream
3*4882a593Smuzhiyun * Part of FSE library
4*4882a593Smuzhiyun * header file (to include)
5*4882a593Smuzhiyun * Copyright (C) 2013-2016, Yann Collet.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * Redistribution and use in source and binary forms, with or without
10*4882a593Smuzhiyun * modification, are permitted provided that the following conditions are
11*4882a593Smuzhiyun * met:
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * * Redistributions of source code must retain the above copyright
14*4882a593Smuzhiyun * notice, this list of conditions and the following disclaimer.
15*4882a593Smuzhiyun * * Redistributions in binary form must reproduce the above
16*4882a593Smuzhiyun * copyright notice, this list of conditions and the following disclaimer
17*4882a593Smuzhiyun * in the documentation and/or other materials provided with the
18*4882a593Smuzhiyun * distribution.
19*4882a593Smuzhiyun *
20*4882a593Smuzhiyun * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*4882a593Smuzhiyun * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*4882a593Smuzhiyun * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23*4882a593Smuzhiyun * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24*4882a593Smuzhiyun * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25*4882a593Smuzhiyun * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26*4882a593Smuzhiyun * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27*4882a593Smuzhiyun * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28*4882a593Smuzhiyun * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29*4882a593Smuzhiyun * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30*4882a593Smuzhiyun * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*4882a593Smuzhiyun *
32*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify it under
33*4882a593Smuzhiyun * the terms of the GNU General Public License version 2 as published by the
34*4882a593Smuzhiyun * Free Software Foundation. This program is dual-licensed; you may select
35*4882a593Smuzhiyun * either version 2 of the GNU General Public License ("GPL") or BSD license
36*4882a593Smuzhiyun * ("BSD").
37*4882a593Smuzhiyun *
38*4882a593Smuzhiyun * You can contact the author at :
39*4882a593Smuzhiyun * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
40*4882a593Smuzhiyun */
41*4882a593Smuzhiyun #ifndef BITSTREAM_H_MODULE
42*4882a593Smuzhiyun #define BITSTREAM_H_MODULE
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /*
45*4882a593Smuzhiyun * This API consists of small unitary functions, which must be inlined for best performance.
46*4882a593Smuzhiyun * Since link-time-optimization is not available for all compilers,
47*4882a593Smuzhiyun * these functions are defined into a .h to be included.
48*4882a593Smuzhiyun */
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun /*-****************************************
51*4882a593Smuzhiyun * Dependencies
52*4882a593Smuzhiyun ******************************************/
53*4882a593Smuzhiyun #include "error_private.h" /* error codes and messages */
54*4882a593Smuzhiyun #include "mem.h" /* unaligned access routines */
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun /*=========================================
57*4882a593Smuzhiyun * Target specific
58*4882a593Smuzhiyun =========================================*/
59*4882a593Smuzhiyun #define STREAM_ACCUMULATOR_MIN_32 25
60*4882a593Smuzhiyun #define STREAM_ACCUMULATOR_MIN_64 57
61*4882a593Smuzhiyun #define STREAM_ACCUMULATOR_MIN ((U32)(ZSTD_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun /*-******************************************
64*4882a593Smuzhiyun * bitStream encoding API (write forward)
65*4882a593Smuzhiyun ********************************************/
66*4882a593Smuzhiyun /* bitStream can mix input from multiple sources.
67*4882a593Smuzhiyun * A critical property of these streams is that they encode and decode in **reverse** direction.
68*4882a593Smuzhiyun * So the first bit sequence you add will be the last to be read, like a LIFO stack.
69*4882a593Smuzhiyun */
70*4882a593Smuzhiyun typedef struct {
71*4882a593Smuzhiyun size_t bitContainer;
72*4882a593Smuzhiyun int bitPos;
73*4882a593Smuzhiyun char *startPtr;
74*4882a593Smuzhiyun char *ptr;
75*4882a593Smuzhiyun char *endPtr;
76*4882a593Smuzhiyun } BIT_CStream_t;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_initCStream(BIT_CStream_t *bitC, void *dstBuffer, size_t dstCapacity);
79*4882a593Smuzhiyun ZSTD_STATIC void BIT_addBits(BIT_CStream_t *bitC, size_t value, unsigned nbBits);
80*4882a593Smuzhiyun ZSTD_STATIC void BIT_flushBits(BIT_CStream_t *bitC);
81*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_closeCStream(BIT_CStream_t *bitC);
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun /* Start with initCStream, providing the size of buffer to write into.
84*4882a593Smuzhiyun * bitStream will never write outside of this buffer.
85*4882a593Smuzhiyun * `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code.
86*4882a593Smuzhiyun *
87*4882a593Smuzhiyun * bits are first added to a local register.
88*4882a593Smuzhiyun * Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems.
89*4882a593Smuzhiyun * Writing data into memory is an explicit operation, performed by the flushBits function.
90*4882a593Smuzhiyun * Hence keep track how many bits are potentially stored into local register to avoid register overflow.
91*4882a593Smuzhiyun * After a flushBits, a maximum of 7 bits might still be stored into local register.
92*4882a593Smuzhiyun *
93*4882a593Smuzhiyun * Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers.
94*4882a593Smuzhiyun *
95*4882a593Smuzhiyun * Last operation is to close the bitStream.
96*4882a593Smuzhiyun * The function returns the final size of CStream in bytes.
97*4882a593Smuzhiyun * If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable)
98*4882a593Smuzhiyun */
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun /*-********************************************
101*4882a593Smuzhiyun * bitStream decoding API (read backward)
102*4882a593Smuzhiyun **********************************************/
103*4882a593Smuzhiyun typedef struct {
104*4882a593Smuzhiyun size_t bitContainer;
105*4882a593Smuzhiyun unsigned bitsConsumed;
106*4882a593Smuzhiyun const char *ptr;
107*4882a593Smuzhiyun const char *start;
108*4882a593Smuzhiyun } BIT_DStream_t;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun typedef enum {
111*4882a593Smuzhiyun BIT_DStream_unfinished = 0,
112*4882a593Smuzhiyun BIT_DStream_endOfBuffer = 1,
113*4882a593Smuzhiyun BIT_DStream_completed = 2,
114*4882a593Smuzhiyun BIT_DStream_overflow = 3
115*4882a593Smuzhiyun } BIT_DStream_status; /* result of BIT_reloadDStream() */
116*4882a593Smuzhiyun /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_initDStream(BIT_DStream_t *bitD, const void *srcBuffer, size_t srcSize);
119*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_readBits(BIT_DStream_t *bitD, unsigned nbBits);
120*4882a593Smuzhiyun ZSTD_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t *bitD);
121*4882a593Smuzhiyun ZSTD_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t *bitD);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun /* Start by invoking BIT_initDStream().
124*4882a593Smuzhiyun * A chunk of the bitStream is then stored into a local register.
125*4882a593Smuzhiyun * Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
126*4882a593Smuzhiyun * You can then retrieve bitFields stored into the local register, **in reverse order**.
127*4882a593Smuzhiyun * Local register is explicitly reloaded from memory by the BIT_reloadDStream() method.
128*4882a593Smuzhiyun * A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished.
129*4882a593Smuzhiyun * Otherwise, it can be less than that, so proceed accordingly.
130*4882a593Smuzhiyun * Checking if DStream has reached its end can be performed with BIT_endOfDStream().
131*4882a593Smuzhiyun */
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun /*-****************************************
134*4882a593Smuzhiyun * unsafe API
135*4882a593Smuzhiyun ******************************************/
136*4882a593Smuzhiyun ZSTD_STATIC void BIT_addBitsFast(BIT_CStream_t *bitC, size_t value, unsigned nbBits);
137*4882a593Smuzhiyun /* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun ZSTD_STATIC void BIT_flushBitsFast(BIT_CStream_t *bitC);
140*4882a593Smuzhiyun /* unsafe version; does not check buffer overflow */
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_readBitsFast(BIT_DStream_t *bitD, unsigned nbBits);
143*4882a593Smuzhiyun /* faster, but works only if nbBits >= 1 */
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun /*-**************************************************************
146*4882a593Smuzhiyun * Internal functions
147*4882a593Smuzhiyun ****************************************************************/
BIT_highbit32(register U32 val)148*4882a593Smuzhiyun ZSTD_STATIC unsigned BIT_highbit32(register U32 val) { return 31 - __builtin_clz(val); }
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun /*===== Local Constants =====*/
151*4882a593Smuzhiyun static const unsigned BIT_mask[] = {0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF,
152*4882a593Smuzhiyun 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF,
153*4882a593Smuzhiyun 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF}; /* up to 26 bits */
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun /*-**************************************************************
156*4882a593Smuzhiyun * bitStream encoding
157*4882a593Smuzhiyun ****************************************************************/
158*4882a593Smuzhiyun /*! BIT_initCStream() :
159*4882a593Smuzhiyun * `dstCapacity` must be > sizeof(void*)
160*4882a593Smuzhiyun * @return : 0 if success,
161*4882a593Smuzhiyun otherwise an error code (can be tested using ERR_isError() ) */
BIT_initCStream(BIT_CStream_t * bitC,void * startPtr,size_t dstCapacity)162*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_initCStream(BIT_CStream_t *bitC, void *startPtr, size_t dstCapacity)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun bitC->bitContainer = 0;
165*4882a593Smuzhiyun bitC->bitPos = 0;
166*4882a593Smuzhiyun bitC->startPtr = (char *)startPtr;
167*4882a593Smuzhiyun bitC->ptr = bitC->startPtr;
168*4882a593Smuzhiyun bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->ptr);
169*4882a593Smuzhiyun if (dstCapacity <= sizeof(bitC->ptr))
170*4882a593Smuzhiyun return ERROR(dstSize_tooSmall);
171*4882a593Smuzhiyun return 0;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun /*! BIT_addBits() :
175*4882a593Smuzhiyun can add up to 26 bits into `bitC`.
176*4882a593Smuzhiyun Does not check for register overflow ! */
BIT_addBits(BIT_CStream_t * bitC,size_t value,unsigned nbBits)177*4882a593Smuzhiyun ZSTD_STATIC void BIT_addBits(BIT_CStream_t *bitC, size_t value, unsigned nbBits)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
180*4882a593Smuzhiyun bitC->bitPos += nbBits;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun /*! BIT_addBitsFast() :
184*4882a593Smuzhiyun * works only if `value` is _clean_, meaning all high bits above nbBits are 0 */
BIT_addBitsFast(BIT_CStream_t * bitC,size_t value,unsigned nbBits)185*4882a593Smuzhiyun ZSTD_STATIC void BIT_addBitsFast(BIT_CStream_t *bitC, size_t value, unsigned nbBits)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun bitC->bitContainer |= value << bitC->bitPos;
188*4882a593Smuzhiyun bitC->bitPos += nbBits;
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun /*! BIT_flushBitsFast() :
192*4882a593Smuzhiyun * unsafe version; does not check buffer overflow */
BIT_flushBitsFast(BIT_CStream_t * bitC)193*4882a593Smuzhiyun ZSTD_STATIC void BIT_flushBitsFast(BIT_CStream_t *bitC)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun size_t const nbBytes = bitC->bitPos >> 3;
196*4882a593Smuzhiyun ZSTD_writeLEST(bitC->ptr, bitC->bitContainer);
197*4882a593Smuzhiyun bitC->ptr += nbBytes;
198*4882a593Smuzhiyun bitC->bitPos &= 7;
199*4882a593Smuzhiyun bitC->bitContainer >>= nbBytes * 8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun /*! BIT_flushBits() :
203*4882a593Smuzhiyun * safe version; check for buffer overflow, and prevents it.
204*4882a593Smuzhiyun * note : does not signal buffer overflow. This will be revealed later on using BIT_closeCStream() */
BIT_flushBits(BIT_CStream_t * bitC)205*4882a593Smuzhiyun ZSTD_STATIC void BIT_flushBits(BIT_CStream_t *bitC)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun size_t const nbBytes = bitC->bitPos >> 3;
208*4882a593Smuzhiyun ZSTD_writeLEST(bitC->ptr, bitC->bitContainer);
209*4882a593Smuzhiyun bitC->ptr += nbBytes;
210*4882a593Smuzhiyun if (bitC->ptr > bitC->endPtr)
211*4882a593Smuzhiyun bitC->ptr = bitC->endPtr;
212*4882a593Smuzhiyun bitC->bitPos &= 7;
213*4882a593Smuzhiyun bitC->bitContainer >>= nbBytes * 8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun /*! BIT_closeCStream() :
217*4882a593Smuzhiyun * @return : size of CStream, in bytes,
218*4882a593Smuzhiyun or 0 if it could not fit into dstBuffer */
BIT_closeCStream(BIT_CStream_t * bitC)219*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_closeCStream(BIT_CStream_t *bitC)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun BIT_addBitsFast(bitC, 1, 1); /* endMark */
222*4882a593Smuzhiyun BIT_flushBits(bitC);
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun if (bitC->ptr >= bitC->endPtr)
225*4882a593Smuzhiyun return 0; /* doesn't fit within authorized budget : cancel */
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun /*-********************************************************
231*4882a593Smuzhiyun * bitStream decoding
232*4882a593Smuzhiyun **********************************************************/
233*4882a593Smuzhiyun /*! BIT_initDStream() :
234*4882a593Smuzhiyun * Initialize a BIT_DStream_t.
235*4882a593Smuzhiyun * `bitD` : a pointer to an already allocated BIT_DStream_t structure.
236*4882a593Smuzhiyun * `srcSize` must be the *exact* size of the bitStream, in bytes.
237*4882a593Smuzhiyun * @return : size of stream (== srcSize) or an errorCode if a problem is detected
238*4882a593Smuzhiyun */
BIT_initDStream(BIT_DStream_t * bitD,const void * srcBuffer,size_t srcSize)239*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_initDStream(BIT_DStream_t *bitD, const void *srcBuffer, size_t srcSize)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun if (srcSize < 1) {
242*4882a593Smuzhiyun memset(bitD, 0, sizeof(*bitD));
243*4882a593Smuzhiyun return ERROR(srcSize_wrong);
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */
247*4882a593Smuzhiyun bitD->start = (const char *)srcBuffer;
248*4882a593Smuzhiyun bitD->ptr = (const char *)srcBuffer + srcSize - sizeof(bitD->bitContainer);
249*4882a593Smuzhiyun bitD->bitContainer = ZSTD_readLEST(bitD->ptr);
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun BYTE const lastByte = ((const BYTE *)srcBuffer)[srcSize - 1];
252*4882a593Smuzhiyun bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
253*4882a593Smuzhiyun if (lastByte == 0)
254*4882a593Smuzhiyun return ERROR(GENERIC); /* endMark not present */
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun } else {
257*4882a593Smuzhiyun bitD->start = (const char *)srcBuffer;
258*4882a593Smuzhiyun bitD->ptr = bitD->start;
259*4882a593Smuzhiyun bitD->bitContainer = *(const BYTE *)(bitD->start);
260*4882a593Smuzhiyun switch (srcSize) {
261*4882a593Smuzhiyun case 7: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[6]) << (sizeof(bitD->bitContainer) * 8 - 16);
262*4882a593Smuzhiyun /* fall through */
263*4882a593Smuzhiyun case 6: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[5]) << (sizeof(bitD->bitContainer) * 8 - 24);
264*4882a593Smuzhiyun /* fall through */
265*4882a593Smuzhiyun case 5: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[4]) << (sizeof(bitD->bitContainer) * 8 - 32);
266*4882a593Smuzhiyun /* fall through */
267*4882a593Smuzhiyun case 4: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[3]) << 24;
268*4882a593Smuzhiyun /* fall through */
269*4882a593Smuzhiyun case 3: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[2]) << 16;
270*4882a593Smuzhiyun /* fall through */
271*4882a593Smuzhiyun case 2: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[1]) << 8;
272*4882a593Smuzhiyun default:;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun BYTE const lastByte = ((const BYTE *)srcBuffer)[srcSize - 1];
276*4882a593Smuzhiyun bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
277*4882a593Smuzhiyun if (lastByte == 0)
278*4882a593Smuzhiyun return ERROR(GENERIC); /* endMark not present */
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize) * 8;
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun return srcSize;
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun
BIT_getUpperBits(size_t bitContainer,U32 const start)286*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start) { return bitContainer >> start; }
287*4882a593Smuzhiyun
BIT_getMiddleBits(size_t bitContainer,U32 const start,U32 const nbBits)288*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) { return (bitContainer >> start) & BIT_mask[nbBits]; }
289*4882a593Smuzhiyun
BIT_getLowerBits(size_t bitContainer,U32 const nbBits)290*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) { return bitContainer & BIT_mask[nbBits]; }
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun /*! BIT_lookBits() :
293*4882a593Smuzhiyun * Provides next n bits from local register.
294*4882a593Smuzhiyun * local register is not modified.
295*4882a593Smuzhiyun * On 32-bits, maxNbBits==24.
296*4882a593Smuzhiyun * On 64-bits, maxNbBits==56.
297*4882a593Smuzhiyun * @return : value extracted
298*4882a593Smuzhiyun */
BIT_lookBits(const BIT_DStream_t * bitD,U32 nbBits)299*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_lookBits(const BIT_DStream_t *bitD, U32 nbBits)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun U32 const bitMask = sizeof(bitD->bitContainer) * 8 - 1;
302*4882a593Smuzhiyun return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask - nbBits) & bitMask);
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun /*! BIT_lookBitsFast() :
306*4882a593Smuzhiyun * unsafe version; only works only if nbBits >= 1 */
BIT_lookBitsFast(const BIT_DStream_t * bitD,U32 nbBits)307*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t *bitD, U32 nbBits)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun U32 const bitMask = sizeof(bitD->bitContainer) * 8 - 1;
310*4882a593Smuzhiyun return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask + 1) - nbBits) & bitMask);
311*4882a593Smuzhiyun }
312*4882a593Smuzhiyun
BIT_skipBits(BIT_DStream_t * bitD,U32 nbBits)313*4882a593Smuzhiyun ZSTD_STATIC void BIT_skipBits(BIT_DStream_t *bitD, U32 nbBits) { bitD->bitsConsumed += nbBits; }
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun /*! BIT_readBits() :
316*4882a593Smuzhiyun * Read (consume) next n bits from local register and update.
317*4882a593Smuzhiyun * Pay attention to not read more than nbBits contained into local register.
318*4882a593Smuzhiyun * @return : extracted value.
319*4882a593Smuzhiyun */
BIT_readBits(BIT_DStream_t * bitD,U32 nbBits)320*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_readBits(BIT_DStream_t *bitD, U32 nbBits)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun size_t const value = BIT_lookBits(bitD, nbBits);
323*4882a593Smuzhiyun BIT_skipBits(bitD, nbBits);
324*4882a593Smuzhiyun return value;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun /*! BIT_readBitsFast() :
328*4882a593Smuzhiyun * unsafe version; only works only if nbBits >= 1 */
BIT_readBitsFast(BIT_DStream_t * bitD,U32 nbBits)329*4882a593Smuzhiyun ZSTD_STATIC size_t BIT_readBitsFast(BIT_DStream_t *bitD, U32 nbBits)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun size_t const value = BIT_lookBitsFast(bitD, nbBits);
332*4882a593Smuzhiyun BIT_skipBits(bitD, nbBits);
333*4882a593Smuzhiyun return value;
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun /*! BIT_reloadDStream() :
337*4882a593Smuzhiyun * Refill `bitD` from buffer previously set in BIT_initDStream() .
338*4882a593Smuzhiyun * This function is safe, it guarantees it will not read beyond src buffer.
339*4882a593Smuzhiyun * @return : status of `BIT_DStream_t` internal register.
340*4882a593Smuzhiyun if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
BIT_reloadDStream(BIT_DStream_t * bitD)341*4882a593Smuzhiyun ZSTD_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t *bitD)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun if (bitD->bitsConsumed > (sizeof(bitD->bitContainer) * 8)) /* should not happen => corruption detected */
344*4882a593Smuzhiyun return BIT_DStream_overflow;
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
347*4882a593Smuzhiyun bitD->ptr -= bitD->bitsConsumed >> 3;
348*4882a593Smuzhiyun bitD->bitsConsumed &= 7;
349*4882a593Smuzhiyun bitD->bitContainer = ZSTD_readLEST(bitD->ptr);
350*4882a593Smuzhiyun return BIT_DStream_unfinished;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun if (bitD->ptr == bitD->start) {
353*4882a593Smuzhiyun if (bitD->bitsConsumed < sizeof(bitD->bitContainer) * 8)
354*4882a593Smuzhiyun return BIT_DStream_endOfBuffer;
355*4882a593Smuzhiyun return BIT_DStream_completed;
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun U32 nbBytes = bitD->bitsConsumed >> 3;
359*4882a593Smuzhiyun BIT_DStream_status result = BIT_DStream_unfinished;
360*4882a593Smuzhiyun if (bitD->ptr - nbBytes < bitD->start) {
361*4882a593Smuzhiyun nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */
362*4882a593Smuzhiyun result = BIT_DStream_endOfBuffer;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun bitD->ptr -= nbBytes;
365*4882a593Smuzhiyun bitD->bitsConsumed -= nbBytes * 8;
366*4882a593Smuzhiyun bitD->bitContainer = ZSTD_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */
367*4882a593Smuzhiyun return result;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun /*! BIT_endOfDStream() :
372*4882a593Smuzhiyun * @return Tells if DStream has exactly reached its end (all bits consumed).
373*4882a593Smuzhiyun */
BIT_endOfDStream(const BIT_DStream_t * DStream)374*4882a593Smuzhiyun ZSTD_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t *DStream)
375*4882a593Smuzhiyun {
376*4882a593Smuzhiyun return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer) * 8));
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun #endif /* BITSTREAM_H_MODULE */
380