libpgf  6.11.42
PGF - Progressive Graphics File
BitStream.h
Go to the documentation of this file.
00001 /*
00002  * The Progressive Graphics File; http://www.libpgf.org
00003  * 
00004  * $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $
00005  * $Revision: 229 $
00006  * 
00007  * This file Copyright (C) 2006 xeraina GmbH, Switzerland
00008  * 
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
00011  * as published by the Free Software Foundation; either version 2.1
00012  * of the License, or (at your option) any later version.
00013  * 
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022  */
00023 
00028 
00029 #ifndef PGF_BITSTREAM_H
00030 #define PGF_BITSTREAM_H
00031 
00032 #include "PGFtypes.h"
00033 
00034 // constants
00035 //static const WordWidth = 32;
00036 //static const WordWidthLog = 5;
00037 static const UINT32 Filled = 0xFFFFFFFF;
00038 
00040 #define MAKEU64(a, b) ((UINT64) (((UINT32) (a)) | ((UINT64) ((UINT32) (b))) << 32)) 
00041  
00042 // these procedures have to be inlined because of performance reasons
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                 // fits into one integer
00085                 val &= mask;
00086                 val <<= (pos%WordWidth);
00087                 return (stream[iLoInt] & val) == val;
00088         } else {
00089                 // must be splitted over integer boundary
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                 // fits into one integer
00112                 stream[iLoInt] &= ~(loMask & hiMask); // clear bits
00113                 stream[iLoInt] |= val << offset; // write value
00114         } else {
00115                 // must be splitted over integer boundary
00116                 stream[iLoInt] &= ~loMask; // clear bits
00117                 stream[iLoInt] |= val << offset; // write lower part of value
00118                 stream[iHiInt] &= ~hiMask; // clear bits
00119                 stream[iHiInt] |= val >> (WordWidth - offset); // write higher part of value
00120         }
00121 }
00122 
00128 inline UINT32 GetValueBlock(UINT32* stream, UINT32 pos, UINT32 k) {
00129         UINT32 count, hiCount;
00130         const UINT32 iLoInt = pos >> WordWidthLog;                              // integer of first bit
00131         const UINT32 iHiInt = (pos + k - 1) >> WordWidthLog;            // integer of last bit
00132         const UINT32 loMask = Filled << (pos%WordWidth);
00133         const UINT32 hiMask = Filled >> (WordWidth - 1 - ((pos + k - 1)%WordWidth));
00134         
00135         if (iLoInt == iHiInt) {
00136                 // inside integer boundary
00137                 count = stream[iLoInt] & (loMask & hiMask);
00138                 count >>= pos%WordWidth;
00139         } else {
00140                 // overlapping integer boundary
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 //      const UINT32 endMask=Filled>>(WordWidth-1-((pos+len-1)%WordWidth));
00162 
00163         if (iFirstInt == iLastInt) {
00164                 stream[iFirstInt] &= ~(startMask /*& endMask*/);
00165         } else {
00166                 stream[iFirstInt] &= ~startMask;
00167                 for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) { // changed <=
00168                         stream[i] = 0;
00169                 }
00170                 //stream[iLastInt] &= ~endMask;
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 //      const UINT32 endMask=Filled>>(WordWidth-1-((pos+len-1)%WordWidth));
00187 
00188         if (iFirstInt == iLastInt) {
00189                 stream[iFirstInt] |= (startMask /*& endMask*/);
00190         } else {
00191                 stream[iFirstInt] |= startMask;
00192                 for (UINT32 i = iFirstInt + 1; i <= iLastInt; i++) { // changed <=
00193                         stream[i] = Filled;
00194                 }
00195                 //stream[iLastInt] &= ~endMask;
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                         // fast steps if all bits in a word are zero
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                         // fast steps if all bits in a word are one
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 //      return ((pos + WordWidth - 1) >> WordWidthLog) << WordWidthLog;
00262         return DWWIDTHBITS(pos);
00263 }
00264 
00269 inline UINT32 NumberOfWords(UINT32 pos) {
00270         return (pos + WordWidth - 1) >> WordWidthLog;
00271 }
00272 #endif //PGF_BITSTREAM_H
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines