00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00028
00029 #ifndef PGF_BITSTREAM_H
00030 #define PGF_BITSTREAM_H
00031
00032 #include "PGFtypes.h"
00033
00034
00035
00036
00037 static const UINT32 Filled = 0xFFFFFFFF;
00038
00040 #define MAKEU64(a, b) ((UINT64) (((UINT32) (a)) | ((UINT64) ((UINT32) (b))) << 32))
00041
00042
00043
00048 inline void SetBit(UINT32* stream, UINT32 pos) {
00049 stream[pos >> WordWidthLog] |= (1 << (pos%WordWidth));
00050 }
00051
00056 inline void ClearBit(UINT32* stream, UINT32 pos) {
00057 stream[pos >> WordWidthLog] &= ~(1 << (pos%WordWidth));
00058 }
00059
00065 inline bool GetBit(UINT32* stream, UINT32 pos) {
00066 return (stream[pos >> WordWidthLog] & (1 << (pos%WordWidth))) > 0;
00067
00068 }
00069
00077 inline bool CompareBitBlock(UINT32* stream, UINT32 pos, UINT32 k, UINT32 val) {
00078 const UINT32 iLoInt = pos >> WordWidthLog;
00079 const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog;
00080 ASSERT(iLoInt <= iHiInt);
00081 const UINT32 mask = (Filled >> (WordWidth - k));
00082
00083 if (iLoInt == iHiInt) {
00084
00085 val &= mask;
00086 val <<= (pos%WordWidth);
00087 return (stream[iLoInt] & val) == val;
00088 } else {
00089
00090 UINT64 v1 = MAKEU64(stream[iLoInt], stream[iHiInt]);
00091 UINT64 v2 = UINT64(val & mask) << (pos%WordWidth);
00092 return (v1 & v2) == v2;
00093 }
00094 }
00095
00102 inline void SetValueBlock(UINT32* stream, UINT32 pos, UINT32 val, UINT32 k) {
00103 const UINT32 offset = pos%WordWidth;
00104 const UINT32 iLoInt = pos >> WordWidthLog;
00105 const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog;
00106 ASSERT(iLoInt <= iHiInt);
00107 const UINT32 loMask = Filled << offset;
00108 const UINT32 hiMask = Filled >> (WordWidth - 1 - ((pos + k - 1)%WordWidth));
00109
00110 if (iLoInt == iHiInt) {
00111
00112 stream[iLoInt] &= ~(loMask & hiMask);
00113 stream[iLoInt] |= val << offset;
00114 } else {
00115
00116 stream[iLoInt] &= ~loMask;
00117 stream[iLoInt] |= val << offset;
00118 stream[iHiInt] &= ~hiMask;
00119 stream[iHiInt] |= val >> (WordWidth - offset);
00120 }
00121 }
00122
00128 inline UINT32 GetValueBlock(UINT32* stream, UINT32 pos, UINT32 k) {
00129 UINT32 count, hiCount;
00130 const UINT32 iLoInt = pos >> WordWidthLog;
00131 const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog;
00132 const UINT32 loMask = Filled << (pos%WordWidth);
00133 const UINT32 hiMask = Filled >> (WordWidth - 1 - ((pos + k - 1)%WordWidth));
00134
00135 if (iLoInt == iHiInt) {
00136
00137 count = stream[iLoInt] & (loMask & hiMask);
00138 count >>= pos%WordWidth;
00139 } else {
00140
00141 count = stream[iLoInt] & loMask;
00142 count >>= pos%WordWidth;
00143 hiCount = stream[iHiInt] & hiMask;
00144 hiCount <<= WordWidth - (pos%WordWidth);
00145 count |= hiCount;
00146 }
00147 return count;
00148 }
00149
00155 inline void ClearBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
00156 ASSERT(len > 0);
00157 const UINT32 iFirstInt = pos >> WordWidthLog;
00158 const UINT32 iLastInt = (pos + len - 1) >> WordWidthLog;
00159
00160 const UINT32 startMask = Filled << (pos%WordWidth);
00161
00162
00163 if (iFirstInt == iLastInt) {
00164 stream[iFirstInt] &= ~(startMask );
00165 } else {
00166 stream[iFirstInt] &= ~startMask;
00167 for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) {
00168 stream[i] = 0;
00169 }
00170
00171 }
00172 }
00173
00179 inline void SetBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
00180 ASSERT(len > 0);
00181
00182 const UINT32 iFirstInt = pos >> WordWidthLog;
00183 const UINT32 iLastInt = (pos + len - 1) >> WordWidthLog;
00184
00185 const UINT32 startMask = Filled << (pos%WordWidth);
00186
00187
00188 if (iFirstInt == iLastInt) {
00189 stream[iFirstInt] |= (startMask );
00190 } else {
00191 stream[iFirstInt] |= startMask;
00192 for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) {
00193 stream[i] = Filled;
00194 }
00195
00196 }
00197 }
00198
00206 inline UINT32 SeekBitRange(UINT32* stream, UINT32 pos, UINT32 len) {
00207 UINT32 count = 0;
00208 UINT32 testMask = 1 << (pos%WordWidth);
00209 UINT32* word = stream + (pos >> WordWidthLog);
00210
00211 while (((*word & testMask) == 0) && (count < len)) {
00212 count++;
00213 testMask <<= 1;
00214 if (!testMask) {
00215 word++; testMask = 1;
00216
00217
00218 while ((count + WordWidth <= len) && (*word == 0)) {
00219 word++;
00220 count += WordWidth;
00221 }
00222 }
00223 }
00224
00225 return count;
00226 }
00227
00235 inline UINT32 SeekBit1Range(UINT32* stream, UINT32 pos, UINT32 len) {
00236 UINT32 count = 0;
00237 UINT32 testMask = 1 << (pos%WordWidth);
00238 UINT32* word = stream + (pos >> WordWidthLog);
00239
00240 while (((*word & testMask) != 0) && (count < len)) {
00241 count++;
00242 testMask <<= 1;
00243 if (!testMask) {
00244 word++; testMask = 1;
00245
00246
00247 while ((count + WordWidth <= len) && (*word == Filled)) {
00248 word++;
00249 count += WordWidth;
00250 }
00251 }
00252 }
00253 return count;
00254 }
00255
00260 inline UINT32 AlignWordPos(UINT32 pos) {
00261
00262 return DWWIDTHBITS(pos);
00263 }
00264
00269 inline UINT32 NumberOfWords(UINT32 pos) {
00270 return (pos + WordWidth - 1) >> WordWidthLog;
00271 }
00272 #endif //PGF_BITSTREAM_H