2
0

bitStream.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  23. // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
  24. // Copyright (C) 2015 Faust Logic, Inc.
  25. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  26. #ifndef _BITSTREAM_H_
  27. #define _BITSTREAM_H_
  28. #ifndef _STREAM_H_
  29. #include "core/stream/stream.h"
  30. #endif
  31. #ifndef _MPOINT3_H_
  32. #include "math/mPoint3.h"
  33. #endif
  34. #ifndef _CRC_H_
  35. #include "core/crc.h"
  36. #endif
  37. //-------------------------------------- Some caveats when using this class:
  38. // - Get/setPosition semantics are changed
  39. // to indicate bit position rather than
  40. // byte position.
  41. //
  42. class Point3F;
  43. class MatrixF;
  44. class HuffmanProcessor;
  45. class BitVector;
  46. class QuatF;
  47. class BitStream : public Stream
  48. {
  49. protected:
  50. U8 *mDataPtr;
  51. S32 bitNum;
  52. S32 bufSize;
  53. bool error;
  54. S32 maxReadBitNum;
  55. S32 maxWriteBitNum;
  56. char *stringBuffer;
  57. Point3F mCompressPoint;
  58. friend class HuffmanProcessor;
  59. public:
  60. static BitStream *getPacketStream(U32 writeSize = 0);
  61. static void sendPacketStream(const NetAddress *addr);
  62. void setBuffer(void *bufPtr, S32 bufSize, S32 maxSize = 0);
  63. U8* getBuffer() { return mDataPtr; }
  64. U8* getBytePtr();
  65. U32 getReadByteSize();
  66. U32 getWriteByteSize();
  67. S32 getCurPos() const;
  68. void setCurPos(const U32);
  69. // HACK: We reverted BitStream to this previous version
  70. // because it was crashing the build.
  71. //
  72. // These are just here so that we don't have to revert
  73. // the changes from the rest of the code.
  74. //
  75. // 9/11/2008 - Tom Spilman
  76. //
  77. S32 getBitPosition() const { return getCurPos(); }
  78. void clearStringBuffer();
  79. BitStream(void *bufPtr, S32 bufSize, S32 maxWriteSize = -1) { setBuffer(bufPtr, bufSize,maxWriteSize); stringBuffer = NULL; }
  80. void clear();
  81. void setStringBuffer(char buffer[256]);
  82. void writeInt(S32 value, S32 bitCount);
  83. S32 readInt(S32 bitCount);
  84. /// Use this method to write out values in a concise but ass backwards way...
  85. /// Good for values you expect to be frequently zero, often small. Worst case
  86. /// this will bloat values by nearly 20% (5 extra bits!) Best case you'll get
  87. /// one bit (if it's zero).
  88. ///
  89. /// This is not so much for efficiency's sake, as to make life painful for
  90. /// people that want to reverse engineer our network or file formats.
  91. void writeCussedU32(U32 val)
  92. {
  93. // Is it zero?
  94. if(writeFlag(val == 0))
  95. return;
  96. if(writeFlag(val <= 0xF)) // 4 bit
  97. writeRangedU32(val, 0, 0xF);
  98. else if(writeFlag(val <= 0xFF)) // 8 bit
  99. writeRangedU32(val, 0, 0xFF);
  100. else if(writeFlag(val <= 0xFFFF)) // 16 bit
  101. writeRangedU32(val, 0, 0xFFFF);
  102. else if(writeFlag(val <= 0xFFFFFF)) // 24 bit
  103. writeRangedU32(val, 0, 0xFFFFFF);
  104. else
  105. writeRangedU32(val, 0, 0xFFFFFFFF);
  106. }
  107. U32 readCussedU32()
  108. {
  109. if(readFlag())
  110. return 0;
  111. if(readFlag())
  112. return readRangedU32(0, 0xF);
  113. else if(readFlag())
  114. return readRangedU32(0, 0xFF);
  115. else if(readFlag())
  116. return readRangedU32(0, 0xFFFF);
  117. else if(readFlag())
  118. return readRangedU32(0, 0xFFFFFF);
  119. else
  120. return readRangedU32(0, 0xFFFFFFFF);
  121. }
  122. void writeSignedInt(S32 value, S32 bitCount);
  123. S32 readSignedInt(S32 bitCount);
  124. void writeRangedU32(U32 value, U32 rangeStart, U32 rangeEnd);
  125. U32 readRangedU32(U32 rangeStart, U32 rangeEnd);
  126. /// Writes a clamped signed integer to the stream using
  127. /// an optimal amount of bits for the range.
  128. void writeRangedS32( S32 value, S32 min, S32 max );
  129. /// Reads a ranged signed integer written with writeRangedS32.
  130. S32 readRangedS32( S32 min, S32 max );
  131. // read and write floats... floats are 0 to 1 inclusive, signed floats are -1 to 1 inclusive
  132. F32 readFloat(S32 bitCount);
  133. F32 readSignedFloat(S32 bitCount);
  134. void writeFloat(F32 f, S32 bitCount);
  135. void writeSignedFloat(F32 f, S32 bitCount);
  136. /// Writes a clamped floating point value to the
  137. /// stream with the desired bits of precision.
  138. void writeRangedF32( F32 value, F32 min, F32 max, U32 numBits );
  139. /// Reads a ranged floating point value written with writeRangedF32.
  140. F32 readRangedF32( F32 min, F32 max, U32 numBits );
  141. void writeClassId(U32 classId, U32 classType, U32 classGroup);
  142. S32 readClassId(U32 classType, U32 classGroup); // returns -1 if the class type is out of range
  143. // writes a normalized vector
  144. void writeNormalVector(const Point3F& vec, S32 bitCount);
  145. void readNormalVector(Point3F *vec, S32 bitCount);
  146. void clearCompressionPoint();
  147. void setCompressionPoint(const Point3F& p);
  148. // Matching calls to these compression methods must, of course,
  149. // have matching scale values.
  150. void writeCompressedPoint(const Point3F& p,F32 scale = 0.001f);
  151. void readCompressedPoint(Point3F* p,F32 scale = 0.001f);
  152. // Uses the above method to reduce the precision of a normal vector so the server can
  153. // determine exactly what is on the client. (Pre-dumbing the vector before sending
  154. // to the client can result in precision errors...)
  155. static Point3F dumbDownNormal(const Point3F& vec, S32 bitCount);
  156. /// Writes a compressed vector as separate magnitude and
  157. /// normal components. The final space used depends on the
  158. /// content of the vector.
  159. ///
  160. /// - 1 bit is used to skip over zero length vectors.
  161. /// - 1 bit is used to mark if the magnitude exceeds max.
  162. /// - The magnitude as:
  163. /// a. magBits if less than maxMag.
  164. /// b. a full 32bit value if greater than maxMag.
  165. /// - The normal as a phi and theta sized normalBits+1 and normalBits.
  166. ///
  167. void writeVector( Point3F vec, F32 maxMag, S32 magBits, S32 normalBits );
  168. /// Reads a compressed vector.
  169. /// @see writeVector
  170. void readVector( Point3F *outVec, F32 maxMag, S32 magBits, S32 normalBits );
  171. // writes an affine transform (full precision version)
  172. void writeAffineTransform(const MatrixF&);
  173. void readAffineTransform(MatrixF*);
  174. /// Writes a quaternion in a lossy compressed format that
  175. /// is ( bitCount * 3 ) + 2 bits in size.
  176. ///
  177. /// @param quat The normalized quaternion to write.
  178. /// @param bitCount The the storage space for the packed components of
  179. /// the quaternion.
  180. ///
  181. void writeQuat( const QuatF& quat, U32 bitCount = 9 );
  182. /// Reads a quaternion written with writeQuat.
  183. ///
  184. /// @param quat The quaternion that was read.
  185. /// @param bitCount The the storage space for the packed components of
  186. /// the quaternion. Must match the bitCount at write.
  187. /// @see writeQuat
  188. ///
  189. void readQuat( QuatF *outQuat, U32 bitCount = 9 );
  190. virtual void writeBits(S32 bitCount, const void *bitPtr);
  191. virtual void readBits(S32 bitCount, void *bitPtr);
  192. virtual bool writeFlag(bool val);
  193. inline bool writeFlag(U32 val)
  194. {
  195. return writeFlag(val != 0);
  196. }
  197. inline bool writeFlag(void *val)
  198. {
  199. return writeFlag(val != 0);
  200. }
  201. virtual bool readFlag();
  202. void writeBits(const BitVector &bitvec);
  203. void readBits(BitVector *bitvec);
  204. void setBit(S32 bitCount, bool set);
  205. bool testBit(S32 bitCount);
  206. bool isFull() { return bitNum > (bufSize << 3); }
  207. bool isValid() { return !error; }
  208. bool _read (const U32 size,void* d);
  209. bool _write(const U32 size,const void* d);
  210. void readString(char stringBuf[256]);
  211. void writeString(const char *stringBuf, S32 maxLen=255);
  212. bool hasCapability(const Capability) const { return true; }
  213. U32 getPosition() const;
  214. bool setPosition(const U32 in_newPosition);
  215. U32 getStreamSize();
  216. S32 getMaxWriteBitNum() const { return maxWriteBitNum; }
  217. };
  218. class ResizeBitStream : public BitStream
  219. {
  220. protected:
  221. U32 mMinSpace;
  222. public:
  223. ResizeBitStream(U32 minSpace = 1500, U32 initialSize = 0);
  224. void validate();
  225. ~ResizeBitStream();
  226. };
  227. /// This class acts to provide an "infinitely extending" stream.
  228. ///
  229. /// Basically, it does what ResizeBitStream does, but it validates
  230. /// on every write op, so that you never have to worry about overwriting
  231. /// the buffer.
  232. class InfiniteBitStream : public ResizeBitStream
  233. {
  234. public:
  235. InfiniteBitStream();
  236. ~InfiniteBitStream();
  237. /// Ensure we have space for at least upcomingBytes more bytes in the stream.
  238. void validate(U32 upcomingBytes);
  239. /// Reset the stream to zero length (but don't clean memory).
  240. void reset();
  241. /// Shrink the buffer down to match the actual size of the data.
  242. void compact();
  243. /// Write us out to a stream... Results in last byte getting padded!
  244. void writeToStream(Stream &s);
  245. virtual void writeBits(S32 bitCount, const void *bitPtr)
  246. {
  247. validate((bitCount >> 3) + 1); // Add a little safety.
  248. BitStream::writeBits(bitCount, bitPtr);
  249. }
  250. virtual bool writeFlag(bool val)
  251. {
  252. validate(1); // One bit will at most grow our buffer by a byte.
  253. return BitStream::writeFlag(val);
  254. }
  255. const U32 getCRC()
  256. {
  257. // This could be kinda inefficient - BJG
  258. return CRC::calculateCRC(getBuffer(), getStreamSize());
  259. }
  260. };
  261. //------------------------------------------------------------------------------
  262. //-------------------------------------- INLINES
  263. //
  264. inline S32 BitStream::getCurPos() const
  265. {
  266. return bitNum;
  267. }
  268. inline void BitStream::setCurPos(const U32 in_position)
  269. {
  270. AssertFatal(in_position < (U32)(bufSize << 3), "Out of range bitposition");
  271. bitNum = S32(in_position);
  272. }
  273. inline bool BitStream::readFlag()
  274. {
  275. if(bitNum > maxReadBitNum)
  276. {
  277. error = true;
  278. AssertFatal(false, "Out of range read");
  279. return false;
  280. }
  281. S32 mask = 1 << (bitNum & 0x7);
  282. bool ret = (*(mDataPtr + (bitNum >> 3)) & mask) != 0;
  283. bitNum++;
  284. return ret;
  285. }
  286. inline void BitStream::writeRangedU32(U32 value, U32 rangeStart, U32 rangeEnd)
  287. {
  288. AssertFatal(value >= rangeStart && value <= rangeEnd, "Out of bounds value!");
  289. AssertFatal(rangeEnd >= rangeStart, "error, end of range less than start");
  290. U32 rangeSize = rangeEnd - rangeStart + 1;
  291. U32 rangeBits = getBinLog2(getNextPow2(rangeSize));
  292. writeInt(S32(value - rangeStart), S32(rangeBits));
  293. }
  294. inline U32 BitStream::readRangedU32(U32 rangeStart, U32 rangeEnd)
  295. {
  296. AssertFatal(rangeEnd >= rangeStart, "error, end of range less than start");
  297. U32 rangeSize = rangeEnd - rangeStart + 1;
  298. U32 rangeBits = getBinLog2(getNextPow2(rangeSize));
  299. U32 val = U32(readInt(S32(rangeBits)));
  300. return val + rangeStart;
  301. }
  302. inline void BitStream::writeRangedS32( S32 value, S32 min, S32 max )
  303. {
  304. value = mClamp( value, min, max );
  305. writeRangedU32( ( value - min ), 0, ( max - min ) );
  306. }
  307. inline S32 BitStream::readRangedS32( S32 min, S32 max )
  308. {
  309. return readRangedU32( 0, ( max - min ) ) + min;
  310. }
  311. inline void BitStream::writeRangedF32( F32 value, F32 min, F32 max, U32 numBits )
  312. {
  313. value = ( mClampF( value, min, max ) - min ) / ( max - min );
  314. writeInt( (S32)mFloor(value * F32( (1 << numBits) - 1 )), numBits );
  315. }
  316. inline F32 BitStream::readRangedF32( F32 min, F32 max, U32 numBits )
  317. {
  318. F32 value = (F32)readInt( numBits );
  319. value /= F32( ( 1 << numBits ) - 1 );
  320. return min + value * ( max - min );
  321. }
  322. #endif //_BITSTREAM_H_