1 | |
2 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
3 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
4 | #pragma once |
5 | |
6 | #include "Prerequisites/BsPrerequisitesUtil.h" |
7 | #include "Math/BsMath.h" |
8 | #include "Math/BsQuaternion.h" |
9 | #include "Math/BsVector3.h" |
10 | #include "Utility/BsBitwise.h" |
11 | |
12 | namespace bs |
13 | { |
14 | /** @addtogroup General |
15 | * @{ |
16 | */ |
17 | |
18 | /** |
19 | * Allows encoding/decoding of types into a stream of bits. Supports various methods of storing data in a compact form. |
20 | * The bitstream can manage its internal memory or a user can provide an external source of data. If using internal |
21 | * memory the bitstream will automatically grow the memory storage as needed. |
22 | * |
23 | * The stream keeps an internal cursor that represents the bit at which to perform read & write operations. |
24 | * Read & write operations will operate at the current cursor location and the cursor will be advanced by the number of |
25 | * bits read or written. If writing outside of range the internal memory buffer will be automatically expanded, except |
26 | * when external memory buffer is used, in which case it is undefined behaviour. Reading outside of range is always |
27 | * undefined behaviour. |
28 | */ |
29 | class Bitstream |
30 | { |
31 | using QuantType = uint8_t; |
32 | public: |
33 | /** |
34 | * Initializes an empty bitstream. As data is written the stream will grow its internal memory storage |
35 | * automatically. |
36 | */ |
37 | Bitstream() = default; |
38 | |
39 | /** |
40 | * Initializes a bitstream with some initial capacity. If more bytes than capacity is written, the bitstream will |
41 | * grow its internal memory storage. |
42 | * |
43 | * @param[in] capacity Number of bytes to initially allocate for the internal memory storage. |
44 | */ |
45 | Bitstream(uint32_t capacity); |
46 | |
47 | /** |
48 | * Initializes a bitstream with external data storage. The bitstream will not manage internal memory and will not |
49 | * grow memory storage if capacity is exceeded. The user is responsible for keeping track and not writing outside |
50 | * of buffer range. |
51 | * |
52 | * @param[in] data Address of the external memory buffer. The user is responsible of keeping this memory alive |
53 | * for the lifetime of the bitstream, as well as releasing it. Must have enough capacity to |
54 | * store @p count bits. |
55 | * @param[in] count Size of the provided data, in bits. |
56 | */ |
57 | Bitstream(QuantType* data, uint32_t count); |
58 | |
59 | ~Bitstream(); |
60 | |
61 | /** |
62 | * Writes bits from the provided buffer into the stream at the current cursor location and advances the cursor. |
63 | * |
64 | * @param[in] data Buffer to write the data from. Must have enough capacity to store @p count bits. |
65 | * @param[in] count Number of bits to write. |
66 | */ |
67 | void writeBits(const QuantType* data, uint32_t count); |
68 | |
69 | /** |
70 | * Reads bits from the stream into the provided buffer from the current cursor location and advances the cursor. |
71 | * |
72 | * @param[out] data Buffer to read the data from. Must have enough capacity to store @p count bits. |
73 | * @param[in] count Number of bits to read. |
74 | */ |
75 | void readBits(QuantType* data, uint32_t count); |
76 | |
77 | /** |
78 | * Writes the provided data into the stream at the current cursor location and advances the cursor. |
79 | * |
80 | * @param[in] value Data to write. |
81 | */ |
82 | template<class T> |
83 | void write(const T& value); |
84 | |
85 | /** |
86 | * Reads bits from the stream and writes them into the provided object. Data is read from the current cursor |
87 | * location and advances the cursor. |
88 | * |
89 | * @param[out] value Object to initialize with the read bits. |
90 | */ |
91 | template<class T> |
92 | void read(T& value); |
93 | |
94 | /** @copydoc write(const T&) */ |
95 | void write(const bool& value); |
96 | |
97 | /** @copydoc read(T&) */ |
98 | void read(bool& value); |
99 | |
100 | /** @copydoc write(const T&) */ |
101 | void write(const String& value); |
102 | |
103 | /** @copydoc read(T&) */ |
104 | void read(String& value); |
105 | |
106 | /** |
107 | * Checks if the provided value differs from the last provided value, and if they are equivalent writes just a |
108 | * single bit signifying no change. Otherwise the value is encoded as if calling write(). |
109 | */ |
110 | template<class T> |
111 | void writeDelta(const T& value, const T& lastValue); |
112 | |
113 | /** Reads the data written by writeDelta() from the current cursor location and advances the cursor. */ |
114 | template<class T> |
115 | void readDelta(T& value, const T& lastValue); |
116 | |
117 | /** @copydoc writeDelta(const T&, const T&) */ |
118 | void writeDelta(bool value, bool lastValue); |
119 | |
120 | /** @copydoc readDelta(T&, const T&) */ |
121 | void readDelta(bool& value, bool lastValue); |
122 | |
123 | /** |
124 | * Encodes a 32-bit integer value as a base-128 varint and writes it to the stream. Write is performed at the |
125 | * current cursor location and advances the cursor. Varints are a method of serializing integers using one or |
126 | * more bytes, where smaller values use less bytes. |
127 | */ |
128 | void writeVarInt(uint32_t value); |
129 | |
130 | /** |
131 | * Encodes a 32-bit integer value as a base-128 varint and writes it to the stream. Write is performed at the |
132 | * current cursor location and advances the cursor. Varints are a method of serializing integers using one or |
133 | * more bytes, where smaller values use less bytes. |
134 | */ |
135 | void writeVarInt(int32_t value); |
136 | |
137 | /** |
138 | * Encodes a 64-bit integer value as a base-128 varint and writes it to the stream. Write is performed at the |
139 | * current cursor location and advances the cursor. Varints are a method of serializing integers using one or |
140 | * more bytes, where smaller values use less bytes. |
141 | */ |
142 | void writeVarInt(uint64_t value); |
143 | |
144 | /** |
145 | * Encodes a 64-bit integer value as a base-128 varint and writes it to the stream. Write is performed at the |
146 | * current cursor location and advances the cursor. Varints are a method of serializing integers using one or |
147 | * more bytes, where smaller values use less bytes. |
148 | */ |
149 | void writeVarInt(int64_t value); |
150 | |
151 | /** |
152 | * Decodes a 32-bit integer value encoded as a base-128 varint from the stream. Read is performed at the |
153 | * current cursor location and advances the cursor. Varints are a method of serializing integers using one or |
154 | * more bytes, where smaller values use less bytes. |
155 | */ |
156 | void readVarInt(uint32_t& value); |
157 | |
158 | /** |
159 | * Decodes a 32-bit integer value encoded as a base-128 varint from the stream. Read is performed at the |
160 | * current cursor location and advances the cursor. Varints are a method of serializing integers using one or |
161 | * more bytes, where smaller values use less bytes. |
162 | */ |
163 | void readVarInt(int32_t& value); |
164 | |
165 | /** |
166 | * Decodes a 32-bit integer value encoded as a base-128 varint from the stream. Read is performed at the |
167 | * current cursor location and advances the cursor. Varints are a method of serializing integers using one or |
168 | * more bytes, where smaller values use less bytes. |
169 | */ |
170 | void readVarInt(uint64_t& value); |
171 | |
172 | /** |
173 | * Decodes a 32-bit integer value encoded as a base-128 varint from the stream. Read is performed at the |
174 | * current cursor location and advances the cursor. Varints are a method of serializing integers using one or |
175 | * more bytes, where smaller values use less bytes. |
176 | */ |
177 | void readVarInt(int64_t& value); |
178 | |
179 | /** |
180 | * Checks if the provided value differs from the last provided value, and if they are equivalent writes just a |
181 | * single bit signifying no change. Otherwise the value is encoded as if calling writeVarInt(). |
182 | */ |
183 | template<class T> |
184 | void writeVarIntDelta(const T& value, const T& lastValue); |
185 | |
186 | /** Reads the data written by writeVarIntDelta() from the current cursor location and advances the cursor. */ |
187 | template<class T> |
188 | void readVarIntDelta(T& value, const T& lastValue); |
189 | |
190 | /** |
191 | * Encodes a float in range [0, 1] into a fixed point representation using a specific number of bits, and writes it |
192 | * to the stream. Write is performed at the current cursor location and advances the cursor. |
193 | */ |
194 | void writeNorm(float value, uint32_t bits = 16); |
195 | |
196 | /** |
197 | * Decodes a float encoded using writeNorm(float, uint32_t). Read is performed at the current cursor location and |
198 | * advances the cursor. Same number of bits need to be used as when the float was encoded. |
199 | */ |
200 | void readNorm(float& value, uint32_t bits = 16); |
201 | |
202 | /** |
203 | * Encodes a 3D vector with individual components in range [-1, 1] into a fixed point representation where each |
204 | * component uses a specific number of bits, and writes it to the stream. Write is performed at the current cursor |
205 | * location and advances the cursor. |
206 | */ |
207 | void writeNorm(const Vector3& value, uint32_t bits = 16); |
208 | |
209 | /** |
210 | * Decodes a 3D vector encoded using writeNorm(Vector3, uint32_t). Read is performed at the current cursor location |
211 | * and advances the cursor. Same number of bits need to be used as when the float was encoded. |
212 | */ |
213 | void readNorm(Vector3& value, uint32_t bits = 16); |
214 | |
215 | /** |
216 | * Encodes a quaternion with individual components in range [-1, 1] into a fixed point representation where each |
217 | * component uses a specific number of bits, and writes it to the stream. Write is performed at the current cursor |
218 | * location and advances the cursor. |
219 | */ |
220 | void writeNorm(const Quaternion& value, uint32_t bits = 16); |
221 | |
222 | /** |
223 | * Decodes a quaternion encoded using writeNorm(Quaternion, uint32_t). Read is performed at the current cursor |
224 | * location and advances the cursor. Same number of bits need to be used as when the float was encoded. |
225 | */ |
226 | void readNorm(Quaternion& value, uint32_t bits = 16); |
227 | |
228 | /** |
229 | * Checks if the provided value differs from the last provided value, and if they are equivalent writes just a |
230 | * single bit signifying no change. Otherwise the value is encoded as if calling writeNorm(). |
231 | */ |
232 | template<class T> |
233 | void writeNormDelta(const T& value, const T& lastValue, uint32_t bits = 16); |
234 | |
235 | /** Reads the data written by writeNormDelta() from the current cursor location and advances the cursor. */ |
236 | template<class T> |
237 | void readNormDelta(T& value, const T& lastValue, uint32_t bits = 16); |
238 | |
239 | /** |
240 | * Encodes an integer in a specific range, using the range the reduce the number of bits required, and writes it |
241 | * to the stream. Write is performed at the current cursor location and advances the cursor. |
242 | */ |
243 | template<class T> |
244 | void writeRange(const T& value, const T& min, const T& max); |
245 | |
246 | /** |
247 | * Decodes an integer encoded using writeRange(const T&, const T&, const T&). Read is performed at the current |
248 | * cursor location and advances the cursor. Same needs to be used as when the value was encoded. |
249 | */ |
250 | template<class T> |
251 | void readRange(T& value, const T& min, const T& max); |
252 | |
253 | /** |
254 | * Checks if the provided value differs from the last provided value, and if they are equivalent writes just a |
255 | * single bit signifying no change. Otherwise the value is encoded as if calling |
256 | * writeRange(const T&, const T&, const T&). |
257 | */ |
258 | template<class T> |
259 | void writeRangeDelta(const T& value, const T& lastValue, const T& min, const T& max); |
260 | |
261 | /** |
262 | * Reads the data written by writeRangeDelta(const T&, const T&, const T&, const T&) from the current cursor |
263 | * location and advances the cursor. |
264 | */ |
265 | template<class T> |
266 | void readRangeDelta(T& value, const T& lastValue, const T& min, const T& max); |
267 | |
268 | /** |
269 | * Encodes a float in a specific range into a fixed point representation using a specific number of bits, and |
270 | * writes it to the stream. Write is performed at the current cursor location and advances the cursor. |
271 | */ |
272 | void writeRange(float value, float min, float max, uint32_t bits = 16); |
273 | |
274 | /** |
275 | * Decodes a float encoded using writeRange(float, float, float, uint32_t). Read is performed at the current cursor |
276 | * location and advances the cursor. Same number of bits, and the same range needs to be used as when the float was |
277 | * encoded. |
278 | */ |
279 | void readRange(float& value, float min, float max, uint32_t bits = 16); |
280 | |
281 | /** |
282 | * Checks if the provided value differs from the last provided value, and if they are equivalent writes just a |
283 | * single bit signifying no change. Otherwise the value is encoded as if calling |
284 | * writeRange(float, float, float, uint32_t). |
285 | */ |
286 | void writeRangeDelta(float value, float lastValue, float min, float max, uint32_t bits = 16); |
287 | |
288 | /** |
289 | * Reads the data written by writeRangeDelta(float, float, float, float, uint32_t) from the current cursor |
290 | * location and advances the cursor. |
291 | */ |
292 | void readRangeDelta(float& value, float lastValue, float min, float max, uint32_t bits = 16); |
293 | |
294 | /** |
295 | * Skip a defined number of bits, moving the read/write cursor by this amount. This can also be a negative value, |
296 | * in which case the file pointer rewinds a defined number of bits. Note the cursor can never skip past the |
297 | * capacity of the buffer, and will be clamped. |
298 | */ |
299 | void skip(int32_t count); |
300 | |
301 | /** |
302 | * Repositions the read/write cursor to the specified bit. Note the cursor can never skip past the capacity |
303 | * of the buffer, and will be clamped. |
304 | */ |
305 | void seek(uint32_t pos); |
306 | |
307 | /** |
308 | * Aligns the read/write cursor to a byte boundary. @p count determines the alignment in bytes. Note the |
309 | * requested alignment might not be achieved if count > 1 and it would move the cursor past the capacity of the |
310 | * buffer, as the cursor will be clamped to buffer end regardless of alignment. |
311 | */ |
312 | void align(uint32_t count = 1); |
313 | |
314 | /** Returns the current read/write cursor position, in bits. */ |
315 | uint32_t tell() const { return mCursor; } |
316 | |
317 | /** Returns true if the stream has reached the end. */ |
318 | bool eof() const { return mCursor >= mNumBits; } |
319 | |
320 | /** Returns the total number of bits available in the stream. */ |
321 | uint32_t size() const { return mNumBits; } |
322 | |
323 | /** Returns the total number of bits the stream can store without needing to allocate more memory. */ |
324 | uint32_t capacity() const { return mMaxBits; } |
325 | |
326 | /** Returns the internal data buffer. */ |
327 | QuantType* data() const { return mData; } |
328 | |
329 | private: |
330 | static constexpr uint32_t BYTES_PER_QUANT = sizeof(QuantType); |
331 | static constexpr uint32_t BITS_PER_QUANT = BYTES_PER_QUANT * 8; |
332 | static constexpr uint32_t BITS_PER_QUANT_LOG2 = Bitwise::bitsLog2(BITS_PER_QUANT); |
333 | |
334 | /** Checks if the internal memory buffer needs to grow in order to accomodate @p numBits bits. */ |
335 | void reallocIfNeeded(uint32_t numBits); |
336 | |
337 | /** Reallocates the internal buffer making enough room for @p numBits (rounded to a multiple of BYTES_PER_QUANT. */ |
338 | void realloc(uint32_t numBits); |
339 | |
340 | QuantType* mData = nullptr; |
341 | uint32_t mMaxBits = 0; |
342 | uint32_t mNumBits = 0; |
343 | bool mOwnsMemory = true; |
344 | |
345 | uint32_t mCursor = 0; |
346 | }; |
347 | |
348 | /** @} */ |
349 | |
350 | /** @addtogroup Implementation |
351 | * @{ |
352 | */ |
353 | |
354 | inline Bitstream::Bitstream(uint32_t capacity) |
355 | { |
356 | realloc(capacity * 8); |
357 | } |
358 | |
359 | inline Bitstream::Bitstream(QuantType* data, uint32_t count) |
360 | : mData(data), mMaxBits(count), mNumBits(count), mOwnsMemory(false) { } |
361 | |
362 | inline Bitstream::~Bitstream() |
363 | { |
364 | if (mData && mOwnsMemory) |
365 | bs_free(mData); |
366 | } |
367 | |
368 | inline void Bitstream::writeBits(const QuantType* data, uint32_t count) |
369 | { |
370 | if (count == 0) |
371 | return; |
372 | |
373 | uint32_t newCursor = mCursor + count; |
374 | reallocIfNeeded(newCursor); |
375 | |
376 | uint32_t destBitsMod = mCursor & (BITS_PER_QUANT - 1); |
377 | uint32_t destQuant = mCursor >> BITS_PER_QUANT_LOG2; |
378 | uint32_t destMask = (1 << destBitsMod) - 1; |
379 | |
380 | // If destination is aligned, memcpy everything except the last quant (unless it is also aligned) |
381 | if (destBitsMod == 0) |
382 | { |
383 | uint32_t numQuants = count >> BITS_PER_QUANT_LOG2; |
384 | memcpy(&mData[destQuant], data, numQuants * BYTES_PER_QUANT); |
385 | |
386 | data += numQuants; |
387 | count -= numQuants * BITS_PER_QUANT; |
388 | destQuant += numQuants; |
389 | } |
390 | |
391 | // Write remaining bits (or all bits if destination wasn't aligned) |
392 | while (count > 0) |
393 | { |
394 | QuantType quant = *data; |
395 | data++; |
396 | |
397 | mData[destQuant] = (quant << destBitsMod) | (mData[destQuant] & destMask); |
398 | |
399 | uint32_t writtenBits = BITS_PER_QUANT - destBitsMod; |
400 | if (count > writtenBits) |
401 | mData[destQuant + 1] = (quant >> writtenBits) | (mData[destQuant + 1] & ~destMask); |
402 | |
403 | destQuant++; |
404 | count -= std::min(BITS_PER_QUANT, count); |
405 | } |
406 | |
407 | mCursor = newCursor; |
408 | mNumBits = std::max(mNumBits, newCursor); |
409 | } |
410 | |
411 | inline void Bitstream::readBits(QuantType* data, uint32_t count) |
412 | { |
413 | if (count == 0) |
414 | return; |
415 | |
416 | assert((mCursor + count) <= mNumBits); |
417 | |
418 | uint32_t newCursor = mCursor + count; |
419 | uint32_t srcBitsMod = mCursor & (BITS_PER_QUANT - 1); |
420 | uint32_t srcQuant = mCursor >> BITS_PER_QUANT_LOG2; |
421 | |
422 | // If source is aligned, memcpy everything except the last quant (unless it is also aligned) |
423 | if (srcBitsMod == 0) |
424 | { |
425 | uint32_t numQuants = count >> BITS_PER_QUANT_LOG2; |
426 | memcpy(data, &mData[srcQuant], numQuants * BYTES_PER_QUANT); |
427 | |
428 | data += numQuants; |
429 | count -= numQuants * BITS_PER_QUANT; |
430 | srcQuant += numQuants; |
431 | } |
432 | |
433 | // Read remaining bits (or all bits if source wasn't aligned) |
434 | while (count > 0) |
435 | { |
436 | QuantType& quant = *data; |
437 | data++; |
438 | |
439 | quant = 0; |
440 | quant |= mData[srcQuant] >> srcBitsMod; |
441 | |
442 | uint32_t readBits = BITS_PER_QUANT - srcBitsMod; |
443 | if (count > readBits) |
444 | quant |= mData[srcQuant + 1] << readBits; |
445 | |
446 | srcQuant++; |
447 | count -= std::min(BITS_PER_QUANT, count); |
448 | } |
449 | |
450 | mCursor = newCursor; |
451 | } |
452 | |
453 | template <class T> |
454 | void Bitstream::write(const T& value) |
455 | { |
456 | writeBits((QuantType*)&value, sizeof(value) * 8); |
457 | } |
458 | |
459 | template <class T> |
460 | void Bitstream::read(T& value) |
461 | { |
462 | QuantType* temp = (QuantType*)&value; |
463 | readBits(temp, sizeof(value) * 8); |
464 | } |
465 | |
466 | inline void Bitstream::write(const bool& value) |
467 | { |
468 | reallocIfNeeded(mCursor + 1); |
469 | |
470 | uint32_t destBitsMod = mCursor & (BITS_PER_QUANT - 1); |
471 | uint32_t destQuant = mCursor >> BITS_PER_QUANT_LOG2; |
472 | |
473 | if (value) |
474 | mData[destQuant] |= 1U << destBitsMod; |
475 | else |
476 | mData[destQuant] &= ~(1U << destBitsMod); |
477 | |
478 | mCursor++; |
479 | mNumBits = std::max(mNumBits, mCursor); |
480 | } |
481 | |
482 | inline void Bitstream::read(bool& value) |
483 | { |
484 | assert((mCursor + 1) <= mNumBits); |
485 | |
486 | uint32_t srcBitsMod = mCursor & (BITS_PER_QUANT - 1); |
487 | uint32_t srcQuant = mCursor >> BITS_PER_QUANT_LOG2; |
488 | |
489 | value = (mData[srcQuant] >> srcBitsMod) & 0x1; |
490 | mCursor++; |
491 | } |
492 | |
493 | inline void Bitstream::write(const String& value) |
494 | { |
495 | uint32_t length = (uint32_t)value.size(); |
496 | writeVarInt(length); |
497 | writeBits((QuantType*)value.data(), length * 8); |
498 | } |
499 | |
500 | inline void Bitstream::read(String& value) |
501 | { |
502 | uint32_t length; |
503 | readVarInt(length); |
504 | |
505 | value.resize(length); |
506 | |
507 | QuantType* temp = (QuantType*)value.data(); |
508 | readBits(temp, length * 8); |
509 | } |
510 | |
511 | template <class T> |
512 | void Bitstream::writeDelta(const T& value, const T& lastValue) |
513 | { |
514 | if(value == lastValue) |
515 | write(true); |
516 | else |
517 | { |
518 | write(false); |
519 | write(value); |
520 | } |
521 | } |
522 | |
523 | template <class T> |
524 | void Bitstream::readDelta(T& value, const T& lastValue) |
525 | { |
526 | bool clean; |
527 | read(clean); |
528 | |
529 | if(clean) |
530 | value = lastValue; |
531 | else |
532 | read(value); |
533 | } |
534 | |
535 | inline void Bitstream::writeDelta(bool value, bool lastValue) |
536 | { |
537 | write(value); |
538 | } |
539 | |
540 | inline void Bitstream::readDelta(bool& value, bool lastValue) |
541 | { |
542 | read(value); |
543 | } |
544 | |
545 | inline void Bitstream::writeVarInt(uint32_t value) |
546 | { |
547 | uint8_t output[5]; |
548 | uint32_t count = Bitwise::encodeVarInt(value, output); |
549 | |
550 | writeBits(output, count * 8); |
551 | } |
552 | |
553 | inline void Bitstream::writeVarInt(int32_t value) |
554 | { |
555 | uint8_t output[5]; |
556 | uint32_t count = Bitwise::encodeVarInt(value, output); |
557 | |
558 | writeBits(output, count * 8); |
559 | } |
560 | |
561 | inline void Bitstream::writeVarInt(uint64_t value) |
562 | { |
563 | uint8_t output[10]; |
564 | uint32_t count = Bitwise::encodeVarInt(value, output); |
565 | |
566 | writeBits(output, count * 8); |
567 | } |
568 | |
569 | inline void Bitstream::writeVarInt(int64_t value) |
570 | { |
571 | uint8_t output[10]; |
572 | uint32_t count = Bitwise::encodeVarInt(value, output); |
573 | |
574 | writeBits(output, count * 8); |
575 | } |
576 | |
577 | inline void Bitstream::readVarInt(uint32_t& value) |
578 | { |
579 | uint8_t output[5]; |
580 | for(uint32_t i = 0; i < 5; i++) |
581 | { |
582 | readBits(&output[i], 8); |
583 | if((output[i] & 0x80) == 0) |
584 | break; |
585 | } |
586 | |
587 | Bitwise::decodeVarInt(value, output, 5); |
588 | } |
589 | |
590 | inline void Bitstream::readVarInt(int32_t& value) |
591 | { |
592 | uint8_t output[5]; |
593 | for(uint32_t i = 0; i < 5; i++) |
594 | { |
595 | readBits(&output[i], 8); |
596 | if((output[i] & 0x80) == 0) |
597 | break; |
598 | } |
599 | |
600 | Bitwise::decodeVarInt(value, output, 5); |
601 | } |
602 | |
603 | inline void Bitstream::readVarInt(uint64_t& value) |
604 | { |
605 | uint8_t output[10]; |
606 | for(uint32_t i = 0; i < 10; i++) |
607 | { |
608 | readBits(&output[i], 8); |
609 | if((output[i] & 0x80) == 0) |
610 | break; |
611 | } |
612 | |
613 | Bitwise::decodeVarInt(value, output, 10); |
614 | } |
615 | |
616 | inline void Bitstream::readVarInt(int64_t& value) |
617 | { |
618 | uint8_t output[10]; |
619 | for(uint32_t i = 0; i < 10; i++) |
620 | { |
621 | readBits(&output[i], 8); |
622 | if((output[i] & 0x80) == 0) |
623 | break; |
624 | } |
625 | |
626 | Bitwise::decodeVarInt(value, output, 10); |
627 | } |
628 | |
629 | template <class T> |
630 | void Bitstream::writeVarIntDelta(const T& value, const T& lastValue) |
631 | { |
632 | if(value == lastValue) |
633 | write(true); |
634 | else |
635 | { |
636 | write(false); |
637 | writeVarInt(value); |
638 | } |
639 | } |
640 | |
641 | template <class T> |
642 | void Bitstream::readVarIntDelta(T& value, const T& lastValue) |
643 | { |
644 | bool clean; |
645 | read(clean); |
646 | |
647 | if(clean) |
648 | value = lastValue; |
649 | else |
650 | readVarInt(value); |
651 | } |
652 | |
653 | inline void Bitstream::writeNorm(float value, uint32_t bits) |
654 | { |
655 | uint32_t encodedVal = Bitwise::unormToUint(value, bits); |
656 | writeBits((QuantType*)&encodedVal, bits); |
657 | } |
658 | |
659 | inline void Bitstream::readNorm(float& value, uint32_t bits) |
660 | { |
661 | uint32_t encodedVal = 0; |
662 | readBits((QuantType*)&encodedVal, bits); |
663 | value = Bitwise::uintToUnorm(encodedVal, bits); |
664 | } |
665 | |
666 | inline void Bitstream::writeNorm(const Vector3& value, uint32_t bits) |
667 | { |
668 | writeRange(value.x, -1.0f, 1.0f, bits); |
669 | writeRange(value.y, -1.0f, 1.0f, bits); |
670 | writeRange(value.z, -1.0f, 1.0f, bits); |
671 | } |
672 | |
673 | inline void Bitstream::readNorm(Vector3& value, uint32_t bits) |
674 | { |
675 | readRange(value.x, -1.0f, 1.0f, bits); |
676 | readRange(value.y, -1.0f, 1.0f, bits); |
677 | readRange(value.z, -1.0f, 1.0f, bits); |
678 | } |
679 | |
680 | inline void Bitstream::writeNorm(const Quaternion& value, uint32_t bits) |
681 | { |
682 | writeRange(value.x, -1.0f, 1.0f, bits); |
683 | writeRange(value.y, -1.0f, 1.0f, bits); |
684 | writeRange(value.z, -1.0f, 1.0f, bits); |
685 | writeRange(value.w, -1.0f, 1.0f, bits); |
686 | } |
687 | |
688 | inline void Bitstream::readNorm(Quaternion& value, uint32_t bits) |
689 | { |
690 | readRange(value.x, -1.0f, 1.0f, bits); |
691 | readRange(value.y, -1.0f, 1.0f, bits); |
692 | readRange(value.z, -1.0f, 1.0f, bits); |
693 | readRange(value.w, -1.0f, 1.0f, bits); |
694 | } |
695 | |
696 | template <class T> |
697 | void Bitstream::writeNormDelta(const T& value, const T& lastValue, uint32_t bits) |
698 | { |
699 | if(value == lastValue) |
700 | write(true); |
701 | else |
702 | { |
703 | write(false); |
704 | writeNorm(value, bits); |
705 | } |
706 | } |
707 | |
708 | template <class T> |
709 | void Bitstream::readNormDelta(T& value, const T& lastValue, uint32_t bits) |
710 | { |
711 | bool clean; |
712 | read(clean); |
713 | |
714 | if(clean) |
715 | value = lastValue; |
716 | else |
717 | readNorm(value, bits); |
718 | } |
719 | |
720 | |
721 | template <class T> |
722 | void Bitstream::writeRange(const T& value, const T& min, const T& max) |
723 | { |
724 | T range = max - min; |
725 | uint32_t bits = Bitwise::mostSignificantBit(range) + 1; |
726 | |
727 | T rangeVal = value - min; |
728 | writeBits((QuantType*)&rangeVal, bits); |
729 | } |
730 | |
731 | template <class T> |
732 | void Bitstream::readRange(T& value, const T& min, const T& max) |
733 | { |
734 | T range = max - min; |
735 | uint32_t bits = Bitwise::mostSignificantBit(range) + 1; |
736 | |
737 | value = 0; |
738 | readBits((QuantType*)&value, bits); |
739 | value += min; |
740 | } |
741 | |
742 | template <class T> |
743 | void Bitstream::writeRangeDelta(const T& value, const T& lastValue, const T& min, const T& max) |
744 | { |
745 | if(value == lastValue) |
746 | write(true); |
747 | else |
748 | { |
749 | write(false); |
750 | writeRange(value, min, max); |
751 | } |
752 | } |
753 | |
754 | template <class T> |
755 | void Bitstream::readRangeDelta(T& value, const T& lastValue, const T& min, const T& max) |
756 | { |
757 | bool clean; |
758 | read(clean); |
759 | |
760 | if(clean) |
761 | value = lastValue; |
762 | else |
763 | readRange(value, min, max); |
764 | } |
765 | |
766 | inline void Bitstream::writeRange(float value, float min, float max, uint32_t bits) |
767 | { |
768 | float pct = Math::clamp01((value - min)/(max - min)); |
769 | writeNorm(pct, bits); |
770 | } |
771 | |
772 | inline void Bitstream::readRange(float& value, float min, float max, uint32_t bits) |
773 | { |
774 | float pct; |
775 | readNorm(pct, bits); |
776 | |
777 | value = min + (max - min) * pct; |
778 | } |
779 | |
780 | inline void Bitstream::writeRangeDelta(float value, float lastValue, float min, float max, uint32_t bits) |
781 | { |
782 | if(value == lastValue) |
783 | write(true); |
784 | else |
785 | { |
786 | write(false); |
787 | writeRange(value, min, max, bits); |
788 | } |
789 | } |
790 | |
791 | inline void Bitstream::readRangeDelta(float& value, float lastValue, float min, float max, uint32_t bits) |
792 | { |
793 | bool clean; |
794 | read(clean); |
795 | |
796 | if(clean) |
797 | value = lastValue; |
798 | else |
799 | readRange(value, min, max, bits); |
800 | } |
801 | |
802 | inline void Bitstream::skip(int32_t count) |
803 | { |
804 | mCursor = (uint32_t)Math::clamp((int32_t)mCursor + count, 0, (int32_t)mMaxBits); |
805 | } |
806 | |
807 | inline void Bitstream::seek(uint32_t pos) |
808 | { |
809 | mCursor = std::min(pos, mMaxBits); |
810 | } |
811 | |
812 | inline void Bitstream::align(uint32_t count) |
813 | { |
814 | if (count == 0) |
815 | return; |
816 | |
817 | uint32_t bits = count * 8; |
818 | skip(bits - (((mCursor - 1) & (bits - 1)) + 1)); |
819 | } |
820 | |
821 | inline void Bitstream::reallocIfNeeded(uint32_t numBits) |
822 | { |
823 | if (numBits > mMaxBits) |
824 | { |
825 | if (mOwnsMemory) |
826 | { |
827 | // Grow |
828 | const uint32_t newMaxBits = numBits + 4 * BITS_PER_QUANT + numBits / 2; |
829 | realloc(newMaxBits); |
830 | } |
831 | else |
832 | { |
833 | // Caller accessing bits outside of external memory range |
834 | assert(false); |
835 | } |
836 | } |
837 | } |
838 | |
839 | inline void Bitstream::realloc(uint32_t numBits) |
840 | { |
841 | numBits = Math::divideAndRoundUp(numBits, BITS_PER_QUANT) * BITS_PER_QUANT; |
842 | |
843 | if (numBits != mMaxBits) |
844 | { |
845 | assert(numBits > mMaxBits); |
846 | |
847 | const uint32_t numQuants = Math::divideAndRoundUp(numBits, BITS_PER_QUANT); |
848 | |
849 | // Note: Eventually add support for custom allocators |
850 | auto buffer = bs_allocN<uint8_t>(numQuants); |
851 | if (mData) |
852 | { |
853 | const uint32_t numBytes = Math::divideAndRoundUp(mMaxBits, BITS_PER_QUANT) * BYTES_PER_QUANT; |
854 | memcpy(buffer, mData, numBytes); |
855 | bs_free(mData); |
856 | } |
857 | |
858 | mData = buffer; |
859 | mMaxBits = numBits; |
860 | } |
861 | } |
862 | } |
863 | |