// Copyright (c) 2016 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
#include "common/vp9_header_parser.h"

#include <stdio.h>

namespace vp9_parser {

bool Vp9HeaderParser::SetFrame(const uint8_t* frame, size_t length) {
  if (!frame || length == 0)
    return false;

  frame_ = frame;
  frame_size_ = length;
  bit_offset_ = 0;
  profile_ = -1;
  show_existing_frame_ = 0;
  key_ = 0;
  altref_ = 0;
  error_resilient_mode_ = 0;
  intra_only_ = 0;
  reset_frame_context_ = 0;
  color_space_ = 0;
  color_range_ = 0;
  subsampling_x_ = 0;
  subsampling_y_ = 0;
  refresh_frame_flags_ = 0;
  return true;
}

bool Vp9HeaderParser::ParseUncompressedHeader(const uint8_t* frame,
                                              size_t length) {
  if (!SetFrame(frame, length))
    return false;
  const int frame_marker = VpxReadLiteral(2);
  if (frame_marker != kVp9FrameMarker) {
    fprintf(stderr, "Invalid VP9 frame_marker:%d\n", frame_marker);
    return false;
  }

  profile_ = ReadBit();
  profile_ |= ReadBit() << 1;
  if (profile_ > 2)
    profile_ += ReadBit();

  // TODO(fgalligan): Decide how to handle show existing frames.
  show_existing_frame_ = ReadBit();
  if (show_existing_frame_)
    return true;

  key_ = !ReadBit();
  altref_ = !ReadBit();
  error_resilient_mode_ = ReadBit();
  if (key_) {
    if (!ValidateVp9SyncCode()) {
      fprintf(stderr, "Invalid Sync code!\n");
      return false;
    }

    ParseColorSpace();
    ParseFrameResolution();
    ParseFrameParallelMode();
    ParseTileInfo();
  } else {
    intra_only_ = altref_ ? ReadBit() : 0;
    reset_frame_context_ = error_resilient_mode_ ? 0 : VpxReadLiteral(2);
    if (intra_only_) {
      if (!ValidateVp9SyncCode()) {
        fprintf(stderr, "Invalid Sync code!\n");
        return false;
      }

      if (profile_ > 0) {
        ParseColorSpace();
      } else {
        // NOTE: The intra-only frame header does not include the specification
        // of either the color format or color sub-sampling in profile 0. VP9
        // specifies that the default color format should be YUV 4:2:0 in this
        // case (normative).
        color_space_ = kVpxCsBt601;
        color_range_ = kVpxCrStudioRange;
        subsampling_y_ = subsampling_x_ = 1;
        bit_depth_ = 8;
      }

      refresh_frame_flags_ = VpxReadLiteral(kRefFrames);
      ParseFrameResolution();
    } else {
      refresh_frame_flags_ = VpxReadLiteral(kRefFrames);
      for (int i = 0; i < kRefsPerFrame; ++i) {
        VpxReadLiteral(kRefFrames_LOG2);  // Consume ref.
        ReadBit();  // Consume ref sign bias.
      }

      bool found = false;
      for (int i = 0; i < kRefsPerFrame; ++i) {
        if (ReadBit()) {
          // Found previous reference, width and height did not change since
          // last frame.
          found = true;
          break;
        }
      }

      if (!found)
        ParseFrameResolution();
    }
  }
  return true;
}

int Vp9HeaderParser::ReadBit() {
  const size_t off = bit_offset_;
  const size_t byte_offset = off >> 3;
  const int bit_shift = 7 - static_cast<int>(off & 0x7);
  if (byte_offset < frame_size_) {
    const int bit = (frame_[byte_offset] >> bit_shift) & 1;
    bit_offset_++;
    return bit;
  } else {
    return 0;
  }
}

int Vp9HeaderParser::VpxReadLiteral(int bits) {
  int value = 0;
  for (int bit = bits - 1; bit >= 0; --bit)
    value |= ReadBit() << bit;
  return value;
}

bool Vp9HeaderParser::ValidateVp9SyncCode() {
  const int sync_code_0 = VpxReadLiteral(8);
  const int sync_code_1 = VpxReadLiteral(8);
  const int sync_code_2 = VpxReadLiteral(8);
  return (sync_code_0 == 0x49 && sync_code_1 == 0x83 && sync_code_2 == 0x42);
}

void Vp9HeaderParser::ParseColorSpace() {
  bit_depth_ = 0;
  if (profile_ >= 2)
    bit_depth_ = ReadBit() ? 12 : 10;
  else
    bit_depth_ = 8;
  color_space_ = VpxReadLiteral(3);
  if (color_space_ != kVpxCsSrgb) {
    color_range_ = ReadBit();
    if (profile_ == 1 || profile_ == 3) {
      subsampling_x_ = ReadBit();
      subsampling_y_ = ReadBit();
      ReadBit();
    } else {
      subsampling_y_ = subsampling_x_ = 1;
    }
  } else {
    color_range_ = kVpxCrFullRange;
    if (profile_ == 1 || profile_ == 3) {
      subsampling_y_ = subsampling_x_ = 0;
      ReadBit();
    }
  }
}

void Vp9HeaderParser::ParseFrameResolution() {
  width_ = VpxReadLiteral(16) + 1;
  height_ = VpxReadLiteral(16) + 1;
}

void Vp9HeaderParser::ParseFrameParallelMode() {
  if (ReadBit()) {
    VpxReadLiteral(16);  // display width
    VpxReadLiteral(16);  // display height
  }
  if (!error_resilient_mode_) {
    ReadBit();  // Consume refresh frame context
    frame_parallel_mode_ = ReadBit();
  } else {
    frame_parallel_mode_ = 1;
  }
}

void Vp9HeaderParser::ParseTileInfo() {
  VpxReadLiteral(2);  // Consume frame context index

  // loopfilter
  VpxReadLiteral(6);  // Consume filter level
  VpxReadLiteral(3);  // Consume sharpness level

  const bool mode_ref_delta_enabled = ReadBit();
  if (mode_ref_delta_enabled) {
    const bool mode_ref_delta_update = ReadBit();
    if (mode_ref_delta_update) {
      const int kMaxRefLFDeltas = 4;
      for (int i = 0; i < kMaxRefLFDeltas; ++i) {
        if (ReadBit())
          VpxReadLiteral(7);  // Consume ref_deltas + sign
      }

      const int kMaxModeDeltas = 2;
      for (int i = 0; i < kMaxModeDeltas; ++i) {
        if (ReadBit())
          VpxReadLiteral(7);  // Consume mode_delta + sign
      }
    }
  }

  // quantization
  VpxReadLiteral(8);  // Consume base_q
  SkipDeltaQ();  // y dc
  SkipDeltaQ();  // uv ac
  SkipDeltaQ();  // uv dc

  // segmentation
  const bool segmentation_enabled = ReadBit();
  if (!segmentation_enabled) {
    const int aligned_width = AlignPowerOfTwo(width_, kMiSizeLog2);
    const int mi_cols = aligned_width >> kMiSizeLog2;
    const int aligned_mi_cols = AlignPowerOfTwo(mi_cols, kMiSizeLog2);
    const int sb_cols = aligned_mi_cols >> 3;  // to_sbs(mi_cols);
    int min_log2_n_tiles, max_log2_n_tiles;

    for (max_log2_n_tiles = 0;
         (sb_cols >> max_log2_n_tiles) >= kMinTileWidthB64;
         max_log2_n_tiles++) {
    }
    max_log2_n_tiles--;
    if (max_log2_n_tiles < 0)
      max_log2_n_tiles = 0;

    for (min_log2_n_tiles = 0; (kMaxTileWidthB64 << min_log2_n_tiles) < sb_cols;
         min_log2_n_tiles++) {
    }

    // columns
    const int max_log2_tile_cols = max_log2_n_tiles;
    const int min_log2_tile_cols = min_log2_n_tiles;
    int max_ones = max_log2_tile_cols - min_log2_tile_cols;
    int log2_tile_cols = min_log2_tile_cols;
    while (max_ones-- && ReadBit())
      log2_tile_cols++;

    // rows
    int log2_tile_rows = ReadBit();
    if (log2_tile_rows)
      log2_tile_rows += ReadBit();

    row_tiles_ = 1 << log2_tile_rows;
    column_tiles_ = 1 << log2_tile_cols;
  }
}

void Vp9HeaderParser::SkipDeltaQ() {
  if (ReadBit())
    VpxReadLiteral(4);
}

int Vp9HeaderParser::AlignPowerOfTwo(int value, int n) {
  return (((value) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1));
}

}  // namespace vp9_parser
