Scribus
Open source desktop publishing at your fingertips
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 
34 // constants
35 //static const WordWidth = 32;
36 //static const WordWidthLog = 5;
37 static const UINT32 Filled = 0xFFFFFFFF;
38 
40 #define MAKEU64(a, b) ((UINT64) (((UINT32) (a)) | ((UINT64) ((UINT32) (b))) << 32))
41 
42 // these procedures have to be inlined because of performance reasons
43 
48 inline void SetBit(UINT32* stream, UINT32 pos) {
49  stream[pos >> WordWidthLog] |= (1 << (pos%WordWidth));
50 }
51 
56 inline void ClearBit(UINT32* stream, UINT32 pos) {
57  stream[pos >> WordWidthLog] &= ~(1 << (pos%WordWidth));
58 }
59 
65 inline bool GetBit(UINT32* stream, UINT32 pos) {
66  return (stream[pos >> WordWidthLog] & (1 << (pos%WordWidth))) > 0;
67 
68 }
69 
77 inline bool CompareBitBlock(UINT32* stream, UINT32 pos, UINT32 k, UINT32 val) {
78  const UINT32 iLoInt = pos >> WordWidthLog;
79  const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog;
80  ASSERT(iLoInt <= iHiInt);
81  const UINT32 mask = (Filled >> (WordWidth - k));
82 
83  if (iLoInt == iHiInt) {
84  // fits into one integer
85  val &= mask;
86  val <<= (pos%WordWidth);
87  return (stream[iLoInt] & val) == val;
88  } else {
89  // must be splitted over integer boundary
90  UINT64 v1 = MAKEU64(stream[iLoInt], stream[iHiInt]);
91  UINT64 v2 = UINT64(val & mask) << (pos%WordWidth);
92  return (v1 & v2) == v2;
93  }
94 }
95 
102 inline void SetValueBlock(UINT32* stream, UINT32 pos, UINT32 val, UINT32 k) {
103  const UINT32 offset = pos%WordWidth;
104  const UINT32 iLoInt = pos >> WordWidthLog;
105  const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog;
106  ASSERT(iLoInt <= iHiInt);
107  const UINT32 loMask = Filled << offset;
108  const UINT32 hiMask = Filled >> (WordWidth - 1 - ((pos + k - 1)%WordWidth));
109 
110  if (iLoInt == iHiInt) {
111  // fits into one integer
112  stream[iLoInt] &= ~(loMask & hiMask); // clear bits
113  stream[iLoInt] |= val << offset; // write value
114  } else {
115  // must be splitted over integer boundary
116  stream[iLoInt] &= ~loMask; // clear bits
117  stream[iLoInt] |= val << offset; // write lower part of value
118  stream[iHiInt] &= ~hiMask; // clear bits
119  stream[iHiInt] |= val >> (WordWidth - offset); // write higher part of value
120  }
121 }
122 
128 inline UINT32 GetValueBlock(UINT32* stream, UINT32 pos, UINT32 k) {
129  UINT32 count, hiCount;
130  const UINT32 iLoInt = pos >> WordWidthLog; // integer of first bit
131  const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog; // integer of last bit
132  const UINT32 loMask = Filled << (pos%WordWidth);
133  const UINT32 hiMask = Filled >> (WordWidth - 1 - ((pos + k - 1)%WordWidth));
134 
135  if (iLoInt == iHiInt) {
136  // inside integer boundary
137  count = stream[iLoInt] & (loMask & hiMask);
138  count >>= pos%WordWidth;
139  } else {
140  // overlapping integer boundary
141  count = stream[iLoInt] & loMask;
142  count >>= pos%WordWidth;
143  hiCount = stream[iHiInt] & hiMask;
144  hiCount <<= WordWidth - (pos%WordWidth);
145  count |= hiCount;
146  }
147  return count;
148 }
149 
155 inline void ClearBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
156  ASSERT(len > 0);
157  const UINT32 iFirstInt = pos >> WordWidthLog;
158  const UINT32 iLastInt = (pos + len - 1) >> WordWidthLog;
159 
160  const UINT32 startMask = Filled << (pos%WordWidth);
161 // const UINT32 endMask=Filled>>(WordWidth-1-((pos+len-1)%WordWidth));
162 
163  if (iFirstInt == iLastInt) {
164  stream[iFirstInt] &= ~(startMask /*& endMask*/);
165  } else {
166  stream[iFirstInt] &= ~startMask;
167  for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) { // changed <=
168  stream[i] = 0;
169  }
170  //stream[iLastInt] &= ~endMask;
171  }
172 }
173 
179 inline void SetBitBlock(UINT32* stream, UINT32 pos, UINT32 len) {
180  ASSERT(len > 0);
181 
182  const UINT32 iFirstInt = pos >> WordWidthLog;
183  const UINT32 iLastInt = (pos + len - 1) >> WordWidthLog;
184 
185  const UINT32 startMask = Filled << (pos%WordWidth);
186 // const UINT32 endMask=Filled>>(WordWidth-1-((pos+len-1)%WordWidth));
187 
188  if (iFirstInt == iLastInt) {
189  stream[iFirstInt] |= (startMask /*& endMask*/);
190  } else {
191  stream[iFirstInt] |= startMask;
192  for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) { // changed <=
193  stream[i] = Filled;
194  }
195  //stream[iLastInt] &= ~endMask;
196  }
197 }
198 
206 inline UINT32 SeekBitRange(UINT32* stream, UINT32 pos, UINT32 len) {
207  UINT32 count = 0;
208  UINT32 testMask = 1 << (pos%WordWidth);
209  UINT32* word = stream + (pos >> WordWidthLog);
210 
211  while (((*word & testMask) == 0) && (count < len)) {
212  count++;
213  testMask <<= 1;
214  if (!testMask) {
215  word++; testMask = 1;
216 
217  // fast steps if all bits in a word are zero
218  while ((count + WordWidth <= len) && (*word == 0)) {
219  word++;
220  count += WordWidth;
221  }
222  }
223  }
224 
225  return count;
226 }
227 
235 inline UINT32 SeekBit1Range(UINT32* stream, UINT32 pos, UINT32 len) {
236  UINT32 count = 0;
237  UINT32 testMask = 1 << (pos%WordWidth);
238  UINT32* word = stream + (pos >> WordWidthLog);
239 
240  while (((*word & testMask) != 0) && (count < len)) {
241  count++;
242  testMask <<= 1;
243  if (!testMask) {
244  word++; testMask = 1;
245 
246  // fast steps if all bits in a word are one
247  while ((count + WordWidth <= len) && (*word == Filled)) {
248  word++;
249  count += WordWidth;
250  }
251  }
252  }
253  return count;
254 }
255 
260 inline UINT32 AlignWordPos(UINT32 pos) {
261 // return ((pos + WordWidth - 1) >> WordWidthLog) << WordWidthLog;
262  return DWWIDTHBITS(pos);
263 }
264 
269 inline UINT32 NumberOfWords(UINT32 pos) {
270  return (pos + WordWidth - 1) >> WordWidthLog;
271 }
272 #endif //PGF_BITSTREAM_H
void SetValueBlock(UINT32 *stream, UINT32 pos, UINT32 val, UINT32 k)
Definition: BitStream.h:102
#define DWWIDTHBITS(bits)
aligns scanline width in bits to DWORD value
Definition: PGFplatform.h:83
UINT32 AlignWordPos(UINT32 pos)
Definition: BitStream.h:260
void SetBitBlock(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:179
UINT32 SeekBitRange(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:206
void ClearBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:56
void ClearBitBlock(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:155
bool GetBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:65
UINT32 NumberOfWords(UINT32 pos)
Definition: BitStream.h:269
#define WordWidth
WordBytes*8.
Definition: PGFplatform.h:73
PGF definitions.
UINT32 SeekBit1Range(UINT32 *stream, UINT32 pos, UINT32 len)
Definition: BitStream.h:235
#define WordWidthLog
ld of WordWidth
Definition: PGFplatform.h:74
#define MAKEU64(a, b)
Make 64 bit unsigned integer from two 32 bit unsigned integers.
Definition: BitStream.h:40
bool CompareBitBlock(UINT32 *stream, UINT32 pos, UINT32 k, UINT32 val)
Definition: BitStream.h:77
void SetBit(UINT32 *stream, UINT32 pos)
Definition: BitStream.h:48
UINT32 GetValueBlock(UINT32 *stream, UINT32 pos, UINT32 k)
Definition: BitStream.h:128