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