fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / FileIO / OSB / OSGNFIOBitPacker.cpp
blob2df7ea048b0f92bda98782516a923c27fd56582b
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000,2001,2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
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. *
18 * *
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. *
23 * *
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. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 #include "OSGConfig.h"
40 #include "OSGNFIOBitPacker.h"
42 #include <cstring>
44 OSG_USING_NAMESPACE
46 /***************************************************************************\
47 * Description *
48 \***************************************************************************/
50 /*! \class OSG::BitPacker
51 packs and unpacks UInt32.
54 /*-------------------------------------------------------------------------*\
55 - Packer -
56 \*-------------------------------------------------------------------------*/
58 /***************************************************************************\
59 * Class variables *
60 \***************************************************************************/
62 const Int32 BitPacker::BITS_PER_WORD = 32;
64 /***************************************************************************\
65 * Instance methods *
66 \***************************************************************************/
68 /*----------------------------- constructors -----------------------------*/
70 BitPacker::BitPacker(UInt32 size, UInt32 max)
71 : _numBitsToPack(1),
72 _nextBit (0),
73 _buffer ( )
75 while(true)
77 UInt32 maxValue = UInt32(1 << _numBitsToPack) - 1;
78 if (maxValue >= max)
79 break;
81 ++_numBitsToPack;
84 // calc buffer size.
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;
112 if(spaceCurrByte)
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);
123 *dest |= fillBits;
125 numBitsToPack -= toCopy;
126 dest++;
127 value <<= toCopy;
130 // Now we do the fast and easy part for what is hopefully
131 // the bulk of the data.
132 while(value)
134 *dest++ = value >> (BITS_PER_WORD - 8);
135 value <<= 8;
139 const BitPacker::BufferType &
140 BitPacker::getBuffer(void) const
142 return _buffer;
145 BitPacker::BufferType &
146 BitPacker::getBuffer(void)
148 return _buffer;
151 /*-------------------------------------------------------------------------*\
152 - Unpacker -
153 \*-------------------------------------------------------------------------*/
156 /***************************************************************************\
157 * Instance methods *
158 \***************************************************************************/
160 /*----------------------------- constructors -----------------------------*/
162 BitUnpacker::BitUnpacker(const std::vector<UInt8> &buffer, UInt32 max) :
163 _numBitsToUnpack (1 ),
164 _numBitsRemaining(Int32(buffer.size()) * 8),
165 _nextBit (0 ),
166 _buffer (buffer )
168 while(true)
170 UInt32 maxValue = UInt32(1 << _numBitsToUnpack) - 1;
171 if (maxValue >= max)
172 break;
174 ++_numBitsToUnpack;
178 UInt32 BitUnpacker::unpack(void)
180 UInt32 result = 0;
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)
191 result |= destMask;
192 numBitsToUnpack--;
193 _nextBit++;
196 _numBitsRemaining -= numBitsToUnpack;
198 return result;