RiceDeltaDecoder.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. #include "RiceDeltaDecoder.h"
  5. namespace {
  6. ////////////////////////////////////////////////////////////////////////
  7. // BitBuffer is copied and modified from webrtc/base/bitbuffer.h
  8. //
  9. /*
  10. * Copyright 2015 The WebRTC Project Authors. All rights reserved.
  11. *
  12. * Use of this source code is governed by a BSD-style license
  13. * that can be found in the LICENSE file in the root of the source
  14. * tree (webrtc/base/bitbuffer.h/cc). An additional intellectual property
  15. * rights grant can be found in the file PATENTS. All contributing
  16. * project authors may be found in the AUTHORS file in the root of
  17. * the source tree.
  18. */
  19. class BitBuffer {
  20. public:
  21. BitBuffer(const uint8_t* bytes, size_t byte_count);
  22. // The remaining bits in the byte buffer.
  23. uint64_t RemainingBitCount() const;
  24. // Reads bit-sized values from the buffer. Returns false if there isn't enough
  25. // data left for the specified bit count..
  26. bool ReadBits(uint32_t* val, size_t bit_count);
  27. // Peeks bit-sized values from the buffer. Returns false if there isn't enough
  28. // data left for the specified number of bits. Doesn't move the current
  29. // offset.
  30. bool PeekBits(uint32_t* val, size_t bit_count);
  31. // Reads the exponential golomb encoded value at the current offset.
  32. // Exponential golomb values are encoded as:
  33. // 1) x = source val + 1
  34. // 2) In binary, write [countbits(x) - 1] 1s, then x
  35. // To decode, we count the number of leading 1 bits, read that many + 1 bits,
  36. // and increment the result by 1.
  37. // Returns false if there isn't enough data left for the specified type, or if
  38. // the value wouldn't fit in a uint32_t.
  39. bool ReadExponentialGolomb(uint32_t* val);
  40. // Moves current position |bit_count| bits forward. Returns false if
  41. // there aren't enough bits left in the buffer.
  42. bool ConsumeBits(size_t bit_count);
  43. protected:
  44. const uint8_t* const bytes_;
  45. // The total size of |bytes_|.
  46. size_t byte_count_;
  47. // The current offset, in bytes, from the start of |bytes_|.
  48. size_t byte_offset_;
  49. // The current offset, in bits, into the current byte.
  50. size_t bit_offset_;
  51. };
  52. } // end of unnamed namespace
  53. static void
  54. ReverseByte(uint8_t& b)
  55. {
  56. b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
  57. b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
  58. b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
  59. }
  60. namespace mozilla {
  61. namespace safebrowsing {
  62. RiceDeltaDecoder::RiceDeltaDecoder(uint8_t* aEncodedData,
  63. size_t aEncodedDataSize)
  64. : mEncodedData(aEncodedData)
  65. , mEncodedDataSize(aEncodedDataSize)
  66. {
  67. }
  68. bool
  69. RiceDeltaDecoder::Decode(uint32_t aRiceParameter,
  70. uint32_t aFirstValue,
  71. uint32_t aNumEntries,
  72. uint32_t* aDecodedData)
  73. {
  74. // Reverse each byte before reading bits from the byte buffer.
  75. for (size_t i = 0; i < mEncodedDataSize; i++) {
  76. ReverseByte(mEncodedData[i]);
  77. }
  78. BitBuffer bitBuffer(mEncodedData, mEncodedDataSize);
  79. // q = quotient
  80. // r = remainder
  81. // k = RICE parameter
  82. const uint32_t k = aRiceParameter;
  83. aDecodedData[0] = aFirstValue;
  84. for (uint32_t i = 0; i < aNumEntries; i++) {
  85. // Read the quotient of N.
  86. uint32_t q;
  87. if (!bitBuffer.ReadExponentialGolomb(&q)) {
  88. LOG(("Encoded data underflow!"));
  89. return false;
  90. }
  91. // Read the remainder of N, one bit at a time.
  92. uint32_t r = 0;
  93. for (uint32_t j = 0; j < k; j++) {
  94. uint32_t b = 0;
  95. if (!bitBuffer.ReadBits(&b, 1)) {
  96. // Insufficient bits. Just leave them as zeros.
  97. break;
  98. }
  99. // Add the bit to the right position so that it's in Little Endian order.
  100. r |= b << j;
  101. }
  102. // Caculate N from q,r,k.
  103. uint32_t N = (q << k) + r;
  104. // We start filling aDecodedData from [1].
  105. aDecodedData[i + 1] = N + aDecodedData[i];
  106. }
  107. return true;
  108. }
  109. } // end of namespace mozilla
  110. } // end of namespace safebrowsing
  111. namespace {
  112. //////////////////////////////////////////////////////////////////////////
  113. // The BitBuffer impl is copied and modified from webrtc/base/bitbuffer.cc
  114. //
  115. // Returns the lowest (right-most) |bit_count| bits in |byte|.
  116. uint8_t LowestBits(uint8_t byte, size_t bit_count) {
  117. return byte & ((1 << bit_count) - 1);
  118. }
  119. // Returns the highest (left-most) |bit_count| bits in |byte|, shifted to the
  120. // lowest bits (to the right).
  121. uint8_t HighestBits(uint8_t byte, size_t bit_count) {
  122. MOZ_ASSERT(bit_count < 8u);
  123. uint8_t shift = 8 - static_cast<uint8_t>(bit_count);
  124. uint8_t mask = 0xFF << shift;
  125. return (byte & mask) >> shift;
  126. }
  127. BitBuffer::BitBuffer(const uint8_t* bytes, size_t byte_count)
  128. : bytes_(bytes), byte_count_(byte_count), byte_offset_(), bit_offset_() {
  129. MOZ_ASSERT(static_cast<uint64_t>(byte_count_) <=
  130. std::numeric_limits<uint32_t>::max());
  131. }
  132. uint64_t BitBuffer::RemainingBitCount() const {
  133. return (static_cast<uint64_t>(byte_count_) - byte_offset_) * 8 - bit_offset_;
  134. }
  135. bool BitBuffer::PeekBits(uint32_t* val, size_t bit_count) {
  136. if (!val || bit_count > RemainingBitCount() || bit_count > 32) {
  137. return false;
  138. }
  139. const uint8_t* bytes = bytes_ + byte_offset_;
  140. size_t remaining_bits_in_current_byte = 8 - bit_offset_;
  141. uint32_t bits = LowestBits(*bytes++, remaining_bits_in_current_byte);
  142. // If we're reading fewer bits than what's left in the current byte, just
  143. // return the portion of this byte that we need.
  144. if (bit_count < remaining_bits_in_current_byte) {
  145. *val = HighestBits(bits, bit_offset_ + bit_count);
  146. return true;
  147. }
  148. // Otherwise, subtract what we've read from the bit count and read as many
  149. // full bytes as we can into bits.
  150. bit_count -= remaining_bits_in_current_byte;
  151. while (bit_count >= 8) {
  152. bits = (bits << 8) | *bytes++;
  153. bit_count -= 8;
  154. }
  155. // Whatever we have left is smaller than a byte, so grab just the bits we need
  156. // and shift them into the lowest bits.
  157. if (bit_count > 0) {
  158. bits <<= bit_count;
  159. bits |= HighestBits(*bytes, bit_count);
  160. }
  161. *val = bits;
  162. return true;
  163. }
  164. bool BitBuffer::ReadBits(uint32_t* val, size_t bit_count) {
  165. return PeekBits(val, bit_count) && ConsumeBits(bit_count);
  166. }
  167. bool BitBuffer::ConsumeBits(size_t bit_count) {
  168. if (bit_count > RemainingBitCount()) {
  169. return false;
  170. }
  171. byte_offset_ += (bit_offset_ + bit_count) / 8;
  172. bit_offset_ = (bit_offset_ + bit_count) % 8;
  173. return true;
  174. }
  175. bool BitBuffer::ReadExponentialGolomb(uint32_t* val) {
  176. if (!val) {
  177. return false;
  178. }
  179. *val = 0;
  180. // Count the number of leading 0 bits by peeking/consuming them one at a time.
  181. size_t one_bit_count = 0;
  182. uint32_t peeked_bit;
  183. while (PeekBits(&peeked_bit, 1) && peeked_bit == 1) {
  184. one_bit_count++;
  185. ConsumeBits(1);
  186. }
  187. if (!ConsumeBits(1)) {
  188. return false; // The stream is incorrectly terminated at '1'.
  189. }
  190. *val = one_bit_count;
  191. return true;
  192. }
  193. }