xref: /OK3568_Linux_fs/kernel/lib/zstd/bitstream.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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