BooleanDecoder.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
  3. * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/BuiltinWrappers.h>
  8. #include <AK/Debug.h>
  9. #include <AK/Endian.h>
  10. #include "BooleanDecoder.h"
  11. namespace Gfx {
  12. // 9.2.1 Initialization process for Boolean decoder
  13. ErrorOr<BooleanDecoder> BooleanDecoder::initialize(ReadonlyBytes data)
  14. {
  15. if (data.size() == 0)
  16. return Error::from_string_literal("Size of decoder range cannot be zero");
  17. // NOTE: This implementation is shared between VP8 and VP9. Therefore, we do not check the
  18. // marker bit at the start of the range decode that is required in the VP9 specification.
  19. // This is instead handled by the function that instantiates all range decoders for the
  20. // VP9 decoder.
  21. // NOTE: As noted below in fill_reservoir(), we read in multi-byte-sized chunks,
  22. // so here we will deviate from the standard to count in bytes rather than bits.
  23. return BooleanDecoder { data.data(), data.size() };
  24. }
  25. // Instead of filling the value field one bit at a time as the spec suggests, we store the
  26. // data to be read in a reservoir of greater than one byte. This allows us to read out data
  27. // for the entire reservoir at once, avoiding a lot of branch misses in read_bool().
  28. void BooleanDecoder::fill_reservoir()
  29. {
  30. if (m_value_bits_left > 8)
  31. return;
  32. // Defer errors until the decode is finalized, so the work to check for errors and return them only has
  33. // to be done once. Not refilling the reservoir here will only result in reading out all zeroes until
  34. // the range decode is finished.
  35. if (m_bytes_left == 0) {
  36. dbgln_if(VPX_DEBUG, "BooleanDecoder has read past the end of the coded range");
  37. m_overread = true;
  38. return;
  39. }
  40. // Read the data into the most significant bits of a variable.
  41. auto read_size = min<size_t>(reserve_bytes, m_bytes_left);
  42. ValueType read_value = 0;
  43. memcpy(&read_value, m_data, read_size);
  44. read_value = AK::convert_between_host_and_big_endian(read_value);
  45. // Skip the number of bytes read in the data.
  46. m_data += read_size;
  47. m_bytes_left -= read_size;
  48. // Shift the value that was read to be less significant than the least significant bit available in the reservoir.
  49. read_value >>= m_value_bits_left;
  50. m_value |= read_value;
  51. m_value_bits_left += read_size * 8;
  52. }
  53. // 9.2.2 Boolean decoding process
  54. bool BooleanDecoder::read_bool(u8 probability)
  55. {
  56. auto split = 1u + (((m_range - 1u) * probability) >> 8u);
  57. // The actual value being read resides in the most significant 8 bits
  58. // of the value field, so we shift the split into that range for comparison.
  59. auto split_shifted = static_cast<ValueType>(split) << reserve_bits;
  60. bool return_bool;
  61. if (m_value < split_shifted) {
  62. m_range = split;
  63. return_bool = false;
  64. } else {
  65. m_range -= split;
  66. m_value -= split_shifted;
  67. return_bool = true;
  68. }
  69. u8 bits_to_shift_into_range = count_leading_zeroes(m_range) - ((sizeof(m_range) - 1) * 8);
  70. m_range <<= bits_to_shift_into_range;
  71. m_value <<= bits_to_shift_into_range;
  72. m_value_bits_left -= bits_to_shift_into_range;
  73. fill_reservoir();
  74. return return_bool;
  75. }
  76. // 9.2.4 Parsing process for read_literal
  77. u8 BooleanDecoder::read_literal(u8 bits)
  78. {
  79. u8 return_value = 0;
  80. for (size_t i = 0; i < bits; i++) {
  81. return_value = (2 * return_value) + read_bool(128);
  82. }
  83. return return_value;
  84. }
  85. ErrorOr<void> BooleanDecoder::finish_decode()
  86. {
  87. if (m_overread)
  88. return Error::from_string_literal("Range decoder was read past the end of its data");
  89. #if VPX_DEBUG
  90. // 9.2.3 Exit process for Boolean decoder
  91. //
  92. // This process is invoked when the function exit_bool( ) is called from the syntax structure.
  93. //
  94. // The padding syntax element is read using the f(BoolMaxBits) parsing process.
  95. //
  96. // It is a requirement of bitstream conformance that padding is equal to 0.
  97. //
  98. // NOTE: This requirement holds up for all of our WebP lossy test inputs, as well.
  99. bool padding_good = true;
  100. if (m_value != 0)
  101. padding_good = false;
  102. while (m_bytes_left > 0) {
  103. if (*m_data != 0)
  104. padding_good = false;
  105. m_data++;
  106. m_bytes_left--;
  107. }
  108. if (!padding_good)
  109. return Error::from_string_literal("Range decoder padding was non-zero");
  110. #endif
  111. return {};
  112. }
  113. }