2
* The Progressive Graphics File; http://www.libpgf.org
4
* $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $
7
* This file Copyright (C) 2006 xeraina GmbH, Switzerland
9
* This program is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
11
* as published by the Free Software Foundation; either version 2.1
12
* of the License, or (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
#ifndef PGF_BITSTREAM_H
25
#define PGF_BITSTREAM_H
30
//static const WordWidth = 32;
31
//static const WordWidthLog = 5;
32
static const UINT32 Filled = 0xFFFFFFFF;
34
#define MAKEU64(a, b) ((UINT64) (((UINT32) (a)) | ((UINT64) ((UINT32) (b))) << 32))
36
// these procedures have to be inlined because of performance reasons
38
//////////////////////////////////////////////////////////////////////
39
/// Set one bit of a bit stream to 1
40
/// @param stream A bit stream composed of unsigned integer arrays
41
/// @param pos A valid zero-based position in the bit stream
42
inline void SetBit(UINT32* stream, UINT32 pos) {
43
stream[pos >> WordWidthLog] |= (1 << (pos%WordWidth));
46
//////////////////////////////////////////////////////////////////////
47
/// Set one bit of a bit stream to 0
48
/// @param stream A bit stream composed of unsigned integer arrays
49
/// @param pos A valid zero-based position in the bit stream
50
inline void ClearBit(UINT32* stream, UINT32 pos) {
51
stream[pos >> WordWidthLog] &= ~(1 << (pos%WordWidth));
54
//////////////////////////////////////////////////////////////////////
55
/// Return one bit of a bit stream
56
/// @param stream A bit stream composed of unsigned integer arrays
57
/// @param pos A valid zero-based position in the bit stream
58
/// @return bit at position pos of bit stream stream
59
inline bool GetBit(UINT32* stream, UINT32 pos) {
60
return (stream[pos >> WordWidthLog] & (1 << (pos%WordWidth))) > 0;
64
//////////////////////////////////////////////////////////////////////
65
/// Compare k-bit binary representation of stream at postition pos with val
66
/// @param stream A bit stream composed of unsigned integer arrays
67
/// @param pos A valid zero-based position in the bit stream
68
/// @param k Number of bits to compare
69
/// @return true if equal
70
inline bool CompareBitBlock(UINT32* stream, UINT32 pos, UINT32 k, UINT32 val) {
71
const UINT32 iLoInt = pos >> WordWidthLog;
72
const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog;
73
ASSERT(iLoInt <= iHiInt);
74
const UINT32 mask = (Filled >> (WordWidth - k));
76
if (iLoInt == iHiInt) {
77
// fits into one integer
79
val <<= (pos%WordWidth);
80
return (stream[iLoInt] & val) == val;
82
// must be splitted over integer boundary
83
UINT64 v1 = MAKEU64(stream[iLoInt], stream[iHiInt]);
84
UINT64 v2 = UINT64(val & mask) << (pos%WordWidth);
85
return (v1 & v2) == v2;
89
//////////////////////////////////////////////////////////////////////
90
/// Store k-bit binary representation of val in stream at postition pos
91
/// @param stream A bit stream composed of unsigned integer arrays
92
/// @param pos A valid zero-based position in the bit stream
93
/// @param k Number of bits of integer representation of val
94
inline void SetValueBlock(UINT32* stream, UINT32 pos, UINT32 val, UINT32 k) {
95
const UINT32 iLoInt = pos >> WordWidthLog;
96
const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog;
97
ASSERT(iLoInt <= iHiInt);
98
const UINT32 loMask = Filled << (pos%WordWidth);
99
const UINT32 hiMask = Filled >> (WordWidth - 1 - ((pos + k - 1)%WordWidth));
101
if (iLoInt == iHiInt) {
102
// fits into one integer
103
stream[iLoInt] &= ~(loMask & hiMask);
104
stream[iLoInt] |= val << (pos%WordWidth);
106
// must be splitted over integer boundary
107
stream[iLoInt] &= ~loMask;
108
stream[iLoInt] |= val << (pos%WordWidth);
109
stream[iHiInt] &= ~hiMask;
110
stream[iHiInt] |= val >> (WordWidth - (pos%WordWidth));
114
//////////////////////////////////////////////////////////////////////
115
/// Read k-bit number from stream at position pos
116
/// @param stream A bit stream composed of unsigned integer arrays
117
/// @param pos A valid zero-based position in the bit stream
118
/// @param k Number of bits to read: 1 <= k <= 32
119
inline UINT32 GetValueBlock(UINT32* stream, UINT32 pos, UINT32 k) {
120
UINT32 count, hiCount;
121
const UINT32 iLoInt = pos >> WordWidthLog; // integer of first bit
122
const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog; // integer of last bit
123
const UINT32 loMask = Filled << (pos%WordWidth);
124
const UINT32 hiMask = Filled >> (WordWidth - 1 - ((pos + k - 1)%WordWidth));
126
if (iLoInt == iHiInt) {
127
// inside integer boundary
128
count = stream[iLoInt] & (loMask & hiMask);
129
count >>= pos%WordWidth;
131
// overlapping integer boundary
132
count = stream[iLoInt] & loMask;
133
count >>= pos%WordWidth;
134
hiCount = stream[iHiInt] & hiMask;
135
hiCount <<= WordWidth - (pos%WordWidth);
141
//////////////////////////////////////////////////////////////////////
142
/// Clear block of size at least len at position pos in stream
143
/// @param stream A bit stream composed of unsigned integer arrays
144
/// @param pos A valid zero-based position in the bit stream
145
/// @param len Number of bits set to 0
146
inline void ClearBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
148
const UINT32 iFirstInt = pos >> WordWidthLog;
149
const UINT32 iLastInt = (pos + len - 1) >> WordWidthLog;
151
const UINT32 startMask = Filled << (pos%WordWidth);
152
// const UINT32 endMask=Filled>>(WordWidth-1-((pos+len-1)%WordWidth));
154
if (iFirstInt == iLastInt) {
155
stream[iFirstInt] &= ~(startMask /*& endMask*/);
157
stream[iFirstInt] &= ~startMask;
158
for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) { // changed <=
161
//stream[iLastInt] &= ~endMask;
165
//////////////////////////////////////////////////////////////////////
166
/// Set block of size at least len at position pos in stream
167
/// @param stream A bit stream composed of unsigned integer arrays
168
/// @param pos A valid zero-based position in the bit stream
169
/// @param len Number of bits set to 1
170
inline void SetBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
173
const UINT32 iFirstInt = pos >> WordWidthLog;
174
const UINT32 iLastInt = (pos + len - 1) >> WordWidthLog;
176
const UINT32 startMask = Filled << (pos%WordWidth);
177
// const UINT32 endMask=Filled>>(WordWidth-1-((pos+len-1)%WordWidth));
179
if (iFirstInt == iLastInt) {
180
stream[iFirstInt] |= (startMask /*& endMask*/);
182
stream[iFirstInt] |= startMask;
183
for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) { // changed <=
186
//stream[iLastInt] &= ~endMask;
190
//////////////////////////////////////////////////////////////////////
191
/// Returns the distance to the next 1 in stream at position pos.
192
/// If no 1 is found within len bits, then len is returned.
193
/// @param stream A bit stream composed of unsigned integer arrays
194
/// @param pos A valid zero-based position in the bit stream
195
/// @param len size of search area (in bits)
196
/// return The distance to the next 1 in stream at position pos
197
inline UINT32 SeekBitRange(UINT32* stream, UINT32 pos, UINT32 len) {
199
UINT32 wordPos = pos >> WordWidthLog;
200
UINT32 testMask = 1 << (pos%WordWidth);
201
UINT32* word = stream + wordPos;
203
while (((*word & testMask) == 0) && (count < len)) {
207
word++; testMask = 1;
209
// fast steps if all bits in a word are zero
210
while ((count + WordWidth <= len) && (*word == 0)) {
220
//////////////////////////////////////////////////////////////////////
221
/// Returns the distance to the next 0 in stream at position pos.
222
/// If no 0 is found within len bits, then len is returned.
223
/// @param stream A bit stream composed of unsigned integer arrays
224
/// @param pos A valid zero-based position in the bit stream
225
/// @param len size of search area (in bits)
226
/// return The distance to the next 0 in stream at position pos
227
inline UINT32 SeekBit1Range(UINT32* stream, UINT32 pos, UINT32 len) {
229
UINT32 wordPos = pos >> WordWidthLog;
230
UINT32 bitPos = pos%WordWidth;
231
UINT32 testMask = 1 << bitPos;
233
while (((stream[wordPos] & testMask) != 0) && (count < len)) {
234
ASSERT(bitPos < WordWidth);
237
if (bitPos < WordWidth) {
240
wordPos++; bitPos = 0; testMask = 1;
242
// fast steps if all bits in a word are zero
243
while ((count + WordWidth <= len) && (stream[wordPos] == Filled)) {
252
//////////////////////////////////////////////////////////////////////
253
/// Compute position to beginning of the next 32-bit word
254
/// @param pos Current bit stream position
255
/// @return Position of next 32-bit word
256
inline UINT32 AlignWordPos(UINT32 pos) {
257
// return (pos%WordWidth) ? pos + (WordWidth - pos%WordWidth) : pos;
258
// return pos + (WordWidth - pos%WordWidth)%WordWidth;
259
return ((pos + WordWidth - 1) >> WordWidthLog) << WordWidthLog;
262
//////////////////////////////////////////////////////////////////////
263
/// Compute number of the 32-bit words
264
/// @param pos Current bit stream position
265
/// @return Number of 32-bit words
266
inline UINT32 NumberOfWords(UINT32 pos) {
267
return (pos + WordWidth - 1) >> WordWidthLog;
269
#endif //PGF_BITSTREAM_H