// 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 "JBig2_HuffmanTable.h"

#include <string.h>

#include <vector>

#include "JBig2_BitStream.h"
#include "JBig2_Define.h"
#include "core/include/fxcrt/fx_memory.h"

CJBig2_HuffmanTable::CJBig2_HuffmanTable(const JBig2TableLine* pTable,
                                         int nLines,
                                         FX_BOOL bHTOOB) {
  init();
  m_bOK = parseFromStandardTable(pTable, nLines, bHTOOB);
}

CJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream* pStream) {
  init();
  m_bOK = parseFromCodedBuffer(pStream);
}

CJBig2_HuffmanTable::~CJBig2_HuffmanTable() {
  FX_Free(CODES);
  FX_Free(PREFLEN);
  FX_Free(RANGELEN);
  FX_Free(RANGELOW);
}
void CJBig2_HuffmanTable::init() {
  HTOOB = FALSE;
  NTEMP = 0;
  CODES = nullptr;
  PREFLEN = nullptr;
  RANGELEN = nullptr;
  RANGELOW = nullptr;
}
int CJBig2_HuffmanTable::parseFromStandardTable(const JBig2TableLine* pTable,
                                                int nLines,
                                                FX_BOOL bHTOOB) {
  HTOOB = bHTOOB;
  NTEMP = nLines;
  CODES = FX_Alloc(int, NTEMP);
  PREFLEN = FX_Alloc(int, NTEMP);
  RANGELEN = FX_Alloc(int, NTEMP);
  RANGELOW = FX_Alloc(int, NTEMP);
  int LENMAX = 0;
  for (FX_DWORD i = 0; i < NTEMP; ++i) {
    PREFLEN[i] = pTable[i].PREFLEN;
    RANGELEN[i] = pTable[i].RANDELEN;
    RANGELOW[i] = pTable[i].RANGELOW;
    if (PREFLEN[i] > LENMAX) {
      LENMAX = PREFLEN[i];
    }
  }
  int* LENCOUNT = FX_Alloc(int, LENMAX + 1);
  JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));
  int* FIRSTCODE = FX_Alloc(int, LENMAX + 1);
  for (FX_DWORD i = 0; i < NTEMP; ++i)
    ++LENCOUNT[PREFLEN[i]];

  int CURLEN = 1;
  FIRSTCODE[0] = 0;
  LENCOUNT[0] = 0;
  while (CURLEN <= LENMAX) {
    FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;
    int CURCODE = FIRSTCODE[CURLEN];
    FX_DWORD CURTEMP = 0;
    while (CURTEMP < NTEMP) {
      if (PREFLEN[CURTEMP] == CURLEN) {
        CODES[CURTEMP] = CURCODE;
        CURCODE = CURCODE + 1;
      }
      CURTEMP = CURTEMP + 1;
    }
    CURLEN = CURLEN + 1;
  }
  FX_Free(LENCOUNT);
  FX_Free(FIRSTCODE);
  return 1;
}

#define HT_CHECK_MEMORY_ADJUST                   \
  if (NTEMP >= nSize) {                          \
    nSize += 16;                                 \
    PREFLEN = FX_Realloc(int, PREFLEN, nSize);   \
    RANGELEN = FX_Realloc(int, RANGELEN, nSize); \
    RANGELOW = FX_Realloc(int, RANGELOW, nSize); \
  }
int CJBig2_HuffmanTable::parseFromCodedBuffer(CJBig2_BitStream* pStream) {
  unsigned char cTemp;
  if (pStream->read1Byte(&cTemp) == -1)
    return FALSE;

  HTOOB = cTemp & 0x01;
  unsigned char HTPS = ((cTemp >> 1) & 0x07) + 1;
  unsigned char HTRS = ((cTemp >> 4) & 0x07) + 1;
  FX_DWORD HTLOW;
  FX_DWORD HTHIGH;
  if (pStream->readInteger(&HTLOW) == -1 ||
      pStream->readInteger(&HTHIGH) == -1) {
    return FALSE;
  }

  const int low = static_cast<int>(HTLOW);
  const int high = static_cast<int>(HTHIGH);
  if (low > high)
    return false;

  FX_DWORD nSize = 16;
  PREFLEN = FX_Alloc(int, nSize);
  RANGELEN = FX_Alloc(int, nSize);
  RANGELOW = FX_Alloc(int, nSize);
  int cur_low = low;
  NTEMP = 0;
  do {
    HT_CHECK_MEMORY_ADJUST
    if ((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) ||
        (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) {
      return FALSE;
    }
    RANGELOW[NTEMP] = cur_low;
    cur_low += (1 << RANGELEN[NTEMP]);
    NTEMP = NTEMP + 1;
  } while (cur_low < high);
  HT_CHECK_MEMORY_ADJUST
  if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
    return FALSE;

  RANGELEN[NTEMP] = 32;
  RANGELOW[NTEMP] = low - 1;
  ++NTEMP;
  HT_CHECK_MEMORY_ADJUST
  if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
    return FALSE;

  RANGELEN[NTEMP] = 32;
  RANGELOW[NTEMP] = high;
  NTEMP = NTEMP + 1;
  if (HTOOB) {
    HT_CHECK_MEMORY_ADJUST
    if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
      return FALSE;

    ++NTEMP;
  }
  CODES = FX_Alloc(int, NTEMP);
  int LENMAX = 0;
  for (FX_DWORD i = 0; i < NTEMP; ++i)
    LENMAX = std::max(PREFLEN[i], LENMAX);

  std::vector<int> LENCOUNT(LENMAX + 1);
  for (FX_DWORD i = 0; i < NTEMP; ++i)
    LENCOUNT[PREFLEN[i]]++;
  LENCOUNT[0] = 0;

  std::vector<int> FIRSTCODE(LENMAX + 1);
  FIRSTCODE[0] = 0;
  for (int i = 1; i <= LENMAX; ++i) {
    FIRSTCODE[i] = (FIRSTCODE[i - 1] + LENCOUNT[i - 1]) << 1;
    int CURCODE = FIRSTCODE[i];
    for (FX_DWORD j = 0; j < NTEMP; ++j) {
      if (PREFLEN[j] == i)
        CODES[j] = CURCODE++;
    }
  }
  return TRUE;
}
