// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cobalt/media/filters/vp9_bool_decoder.h"

#include <algorithm>

#include "base/logging.h"
#include "cobalt/media/base/bit_reader.h"

namespace cobalt {
namespace media {

namespace {

// This is an optimization lookup table for the loop in spec 9.2.2.
//     while BoolRange <= 128:
//       read 1 bit
//       BoolRange *= 2
// This table indicates how many iterations to run for a given BoolRange. So
// the loop could be reduced to
//     read (kCountToShiftTo128[BoolRange]) bits
const int kCountToShiftTo128[256] = {
    0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
    3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
}  // namespace

Vp9BoolDecoder::Vp9BoolDecoder() {}

Vp9BoolDecoder::~Vp9BoolDecoder() {}

// 9.2.1 Initialization process for Boolean decoder
bool Vp9BoolDecoder::Initialize(const uint8_t* data, size_t size) {
  DCHECK(data);
  if (size < 1) {
    DVLOG(1) << "input size of bool decoder shall be at least 1";
    valid_ = false;
    return false;
  }

  reader_.reset(new BitReader(data, size));
  valid_ = true;

  bool_value_ = 0;
  count_to_fill_ = 8;
  bool_range_ = 255;
  if (ReadLiteral(1) != 0) {
    DVLOG(1) << "marker bit should be 0";
    valid_ = false;
    return false;
  }
  return true;
}

// Fill at least |count_to_fill_| bits and prefill remain bits of |bool_value_|
// if data is enough.
bool Vp9BoolDecoder::Fill() {
  DCHECK_GE(count_to_fill_, 0);

  int bits_left = reader_->bits_available();
  if (bits_left < count_to_fill_) {
    valid_ = false;
    DVLOG(1) << "Vp9BoolDecoder reads beyond the end of stream";
    return false;
  }

  DCHECK_LE(count_to_fill_, kBoolSize);
  int max_bits_to_read = kBigBoolBitSize - kBoolSize + count_to_fill_;
  int bits_to_read = std::min(max_bits_to_read, bits_left);

  BigBool data;
  reader_->ReadBits(bits_to_read, &data);
  bool_value_ |= data << (max_bits_to_read - bits_to_read);
  count_to_fill_ -= bits_to_read;

  return true;
}

// 9.2.2 Boolean decoding process
bool Vp9BoolDecoder::ReadBool(int prob) {
  DCHECK(reader_);

  if (count_to_fill_ > 0) {
    if (!Fill()) return false;
  }

  unsigned int split = (bool_range_ * prob + (256 - prob)) >> kBoolSize;
  BigBool big_split = static_cast<BigBool>(split)
                      << (kBigBoolBitSize - kBoolSize);

  bool bit;
  if (bool_value_ < big_split) {
    bool_range_ = split;
    bit = false;
  } else {
    bool_range_ -= split;
    bool_value_ -= big_split;
    bit = true;
  }

  // Need to fill |count| bits next time in order to make |bool_range_| >=
  // 128.
  DCHECK_LT(bool_range_, arraysize(kCountToShiftTo128));
  DCHECK_GT(bool_range_, 0u);
  int count = kCountToShiftTo128[bool_range_];
  bool_range_ <<= count;
  bool_value_ <<= count;
  count_to_fill_ += count;

  return bit;
}

// 9.2.4 Parsing process for read_literal
uint8_t Vp9BoolDecoder::ReadLiteral(int bits) {
  DCHECK_LT(static_cast<size_t>(bits), sizeof(uint8_t) * 8);
  DCHECK(reader_);

  uint8_t x = 0;
  for (int i = 0; i < bits; i++) x = 2 * x + ReadBool(128);

  return x;
}

bool Vp9BoolDecoder::ConsumePaddingBits() {
  DCHECK(reader_);

  if (count_to_fill_ > reader_->bits_available()) {
    // 9.2.2 Boolean decoding process
    // Although we actually don't used the value, spec says the bitstream
    // should have enough bits to fill bool range, this should never happen.
    DVLOG(2) << "not enough bits in bitstream to fill bool range";
    return false;
  }

  if (bool_value_ != 0) {
    DVLOG(1) << "prefilled padding bits are not zero";
    return false;
  }
  while (reader_->bits_available() > 0) {
    int data;
    int size_to_read =
        std::min(reader_->bits_available(), static_cast<int>(sizeof(data) * 8));
    reader_->ReadBits(size_to_read, &data);
    if (data != 0) {
      DVLOG(1) << "padding bits are not zero";
      return false;
    }
  }
  return true;
}

}  // namespace media
}  // namespace cobalt
