BooleanDecoder.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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 "BooleanDecoder.h"
  9. namespace Gfx {
  10. ErrorOr<BooleanDecoder> BooleanDecoder::initialize(MaybeOwned<BigEndianInputBitStream> bit_stream, size_t size_in_bytes)
  11. {
  12. VERIFY(bit_stream->is_aligned_to_byte_boundary());
  13. auto value = TRY(bit_stream->read_value<u8>());
  14. u8 range = 255;
  15. u64 bits_left = (8 * size_in_bytes) - 8;
  16. return BooleanDecoder { move(bit_stream), value, range, bits_left };
  17. }
  18. /* 9.2.1 */
  19. ErrorOr<BooleanDecoder> BooleanDecoder::initialize_vp9(MaybeOwned<BigEndianInputBitStream> bit_stream, size_t size_in_bytes)
  20. {
  21. BooleanDecoder decoder = TRY(initialize(move(bit_stream), size_in_bytes));
  22. if (TRY(decoder.read_bool(128)))
  23. return Error::from_string_literal("Range decoder marker was non-zero");
  24. return decoder;
  25. }
  26. /* 9.2.2 */
  27. ErrorOr<bool> BooleanDecoder::read_bool(u8 probability)
  28. {
  29. auto split = 1u + (((m_range - 1u) * probability) >> 8u);
  30. bool return_bool;
  31. if (m_value < split) {
  32. m_range = split;
  33. return_bool = false;
  34. } else {
  35. m_range -= split;
  36. m_value -= split;
  37. return_bool = true;
  38. }
  39. if (m_range < 128) {
  40. u8 bits_to_shift_into_range = count_leading_zeroes(m_range);
  41. if (bits_to_shift_into_range > m_bits_left)
  42. return Error::from_string_literal("Range decoder is out of data");
  43. m_range <<= bits_to_shift_into_range;
  44. m_value = (m_value << bits_to_shift_into_range) | TRY(m_bit_stream->read_bits<u8>(bits_to_shift_into_range));
  45. m_bits_left -= bits_to_shift_into_range;
  46. }
  47. return return_bool;
  48. }
  49. ErrorOr<u8> BooleanDecoder::read_literal(u8 bits)
  50. {
  51. u8 return_value = 0;
  52. for (size_t i = 0; i < bits; i++) {
  53. return_value = (2 * return_value) + TRY(read_bool(128));
  54. }
  55. return return_value;
  56. }
  57. /* 9.2.3 */
  58. ErrorOr<void> BooleanDecoder::finish_decode_vp9()
  59. {
  60. while (m_bits_left > 0) {
  61. auto padding_read_size = min(m_bits_left, 64);
  62. auto padding_bits = TRY(m_bit_stream->read_bits(padding_read_size));
  63. m_bits_left -= padding_read_size;
  64. if (padding_bits != 0)
  65. return Error::from_string_literal("Range decoder has non-zero padding element");
  66. }
  67. // FIXME: It is a requirement of bitstream conformance that enough padding bits are inserted to ensure that the final coded byte of a frame is not equal to a superframe marker.
  68. // A byte b is equal to a superframe marker if and only if (b & 0xe0)is equal to 0xc0, i.e. if the most significant 3 bits are equal to 0b110.
  69. return {};
  70. }
  71. }