PageRenderTime 105ms CodeModel.GetById 68ms app.highlight 31ms RepoModel.GetById 2ms app.codeStats 0ms

/indra/llcommon/bitpack.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 208 lines | 162 code | 21 blank | 25 comment | 20 complexity | d7622c219aa3ce24de68f1458696a805 MD5 | raw file
  1/** 
  2 * @file bitpack.h
  3 * @brief Convert data to packed bit stream
  4 *
  5 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library 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 GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#ifndef LL_BITPACK_H
 28#define LL_BITPACK_H
 29
 30#include "llerror.h"
 31
 32const U32 MAX_DATA_BITS = 8;
 33
 34
 35class LLBitPack
 36{
 37public:
 38	LLBitPack(U8 *buffer, U32 max_size) : mBuffer(buffer), mBufferSize(0), mLoad(0), mLoadSize(0), mTotalBits(0), mMaxSize(max_size)
 39	{
 40	}
 41
 42	~LLBitPack()
 43	{
 44	}
 45
 46	void resetBitPacking()
 47	{
 48		mLoad = 0;
 49		mLoadSize = 0;
 50		mTotalBits = 0;
 51		mBufferSize = 0;
 52	}
 53
 54	U32 bitPack(U8 *total_data, U32 total_dsize)
 55	{
 56		U32 dsize;
 57		U8 data;
 58
 59		while (total_dsize > 0)
 60		{
 61			if (total_dsize > MAX_DATA_BITS)
 62			{
 63				dsize = MAX_DATA_BITS;
 64				total_dsize -= MAX_DATA_BITS;
 65			}
 66			else
 67			{
 68				dsize = total_dsize;
 69				total_dsize = 0;
 70			}
 71
 72			data = *total_data++;
 73
 74			data <<= (MAX_DATA_BITS - dsize);
 75			while (dsize > 0) 
 76			{
 77				if (mLoadSize == MAX_DATA_BITS) 
 78				{
 79					*(mBuffer + mBufferSize++) = mLoad;
 80					if (mBufferSize > mMaxSize)
 81					{
 82						llerror("mBufferSize exceeding mMaxSize!", 0);
 83					}
 84					mLoadSize = 0;
 85					mLoad = 0x00;
 86				}
 87				mLoad <<= 1;			
 88				mLoad |= (data >> (MAX_DATA_BITS - 1));
 89				data <<= 1;
 90				mLoadSize++;
 91				mTotalBits++;
 92				dsize--;
 93			}
 94		}
 95		return mBufferSize;
 96	}
 97
 98	U32 bitCopy(U8 *total_data, U32 total_dsize)
 99	{
100		U32 dsize;
101		U8  data;
102
103		while (total_dsize > 0)
104		{
105			if (total_dsize > MAX_DATA_BITS)
106			{
107				dsize = MAX_DATA_BITS;
108				total_dsize -= MAX_DATA_BITS;
109			}
110			else
111			{
112				dsize = total_dsize;
113				total_dsize = 0;
114			}
115
116			data = *total_data++;
117
118			while (dsize > 0) 
119			{
120				if (mLoadSize == MAX_DATA_BITS) 
121				{
122					*(mBuffer + mBufferSize++) = mLoad;
123					if (mBufferSize > mMaxSize)
124					{
125						llerror("mBufferSize exceeding mMaxSize!", 0);
126					}
127					mLoadSize = 0;
128					mLoad = 0x00;
129				}
130				mLoad <<= 1;			
131				mLoad |= (data >> (MAX_DATA_BITS - 1));
132				data <<= 1;
133				mLoadSize++;
134				mTotalBits++;
135				dsize--;
136			}
137		}
138		return mBufferSize;
139	}
140
141	U32 bitUnpack(U8 *total_retval, U32 total_dsize)
142	{
143		U32 dsize;
144		U8	*retval;
145
146		while (total_dsize > 0)
147		{
148			if (total_dsize > MAX_DATA_BITS)
149			{
150				dsize = MAX_DATA_BITS;
151				total_dsize -= MAX_DATA_BITS;
152			}
153			else
154			{
155				dsize = total_dsize;
156				total_dsize = 0;
157			}
158
159			retval = total_retval++;
160			*retval = 0x00;
161			while (dsize > 0) 
162			{
163				if (mLoadSize == 0) 
164				{
165#ifdef _DEBUG
166					if (mBufferSize > mMaxSize)
167					{
168						llerrs << "mBufferSize exceeding mMaxSize" << llendl;
169						llerrs << mBufferSize << " > " << mMaxSize << llendl;
170					}
171#endif
172					mLoad = *(mBuffer + mBufferSize++);
173					mLoadSize = MAX_DATA_BITS;
174				}
175				*retval <<= 1;
176				*retval |= (mLoad >> (MAX_DATA_BITS - 1));
177				mLoadSize--;
178				mLoad <<= 1;
179				dsize--;
180			}
181		}
182		return mBufferSize;
183	}
184
185	U32 flushBitPack()
186	{
187		if (mLoadSize) 
188		{
189			mLoad <<= (MAX_DATA_BITS - mLoadSize);
190			*(mBuffer + mBufferSize++) = mLoad;
191			if (mBufferSize > mMaxSize)
192			{
193				llerror("mBufferSize exceeding mMaxSize!", 0);
194			}
195			mLoadSize = 0;
196		}
197		return mBufferSize;
198	}
199
200	U8		*mBuffer;
201	U32		mBufferSize;
202	U8		mLoad;
203	U32		mLoadSize;
204	U32		mTotalBits;
205	U32		mMaxSize;
206};
207
208#endif