| libpgf 7.21.2 PGF - Progressive Graphics File

BitStream.h
Go to the documentation of this file.
1 /*
2 * The Progressive Graphics File; http://www.libpgf.org
3 *
4 * $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $
5 * $Revision: 229 $
6 *
7 * This file Copyright (C) 2006 xeraina GmbH, Switzerland
8 *
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.
13 *
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.
18 *
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.
22 */
23
28
29 #ifndef PGF_BITSTREAM_H
30 #define PGF_BITSTREAM_H
31
32 #include "PGFtypes.h"
33
35 // constants
36 //static const WordWidth = 32;
37 //static const WordWidthLog = 5;
38 static const UINT32 Filled = 0xFFFFFFFF;
39
41 #define MAKEU64(a, b) ((UINT64) (((UINT32) (a)) | ((UINT64) ((UINT32) (b))) << 32))
42
43 /*
44 static UINT8 lMask[] = {
45 0x00, // 00000000
46 0x80, // 10000000
47 0xc0, // 11000000
48 0xe0, // 11100000
49 0xf0, // 11110000
50 0xf8, // 11111000
51 0xfc, // 11111100
52 0xfe, // 11111110
53 0xff, // 11111111
54 };
55 */
56 // these procedures have to be inlined because of performance reasons
57
62 inline void SetBit(UINT32* stream, UINT32 pos) {
63 stream[pos >> WordWidthLog] |= (1 << (pos%WordWidth));
64 }
65
70 inline void ClearBit(UINT32* stream, UINT32 pos) {
71 stream[pos >> WordWidthLog] &= ~(1 << (pos%WordWidth));
72 }
73
79 inline bool GetBit(UINT32* stream, UINT32 pos) {
80 return (stream[pos >> WordWidthLog] & (1 << (pos%WordWidth))) > 0;
81
82 }
83
91 inline bool CompareBitBlock(UINT32* stream, UINT32 pos, UINT32 k, UINT32 val) {
92 const UINT32 iLoInt = pos >> WordWidthLog;
93 const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog;
94 ASSERT(iLoInt <= iHiInt);
95 const UINT32 mask = (Filled >> (WordWidth - k));
96
97 if (iLoInt == iHiInt) {
98 // fits into one integer
99 val &= mask;
100 val <<= (pos%WordWidth);
101 return (stream[iLoInt] & val) == val;
102 } else {
103 // must be splitted over integer boundary
104 UINT64 v1 = MAKEU64(stream[iLoInt], stream[iHiInt]);
105 UINT64 v2 = UINT64(val & mask) << (pos%WordWidth);
106 return (v1 & v2) == v2;
107 }
108 }
109
116 inline void SetValueBlock(UINT32* stream, UINT32 pos, UINT32 val, UINT32 k) {
117 const UINT32 offset = pos%WordWidth;
118 const UINT32 iLoInt = pos >> WordWidthLog;
119 const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog;
120 ASSERT(iLoInt <= iHiInt);
121 const UINT32 loMask = Filled << offset;
122 const UINT32 hiMask = Filled >> (WordWidth - 1 - ((pos + k - 1)%WordWidth));
123
124 if (iLoInt == iHiInt) {
125 // fits into one integer
126 stream[iLoInt] &= ~(loMask & hiMask); // clear bits
127 stream[iLoInt] |= val << offset; // write value
128 } else {
129 // must be splitted over integer boundary
130 stream[iLoInt] &= ~loMask; // clear bits
131 stream[iLoInt] |= val << offset; // write lower part of value
132 stream[iHiInt] &= ~hiMask; // clear bits
133 stream[iHiInt] |= val >> (WordWidth - offset); // write higher part of value
134 }
135 }
136
142 inline UINT32 GetValueBlock(UINT32* stream, UINT32 pos, UINT32 k) {
143 UINT32 count, hiCount;
144 const UINT32 iLoInt = pos >> WordWidthLog; // integer of first bit
145 const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog; // integer of last bit
146 const UINT32 loMask = Filled << (pos%WordWidth);
147 const UINT32 hiMask = Filled >> (WordWidth - 1 - ((pos + k - 1)%WordWidth));
148
149 if (iLoInt == iHiInt) {
150 // inside integer boundary
151 count = stream[iLoInt] & (loMask & hiMask);
152 count >>= pos%WordWidth;
153 } else {
154 // overlapping integer boundary
155 count = stream[iLoInt] & loMask;
156 count >>= pos%WordWidth;
157 hiCount = stream[iHiInt] & hiMask;
158 hiCount <<= WordWidth - (pos%WordWidth);
159 count |= hiCount;
160 }
161 return count;
162 }
163
169 inline void ClearBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
170 ASSERT(len > 0);
171 const UINT32 iFirstInt = pos >> WordWidthLog;
172 const UINT32 iLastInt = (pos + len - 1) >> WordWidthLog;
173
174 const UINT32 startMask = Filled << (pos%WordWidth);
175 // const UINT32 endMask=Filled>>(WordWidth-1-((pos+len-1)%WordWidth));
176
177 if (iFirstInt == iLastInt) {
178 stream[iFirstInt] &= ~(startMask /*& endMask*/);
179 } else {
180 stream[iFirstInt] &= ~startMask;
181 for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) { // changed <=
182 stream[i] = 0;
183 }
184 //stream[iLastInt] &= ~endMask;
185 }
186 }
187
193 inline void SetBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
194 ASSERT(len > 0);
195
196 const UINT32 iFirstInt = pos >> WordWidthLog;
197 const UINT32 iLastInt = (pos + len - 1) >> WordWidthLog;
198
199 const UINT32 startMask = Filled << (pos%WordWidth);
200 // const UINT32 endMask=Filled>>(WordWidth-1-((pos+len-1)%WordWidth));
201
202 if (iFirstInt == iLastInt) {
203 stream[iFirstInt] |= (startMask /*& endMask*/);
204 } else {
205 stream[iFirstInt] |= startMask;
206 for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) { // changed <=
207 stream[i] = Filled;
208 }
209 //stream[iLastInt] &= ~endMask;
210 }
211 }
212
220 inline UINT32 SeekBitRange(UINT32* stream, UINT32 pos, UINT32 len) {
221 UINT32 count = 0;
222 UINT32 testMask = 1 << (pos%WordWidth);
223 UINT32* word = stream + (pos >> WordWidthLog);
224
225 while (((*word & testMask) == 0) && (count < len)) {
226 count++;
227 testMask <<= 1;
228 if (!testMask) {
229 word++; testMask = 1;
230
231 // fast steps if all bits in a word are zero
232 while ((count + WordWidth <= len) && (*word == 0)) {
233 word++;
234 count += WordWidth;
235 }
236 }
237 }
238
239 return count;
240 }
241
249 inline UINT32 SeekBit1Range(UINT32* stream, UINT32 pos, UINT32 len) {
250 UINT32 count = 0;
251 UINT32 testMask = 1 << (pos%WordWidth);
252 UINT32* word = stream + (pos >> WordWidthLog);
253
254 while (((*word & testMask) != 0) && (count < len)) {
255 count++;
256 testMask <<= 1;
257 if (!testMask) {
258 word++; testMask = 1;
259
260 // fast steps if all bits in a word are one
261 while ((count + WordWidth <= len) && (*word == Filled)) {
262 word++;
263 count += WordWidth;
264 }
265 }
266 }
267 return count;
268 }
269 /*
274 inline void BitCopy(const UINT8 *sStream, UINT32 sPos, UINT8 *dStream, UINT32 dPos, UINT32 k) {
275 ASSERT(k > 0);
276
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;
282
283 const UINT8 *sAddr = sStream + divS.quot;
284 UINT8 *dAddrS = dStream + divD.quot;
285 UINT8 *dAddrE = dStream + tmp;
286 UINT8 eMask;
287
288 UINT8 destSB = *dAddrS;
289 UINT8 destEB = *dAddrE;
290 UINT8 *dAddr;
291 UINT8 prec;
292 INT32 shiftl, shiftr;
293
294 if (dOff > sOff) {
295 prec = 0;
296 shiftr = dOff - sOff;
297 shiftl = 8 - dOff + sOff;
298 } else {
299 prec = *sAddr << (sOff - dOff);
300 shiftr = 8 - sOff + dOff;
301 shiftl = sOff - dOff;
302 sAddr++;
303 }
304
305 for (dAddr = dAddrS; dAddr < dAddrE; dAddr++, sAddr++) {
306 *dAddr = prec | (*sAddr >> shiftr);
307 prec = *sAddr << shiftl;
308 }
309
310 if ((sPos + k)%8 == 0) {
311 *dAddr = prec;
312 } else {
313 *dAddr = prec | (*sAddr >> shiftr);
314 }
315
316 eMask = lMask[dOff];
317 *dAddrS = (destSB & eMask) | (*dAddrS & (~eMask));
318
319 INT32 mind = (dPos + k) % 8;
320 eMask = (mind) ? lMask[mind] : lMask[8];
321 *dAddrE = (destEB & (~eMask)) | (*dAddrE & eMask);
322 }
323 */
328 inline UINT32 AlignWordPos(UINT32 pos) {
329 // return ((pos + WordWidth - 1) >> WordWidthLog) << WordWidthLog;
330 return DWWIDTHBITS(pos);
331 }
332
337 inline UINT32 NumberOfWords(UINT32 pos) {
338 return (pos + WordWidth - 1) >> WordWidthLog;
339 }
340
341 #endif //PGF_BITSTREAM_H
GetBit
bool GetBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:79
AlignWordPos
UINT32 AlignWordPos(UINT32 pos)
Definition: BitStream.h:328
MAKEU64
#define MAKEU64(a, b)
Make 64 bit unsigned integer from two 32 bit unsigned integers.
Definition: BitStream.h:41
SetBitBlock
void SetBitBlock(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:193
DWWIDTHBITS
#define DWWIDTHBITS(bits)
aligns scanline width in bits to DWORD value
Definition: PGFplatform.h:83
WordWidthLog
#define WordWidthLog
ld of WordWidth
Definition: PGFplatform.h:74
ClearBit
void ClearBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:70
ClearBitBlock
void ClearBitBlock(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:169
SeekBitRange
UINT32 SeekBitRange(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:220
SeekBit1Range
UINT32 SeekBit1Range(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:249
SetBit
void SetBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:62
PGFtypes.h
PGF definitions.
GetValueBlock
UINT32 GetValueBlock(UINT32 *stream, UINT32 pos, UINT32 k)
Definition: BitStream.h:142
NumberOfWords
UINT32 NumberOfWords(UINT32 pos)
Definition: BitStream.h:337
SetValueBlock
void SetValueBlock(UINT32 *stream, UINT32 pos, UINT32 val, UINT32 k)
Definition: BitStream.h:116
Filled
static const UINT32 Filled
Definition: BitStream.h:38
CompareBitBlock
bool CompareBitBlock(UINT32 *stream, UINT32 pos, UINT32 k, UINT32 val)
Definition: BitStream.h:91
WordWidth
#define WordWidth
WordBytes*8.
Definition: PGFplatform.h:73