// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#if defined(UNSAFE_BUFFERS_BUILD)
// TODO(crbug.com/pdfium/2154): resolve buffer safety issues.
#pragma allow_unsafe_buffers
#endif

#include "core/fxcodec/jbig2/JBig2_ArithDecoder.h"

#include <iterator>

#include "core/fxcodec/jbig2/JBig2_BitStream.h"
#include "core/fxcrt/check_op.h"

namespace {

const JBig2ArithCtx::JBig2ArithQe kQeTable[] = {
    // Stupid hack to keep clang-format from reformatting this badly.
    {0x5601, 1, 1, true},    {0x3401, 2, 6, false},   {0x1801, 3, 9, false},
    {0x0AC1, 4, 12, false},  {0x0521, 5, 29, false},  {0x0221, 38, 33, false},
    {0x5601, 7, 6, true},    {0x5401, 8, 14, false},  {0x4801, 9, 14, false},
    {0x3801, 10, 14, false}, {0x3001, 11, 17, false}, {0x2401, 12, 18, false},
    {0x1C01, 13, 20, false}, {0x1601, 29, 21, false}, {0x5601, 15, 14, true},
    {0x5401, 16, 14, false}, {0x5101, 17, 15, false}, {0x4801, 18, 16, false},
    {0x3801, 19, 17, false}, {0x3401, 20, 18, false}, {0x3001, 21, 19, false},
    {0x2801, 22, 19, false}, {0x2401, 23, 20, false}, {0x2201, 24, 21, false},
    {0x1C01, 25, 22, false}, {0x1801, 26, 23, false}, {0x1601, 27, 24, false},
    {0x1401, 28, 25, false}, {0x1201, 29, 26, false}, {0x1101, 30, 27, false},
    {0x0AC1, 31, 28, false}, {0x09C1, 32, 29, false}, {0x08A1, 33, 30, false},
    {0x0521, 34, 31, false}, {0x0441, 35, 32, false}, {0x02A1, 36, 33, false},
    {0x0221, 37, 34, false}, {0x0141, 38, 35, false}, {0x0111, 39, 36, false},
    {0x0085, 40, 37, false}, {0x0049, 41, 38, false}, {0x0025, 42, 39, false},
    {0x0015, 43, 40, false}, {0x0009, 44, 41, false}, {0x0005, 45, 42, false},
    {0x0001, 45, 43, false}, {0x5601, 46, 46, false}};

const unsigned int kDefaultAValue = 0x8000;

}  // namespace

JBig2ArithCtx::JBig2ArithCtx() = default;

int JBig2ArithCtx::DecodeNLPS(const JBig2ArithQe& qe) {
  bool D = !m_MPS;
  if (qe.bSwitch)
    m_MPS = !m_MPS;
  m_I = qe.NLPS;
  DCHECK_LT(m_I, std::size(kQeTable));
  return D;
}

int JBig2ArithCtx::DecodeNMPS(const JBig2ArithQe& qe) {
  m_I = qe.NMPS;
  DCHECK_LT(m_I, std::size(kQeTable));
  return MPS();
}

CJBig2_ArithDecoder::CJBig2_ArithDecoder(CJBig2_BitStream* pStream)
    : m_pStream(pStream) {
  m_B = m_pStream->getCurByte_arith();
  m_C = (m_B ^ 0xff) << 16;
  BYTEIN();
  m_C = m_C << 7;
  m_CT = m_CT - 7;
  m_A = kDefaultAValue;
}

CJBig2_ArithDecoder::~CJBig2_ArithDecoder() = default;

int CJBig2_ArithDecoder::Decode(JBig2ArithCtx* pCX) {
  CHECK_LT(pCX->I(), std::size(kQeTable));

  const JBig2ArithCtx::JBig2ArithQe& qe = kQeTable[pCX->I()];
  m_A -= qe.Qe;
  if ((m_C >> 16) < m_A) {
    if (m_A & kDefaultAValue)
      return pCX->MPS();

    const int D = m_A < qe.Qe ? pCX->DecodeNLPS(qe) : pCX->DecodeNMPS(qe);
    ReadValueA();
    return D;
  }

  m_C -= m_A << 16;
  const int D = m_A < qe.Qe ? pCX->DecodeNMPS(qe) : pCX->DecodeNLPS(qe);
  m_A = qe.Qe;
  ReadValueA();
  return D;
}

void CJBig2_ArithDecoder::BYTEIN() {
  if (m_B == 0xff) {
    unsigned char B1 = m_pStream->getNextByte_arith();
    if (B1 > 0x8f) {
      m_CT = 8;

      switch (m_State) {
        case StreamState::kDataAvailable:
          // Finished decoding data (see JBIG2 spec, Section E.3.4).
          m_State = StreamState::kDecodingFinished;
          break;
        case StreamState::kDecodingFinished:
          // Allow one more call in the finished state. https://crbug.com/947622
          m_State = StreamState::kLooping;
          break;
        case StreamState::kLooping:
          // Looping state detected. Mark decoding as complete to bail out.
          // https://crbug.com/767156
          m_Complete = true;
          break;
      }
    } else {
      m_pStream->incByteIdx();
      m_B = B1;
      m_C = m_C + 0xfe00 - (m_B << 9);
      m_CT = 7;
    }
  } else {
    m_pStream->incByteIdx();
    m_B = m_pStream->getCurByte_arith();
    m_C = m_C + 0xff00 - (m_B << 8);
    m_CT = 8;
  }

  if (!m_pStream->IsInBounds())
    m_Complete = true;
}

void CJBig2_ArithDecoder::ReadValueA() {
  do {
    if (m_CT == 0)
      BYTEIN();
    m_A <<= 1;
    m_C <<= 1;
    --m_CT;
  } while ((m_A & kDefaultAValue) == 0);
}
