1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// found in the LICENSE file.
4ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
7ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "core/src/fxcodec/jbig2/JBig2_HuffmanTable.h"
8ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
9ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include <algorithm>
10ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include <vector>
11ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
12ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "core/include/fxcrt/fx_memory.h"
13ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "core/src/fxcodec/jbig2/JBig2_BitStream.h"
14ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "core/src/fxcodec/jbig2/JBig2_Define.h"
15ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "core/src/fxcodec/jbig2/JBig2_HuffmanTable_Standard.h"
16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
17ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCJBig2_HuffmanTable::CJBig2_HuffmanTable(const JBig2TableLine* pTable,
18ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                         FX_DWORD nLines,
19ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                         bool bHTOOB)
20ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    : m_bOK(true), HTOOB(bHTOOB), NTEMP(nLines) {
21ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  ParseFromStandardTable(pTable);
22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
24ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream* pStream)
25ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    : HTOOB(false), NTEMP(0) {
26ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  m_bOK = ParseFromCodedBuffer(pStream);
27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
28e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
29ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCJBig2_HuffmanTable::~CJBig2_HuffmanTable() {
30e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
31ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
32ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CJBig2_HuffmanTable::ParseFromStandardTable(const JBig2TableLine* pTable) {
33ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  PREFLEN.resize(NTEMP);
34ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  RANGELEN.resize(NTEMP);
35ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  RANGELOW.resize(NTEMP);
36ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  for (FX_DWORD i = 0; i < NTEMP; ++i) {
37ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    PREFLEN[i] = pTable[i].PREFLEN;
38ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    RANGELEN[i] = pTable[i].RANDELEN;
39ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    RANGELOW[i] = pTable[i].RANGELOW;
40ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
41ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  InitCodes();
42e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
43ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
44ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannbool CJBig2_HuffmanTable::ParseFromCodedBuffer(CJBig2_BitStream* pStream) {
45ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  unsigned char cTemp;
46ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (pStream->read1Byte(&cTemp) == -1)
47ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return false;
48ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
49ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  HTOOB = !!(cTemp & 0x01);
50ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  unsigned char HTPS = ((cTemp >> 1) & 0x07) + 1;
51ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  unsigned char HTRS = ((cTemp >> 4) & 0x07) + 1;
52ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  FX_DWORD HTLOW;
53ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  FX_DWORD HTHIGH;
54ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (pStream->readInteger(&HTLOW) == -1 ||
55ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      pStream->readInteger(&HTHIGH) == -1) {
56ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return false;
57ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
58ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
59ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  const int low = static_cast<int>(HTLOW);
60ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  const int high = static_cast<int>(HTHIGH);
61ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (low > high)
62ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return false;
63ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
64ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  ExtendBuffers(false);
65ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  int cur_low = low;
66ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  do {
67ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if ((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) ||
68ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) {
69ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      return false;
70ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
71ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    RANGELOW[NTEMP] = cur_low;
72ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    cur_low += (1 << RANGELEN[NTEMP]);
73ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    ExtendBuffers(true);
74ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  } while (cur_low < high);
75ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
76ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
77ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return false;
78ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
79ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  RANGELEN[NTEMP] = 32;
80ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  RANGELOW[NTEMP] = low - 1;
81ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  ExtendBuffers(true);
82ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
83ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
84ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return false;
85ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
86ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  RANGELEN[NTEMP] = 32;
87ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  RANGELOW[NTEMP] = high;
88ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  ExtendBuffers(true);
89ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
90ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (HTOOB) {
91ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
92ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      return false;
93ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
94ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    ++NTEMP;
95ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
96ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
97ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  InitCodes();
98ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  return true;
99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
101ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CJBig2_HuffmanTable::InitCodes() {
102ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  int lenmax = 0;
103ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  for (FX_DWORD i = 0; i < NTEMP; ++i)
104ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    lenmax = std::max(PREFLEN[i], lenmax);
105ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
106ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  CODES.resize(NTEMP);
107ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  std::vector<int> LENCOUNT(lenmax + 1);
108ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  std::vector<int> FIRSTCODE(lenmax + 1);
109ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  for (int len : PREFLEN)
110ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    ++LENCOUNT[len];
111ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
112ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  FIRSTCODE[0] = 0;
113ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  LENCOUNT[0] = 0;
114ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  for (int i = 1; i <= lenmax; ++i) {
115ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    FIRSTCODE[i] = (FIRSTCODE[i - 1] + LENCOUNT[i - 1]) << 1;
116ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    int CURCODE = FIRSTCODE[i];
117ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    for (FX_DWORD j = 0; j < NTEMP; ++j) {
118ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      if (PREFLEN[j] == i)
119ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann        CODES[j] = CURCODE++;
120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    }
121ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  }
122ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann}
123ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
124ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CJBig2_HuffmanTable::ExtendBuffers(bool increment) {
125ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (increment)
126ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    ++NTEMP;
127ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
128ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  size_t size = PREFLEN.size();
129ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if (NTEMP < size)
130ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    return;
131ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
132ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  size += 16;
133ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  ASSERT(NTEMP < size);
134ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  PREFLEN.resize(size);
135ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  RANGELEN.resize(size);
136ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  RANGELOW.resize(size);
137e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
138