summaryrefslogtreecommitdiff
path: root/core/fxcodec/jbig2/JBig2_HuffmanTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxcodec/jbig2/JBig2_HuffmanTable.cpp')
-rw-r--r--core/fxcodec/jbig2/JBig2_HuffmanTable.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/core/fxcodec/jbig2/JBig2_HuffmanTable.cpp b/core/fxcodec/jbig2/JBig2_HuffmanTable.cpp
new file mode 100644
index 0000000000..f4a838eb24
--- /dev/null
+++ b/core/fxcodec/jbig2/JBig2_HuffmanTable.cpp
@@ -0,0 +1,136 @@
+// 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_HuffmanTable.h"
+
+#include <algorithm>
+#include <vector>
+
+#include "core/fxcodec/jbig2/JBig2_BitStream.h"
+#include "core/fxcodec/jbig2/JBig2_Define.h"
+#include "core/fxcodec/jbig2/JBig2_HuffmanTable_Standard.h"
+#include "core/include/fxcrt/fx_memory.h"
+
+CJBig2_HuffmanTable::CJBig2_HuffmanTable(const JBig2TableLine* pTable,
+ FX_DWORD nLines,
+ bool bHTOOB)
+ : m_bOK(true), HTOOB(bHTOOB), NTEMP(nLines) {
+ ParseFromStandardTable(pTable);
+}
+
+CJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream* pStream)
+ : HTOOB(false), NTEMP(0) {
+ m_bOK = ParseFromCodedBuffer(pStream);
+}
+
+CJBig2_HuffmanTable::~CJBig2_HuffmanTable() {}
+
+void CJBig2_HuffmanTable::ParseFromStandardTable(const JBig2TableLine* pTable) {
+ PREFLEN.resize(NTEMP);
+ RANGELEN.resize(NTEMP);
+ RANGELOW.resize(NTEMP);
+ for (FX_DWORD i = 0; i < NTEMP; ++i) {
+ PREFLEN[i] = pTable[i].PREFLEN;
+ RANGELEN[i] = pTable[i].RANDELEN;
+ RANGELOW[i] = pTable[i].RANGELOW;
+ }
+ InitCodes();
+}
+
+bool 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;
+
+ ExtendBuffers(false);
+ int cur_low = low;
+ do {
+ if ((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) ||
+ (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) {
+ return false;
+ }
+ RANGELOW[NTEMP] = cur_low;
+ cur_low += (1 << RANGELEN[NTEMP]);
+ ExtendBuffers(true);
+ } while (cur_low < high);
+
+ if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
+ return false;
+
+ RANGELEN[NTEMP] = 32;
+ RANGELOW[NTEMP] = low - 1;
+ ExtendBuffers(true);
+
+ if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
+ return false;
+
+ RANGELEN[NTEMP] = 32;
+ RANGELOW[NTEMP] = high;
+ ExtendBuffers(true);
+
+ if (HTOOB) {
+ if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1)
+ return false;
+
+ ++NTEMP;
+ }
+
+ InitCodes();
+ return true;
+}
+
+void CJBig2_HuffmanTable::InitCodes() {
+ int lenmax = 0;
+ for (FX_DWORD i = 0; i < NTEMP; ++i)
+ lenmax = std::max(PREFLEN[i], lenmax);
+
+ CODES.resize(NTEMP);
+ std::vector<int> LENCOUNT(lenmax + 1);
+ std::vector<int> FIRSTCODE(lenmax + 1);
+ for (int len : PREFLEN)
+ ++LENCOUNT[len];
+
+ FIRSTCODE[0] = 0;
+ LENCOUNT[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++;
+ }
+ }
+}
+
+void CJBig2_HuffmanTable::ExtendBuffers(bool increment) {
+ if (increment)
+ ++NTEMP;
+
+ size_t size = PREFLEN.size();
+ if (NTEMP < size)
+ return;
+
+ size += 16;
+ ASSERT(NTEMP < size);
+ PREFLEN.resize(size);
+ RANGELEN.resize(size);
+ RANGELOW.resize(size);
+}