// Copyright 2014 PDFium Authors. All rights reserved.
// 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

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

#include <vector>

#include "core/fxcrt/fx_memory.h"

namespace {

int ShiftOr(int val, int bitwise_or_val) {
  return (val << 1) | bitwise_or_val;
}

const struct ArithIntDecodeData {
  int nNeedBits;
  int nValue;
} g_ArithIntDecodeData[] = {
    {2, 0}, {4, 4}, {6, 20}, {8, 84}, {12, 340}, {32, 4436},
};

size_t RecursiveDecode(CJBig2_ArithDecoder* decoder,
                       std::vector<JBig2ArithCtx>* context,
                       int* prev,
                       size_t depth) {
  static const size_t kDepthEnd = FX_ArraySize(g_ArithIntDecodeData) - 1;
  if (depth == kDepthEnd)
    return kDepthEnd;

  JBig2ArithCtx* pCX = &(*context)[*prev];
  int D = decoder->DECODE(pCX);
  *prev = ShiftOr(*prev, D);
  if (!D)
    return depth;
  return RecursiveDecode(decoder, context, prev, depth + 1);
}

}  // namespace

CJBig2_ArithIntDecoder::CJBig2_ArithIntDecoder() {
  m_IAx.resize(512);
}

CJBig2_ArithIntDecoder::~CJBig2_ArithIntDecoder() {}

bool CJBig2_ArithIntDecoder::decode(CJBig2_ArithDecoder* pArithDecoder,
                                    int* nResult) {
  // This decoding algorithm is explained in "Annex A - Arithmetic Integer
  // Decoding Procedure" on page 113 of the JBIG2 specification (ISO/IEC FCD
  // 14492).
  int PREV = 1;
  if (pArithDecoder->IsComplete())
    return false;

  const int S = pArithDecoder->DECODE(&m_IAx[PREV]);
  PREV = ShiftOr(PREV, S);

  const size_t nDecodeDataIndex =
      RecursiveDecode(pArithDecoder, &m_IAx, &PREV, 0);

  int nTemp = 0;
  for (int i = 0; i < g_ArithIntDecodeData[nDecodeDataIndex].nNeedBits; ++i) {
    if (pArithDecoder->IsComplete())
      return false;

    int D = pArithDecoder->DECODE(&m_IAx[PREV]);
    PREV = ShiftOr(PREV, D);
    if (PREV >= 256)
      PREV = (PREV & 511) | 256;
    nTemp = ShiftOr(nTemp, D);
  }
  pdfium::base::CheckedNumeric<int> safeValue =
      g_ArithIntDecodeData[nDecodeDataIndex].nValue;
  safeValue += nTemp;

  // Value does not fit in int.
  if (!safeValue.IsValid()) {
    *nResult = 0;
    return false;
  }

  int nValue = safeValue.ValueOrDie();
  if (S == 1 && nValue > 0)
    nValue = -nValue;

  *nResult = nValue;
  return S != 1 || nValue != 0;
}

CJBig2_ArithIaidDecoder::CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA)
    : SBSYMCODELEN(SBSYMCODELENA) {
  m_IAID.resize(static_cast<size_t>(1) << SBSYMCODELEN);
}

CJBig2_ArithIaidDecoder::~CJBig2_ArithIaidDecoder() {}

bool CJBig2_ArithIaidDecoder::decode(CJBig2_ArithDecoder* pArithDecoder,
                                     uint32_t* nResult) {
  int PREV = 1;
  for (unsigned char i = 0; i < SBSYMCODELEN; ++i) {
    JBig2ArithCtx* pCX = &m_IAID[PREV];
    if (pArithDecoder->IsComplete())
      return false;

    int D = pArithDecoder->DECODE(pCX);
    PREV = ShiftOr(PREV, D);
  }
  *nResult = PREV - (1 << SBSYMCODELEN);
  return true;
}
