PageRenderTime 26ms CodeModel.GetById 9ms RepoModel.GetById 0ms 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
Possible License(s): LGPL-2.1
  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. #ifndef LL_BITPACK_H
  27. #define LL_BITPACK_H
  28. #include "llerror.h"
  29. const U32 MAX_DATA_BITS = 8;
  30. class LLBitPack
  31. {
  32. public:
  33. LLBitPack(U8 *buffer, U32 max_size) : mBuffer(buffer), mBufferSize(0), mLoad(0), mLoadSize(0), mTotalBits(0), mMaxSize(max_size)
  34. {
  35. }
  36. ~LLBitPack()
  37. {
  38. }
  39. void resetBitPacking()
  40. {
  41. mLoad = 0;
  42. mLoadSize = 0;
  43. mTotalBits = 0;
  44. mBufferSize = 0;
  45. }
  46. U32 bitPack(U8 *total_data, U32 total_dsize)
  47. {
  48. U32 dsize;
  49. U8 data;
  50. while (total_dsize > 0)
  51. {
  52. if (total_dsize > MAX_DATA_BITS)
  53. {
  54. dsize = MAX_DATA_BITS;
  55. total_dsize -= MAX_DATA_BITS;
  56. }
  57. else
  58. {
  59. dsize = total_dsize;
  60. total_dsize = 0;
  61. }
  62. data = *total_data++;
  63. data <<= (MAX_DATA_BITS - dsize);
  64. while (dsize > 0)
  65. {
  66. if (mLoadSize == MAX_DATA_BITS)
  67. {
  68. *(mBuffer + mBufferSize++) = mLoad;
  69. if (mBufferSize > mMaxSize)
  70. {
  71. llerror("mBufferSize exceeding mMaxSize!", 0);
  72. }
  73. mLoadSize = 0;
  74. mLoad = 0x00;
  75. }
  76. mLoad <<= 1;
  77. mLoad |= (data >> (MAX_DATA_BITS - 1));
  78. data <<= 1;
  79. mLoadSize++;
  80. mTotalBits++;
  81. dsize--;
  82. }
  83. }
  84. return mBufferSize;
  85. }
  86. U32 bitCopy(U8 *total_data, U32 total_dsize)
  87. {
  88. U32 dsize;
  89. U8 data;
  90. while (total_dsize > 0)
  91. {
  92. if (total_dsize > MAX_DATA_BITS)
  93. {
  94. dsize = MAX_DATA_BITS;
  95. total_dsize -= MAX_DATA_BITS;
  96. }
  97. else
  98. {
  99. dsize = total_dsize;
  100. total_dsize = 0;
  101. }
  102. data = *total_data++;
  103. while (dsize > 0)
  104. {
  105. if (mLoadSize == MAX_DATA_BITS)
  106. {
  107. *(mBuffer + mBufferSize++) = mLoad;
  108. if (mBufferSize > mMaxSize)
  109. {
  110. llerror("mBufferSize exceeding mMaxSize!", 0);
  111. }
  112. mLoadSize = 0;
  113. mLoad = 0x00;
  114. }
  115. mLoad <<= 1;
  116. mLoad |= (data >> (MAX_DATA_BITS - 1));
  117. data <<= 1;
  118. mLoadSize++;
  119. mTotalBits++;
  120. dsize--;
  121. }
  122. }
  123. return mBufferSize;
  124. }
  125. U32 bitUnpack(U8 *total_retval, U32 total_dsize)
  126. {
  127. U32 dsize;
  128. U8 *retval;
  129. while (total_dsize > 0)
  130. {
  131. if (total_dsize > MAX_DATA_BITS)
  132. {
  133. dsize = MAX_DATA_BITS;
  134. total_dsize -= MAX_DATA_BITS;
  135. }
  136. else
  137. {
  138. dsize = total_dsize;
  139. total_dsize = 0;
  140. }
  141. retval = total_retval++;
  142. *retval = 0x00;
  143. while (dsize > 0)
  144. {
  145. if (mLoadSize == 0)
  146. {
  147. #ifdef _DEBUG
  148. if (mBufferSize > mMaxSize)
  149. {
  150. llerrs << "mBufferSize exceeding mMaxSize" << llendl;
  151. llerrs << mBufferSize << " > " << mMaxSize << llendl;
  152. }
  153. #endif
  154. mLoad = *(mBuffer + mBufferSize++);
  155. mLoadSize = MAX_DATA_BITS;
  156. }
  157. *retval <<= 1;
  158. *retval |= (mLoad >> (MAX_DATA_BITS - 1));
  159. mLoadSize--;
  160. mLoad <<= 1;
  161. dsize--;
  162. }
  163. }
  164. return mBufferSize;
  165. }
  166. U32 flushBitPack()
  167. {
  168. if (mLoadSize)
  169. {
  170. mLoad <<= (MAX_DATA_BITS - mLoadSize);
  171. *(mBuffer + mBufferSize++) = mLoad;
  172. if (mBufferSize > mMaxSize)
  173. {
  174. llerror("mBufferSize exceeding mMaxSize!", 0);
  175. }
  176. mLoadSize = 0;
  177. }
  178. return mBufferSize;
  179. }
  180. U8 *mBuffer;
  181. U32 mBufferSize;
  182. U8 mLoad;
  183. U32 mLoadSize;
  184. U32 mTotalBits;
  185. U32 mMaxSize;
  186. };
  187. #endif