29#ifndef PGF_BITSTREAM_H
30#define PGF_BITSTREAM_H
38static const UINT32
Filled = 0xFFFFFFFF;
41#define MAKEU64(a, b) ((UINT64) (((UINT32) (a)) | ((UINT64) ((UINT32) (b))) << 32))
62inline void SetBit(UINT32* stream, UINT32 pos) {
70inline void ClearBit(UINT32* stream, UINT32 pos) {
79inline bool GetBit(UINT32* stream, UINT32 pos) {
94 ASSERT(iLoInt <= iHiInt);
97 if (iLoInt == iHiInt) {
101 return (stream[iLoInt] & val) == val;
104 UINT64 v1 =
MAKEU64(stream[iLoInt], stream[iHiInt]);
105 UINT64 v2 = UINT64(val & mask) << (pos%
WordWidth);
106 return (v1 & v2) == v2;
116inline void SetValueBlock(UINT32* stream, UINT32 pos, UINT32 val, UINT32 k) {
120 ASSERT(iLoInt <= iHiInt);
121 const UINT32 loMask =
Filled << offset;
124 if (iLoInt == iHiInt) {
126 stream[iLoInt] &= ~(loMask & hiMask);
127 stream[iLoInt] |= val << offset;
130 stream[iLoInt] &= ~loMask;
131 stream[iLoInt] |= val << offset;
132 stream[iHiInt] &= ~hiMask;
133 stream[iHiInt] |= val >> (
WordWidth - offset);
143 UINT32 count, hiCount;
149 if (iLoInt == iHiInt) {
151 count = stream[iLoInt] & (loMask & hiMask);
155 count = stream[iLoInt] & loMask;
157 hiCount = stream[iHiInt] & hiMask;
172 const UINT32 iLastInt = (pos + len - 1) >>
WordWidthLog;
177 if (iFirstInt == iLastInt) {
178 stream[iFirstInt] &= ~(startMask );
180 stream[iFirstInt] &= ~startMask;
181 for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) {
197 const UINT32 iLastInt = (pos + len - 1) >>
WordWidthLog;
202 if (iFirstInt == iLastInt) {
203 stream[iFirstInt] |= (startMask );
205 stream[iFirstInt] |= startMask;
206 for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) {
225 while (((*word & testMask) == 0) && (count < len)) {
229 word++; testMask = 1;
232 while ((count +
WordWidth <= len) && (*word == 0)) {
254 while (((*word & testMask) != 0) && (count < len)) {
258 word++; testMask = 1;
274inline void BitCopy(const UINT8 *sStream, UINT32 sPos, UINT8 *dStream, UINT32 dPos, UINT32 k) {
277 div_t divS = div(sPos, 8);
278 div_t divD = div(dPos, 8);
279 UINT32 sOff = divS.rem;
280 UINT32 dOff = divD.rem;
281 INT32 tmp = div(dPos + k - 1, 8).quot;
283 const UINT8 *sAddr = sStream + divS.quot;
284 UINT8 *dAddrS = dStream + divD.quot;
285 UINT8 *dAddrE = dStream + tmp;
288 UINT8 destSB = *dAddrS;
289 UINT8 destEB = *dAddrE;
292 INT32 shiftl, shiftr;
296 shiftr = dOff - sOff;
297 shiftl = 8 - dOff + sOff;
299 prec = *sAddr << (sOff - dOff);
300 shiftr = 8 - sOff + dOff;
301 shiftl = sOff - dOff;
305 for (dAddr = dAddrS; dAddr < dAddrE; dAddr++, sAddr++) {
306 *dAddr = prec | (*sAddr >> shiftr);
307 prec = *sAddr << shiftl;
310 if ((sPos + k)%8 == 0) {
313 *dAddr = prec | (*sAddr >> shiftr);
317 *dAddrS = (destSB & eMask) | (*dAddrS & (~eMask));
319 INT32 mind = (dPos + k) % 8;
320 eMask = (mind) ? lMask[mind] : lMask[8];
321 *dAddrE = (destEB & (~eMask)) | (*dAddrE & eMask);
UINT32 AlignWordPos(UINT32 pos)
static const UINT32 Filled
void SetBit(UINT32 *stream, UINT32 pos)
void SetValueBlock(UINT32 *stream, UINT32 pos, UINT32 val, UINT32 k)
bool CompareBitBlock(UINT32 *stream, UINT32 pos, UINT32 k, UINT32 val)
void ClearBit(UINT32 *stream, UINT32 pos)
bool GetBit(UINT32 *stream, UINT32 pos)
void SetBitBlock(UINT32 *stream, UINT32 pos, UINT32 len)
UINT32 GetValueBlock(UINT32 *stream, UINT32 pos, UINT32 k)
void ClearBitBlock(UINT32 *stream, UINT32 pos, UINT32 len)
UINT32 SeekBit1Range(UINT32 *stream, UINT32 pos, UINT32 len)
#define MAKEU64(a, b)
Make 64 bit unsigned integer from two 32 bit unsigned integers.
UINT32 SeekBitRange(UINT32 *stream, UINT32 pos, UINT32 len)
UINT32 NumberOfWords(UINT32 pos)