libpgf
6.11.42
PGF - Progressive Graphics 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