1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000,2001,2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 #include "OSGConfig.h"
40 #include "OSGNFIOBitPacker.h"
46 /***************************************************************************\
48 \***************************************************************************/
50 /*! \class OSG::BitPacker
51 packs and unpacks UInt32.
54 /*-------------------------------------------------------------------------*\
56 \*-------------------------------------------------------------------------*/
58 /***************************************************************************\
60 \***************************************************************************/
62 const Int32
BitPacker::BITS_PER_WORD
= 32;
64 /***************************************************************************\
66 \***************************************************************************/
68 /*----------------------------- constructors -----------------------------*/
70 BitPacker::BitPacker(UInt32 size
, UInt32 max
)
77 UInt32 maxValue
= UInt32(1 << _numBitsToPack
) - 1;
85 UInt32 lenInBytes
= (_numBitsToPack
* size
+ 7) / 8;
87 _buffer
.resize(lenInBytes
);
88 memset(&_buffer
[0], 0, lenInBytes
* sizeof(UInt8
)); // unneccessary ?
91 void BitPacker::pack(UInt32 value
)
93 Int32 numBitsToPack
= _numBitsToPack
;
95 // Scoot the value bits up to the top of the word; this makes
96 // them easier to work with.
97 value
<<= (BITS_PER_WORD
- numBitsToPack
);
99 // First we do the hard part: pack bits into the first u8,
100 // which may already have bits in it.
102 Int32 byteIndex
= (_nextBit
/ 8);
103 Int32 bitIndex
= (_nextBit
% 8);
104 Int32 spaceCurrByte
= (8 - bitIndex
) & 0x7;
106 // Update _nextBit for the next call; we don't need
107 // the old value any more
108 _nextBit
+= numBitsToPack
;
110 UInt8
*dest
= &_buffer
[0] + byteIndex
;
114 Int32 toCopy
= spaceCurrByte
;
116 if(toCopy
> numBitsToPack
)
118 // We don't have enough bits to fill up this u8.
119 toCopy
= numBitsToPack
;
122 UInt32 fillBits
= value
>> (BITS_PER_WORD
- spaceCurrByte
);
125 numBitsToPack
-= toCopy
;
130 // Now we do the fast and easy part for what is hopefully
131 // the bulk of the data.
134 *dest
++ = value
>> (BITS_PER_WORD
- 8);
139 const BitPacker::BufferType
&
140 BitPacker::getBuffer(void) const
145 BitPacker::BufferType
&
146 BitPacker::getBuffer(void)
151 /*-------------------------------------------------------------------------*\
153 \*-------------------------------------------------------------------------*/
156 /***************************************************************************\
158 \***************************************************************************/
160 /*----------------------------- constructors -----------------------------*/
162 BitUnpacker::BitUnpacker(const std::vector
<UInt8
> &buffer
, UInt32 max
) :
163 _numBitsToUnpack (1 ),
164 _numBitsRemaining(Int32(buffer
.size()) * 8),
170 UInt32 maxValue
= UInt32(1 << _numBitsToUnpack
) - 1;
178 UInt32
BitUnpacker::unpack(void)
181 UInt32 numBitsToUnpack
= _numBitsToUnpack
;
183 while(numBitsToUnpack
)
185 UInt32 byteIndex
= (_nextBit
/ 8);
186 UInt32 bitIndex
= (_nextBit
% 8);
187 UInt32 srcMask
= (1 << (7 - bitIndex
));
188 UInt32 destMask
= (1 << (numBitsToUnpack
- 1));
190 if(_buffer
[byteIndex
] & srcMask
)
196 _numBitsRemaining
-= numBitsToUnpack
;