// 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 "JBig2_BitStream.h" | |
#include <string.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() | |
{ | |
if(CODES) { | |
m_pModule->JBig2_Free(CODES); | |
} | |
if(PREFLEN) { | |
m_pModule->JBig2_Free(PREFLEN); | |
} | |
if(RANGELEN) { | |
m_pModule->JBig2_Free(RANGELEN); | |
} | |
if(RANGELOW) { | |
m_pModule->JBig2_Free(RANGELOW); | |
} | |
} | |
void CJBig2_HuffmanTable::init() | |
{ | |
HTOOB = FALSE; | |
NTEMP = 0; | |
CODES = NULL; | |
PREFLEN = NULL; | |
RANGELEN = NULL; | |
RANGELOW = NULL; | |
} | |
int CJBig2_HuffmanTable::parseFromStandardTable(const JBig2TableLine *pTable, int nLines, FX_BOOL bHTOOB) | |
{ | |
int CURLEN, LENMAX, CURCODE, CURTEMP, i; | |
int *LENCOUNT; | |
int *FIRSTCODE; | |
HTOOB = bHTOOB; | |
NTEMP = nLines; | |
CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP); | |
PREFLEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP); | |
RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP); | |
RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP); | |
LENMAX = 0; | |
for(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]; | |
} | |
} | |
LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); | |
JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); | |
FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); | |
for(i = 0; i < NTEMP; i++) { | |
LENCOUNT[PREFLEN[i]] ++; | |
} | |
CURLEN = 1; | |
FIRSTCODE[0] = 0; | |
LENCOUNT[0] = 0; | |
while(CURLEN <= LENMAX) { | |
FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; | |
CURCODE = FIRSTCODE[CURLEN]; | |
CURTEMP = 0; | |
while(CURTEMP < NTEMP) { | |
if(PREFLEN[CURTEMP] == CURLEN) { | |
CODES[CURTEMP] = CURCODE; | |
CURCODE = CURCODE + 1; | |
} | |
CURTEMP = CURTEMP + 1; | |
} | |
CURLEN = CURLEN + 1; | |
} | |
m_pModule->JBig2_Free(LENCOUNT); | |
m_pModule->JBig2_Free(FIRSTCODE); | |
return 1; | |
} | |
#define HT_CHECK_MEMORY_ADJUST \ | |
if(NTEMP >= nSize) \ | |
{ \ | |
nSize += 16; \ | |
PREFLEN = (int*)m_pModule->JBig2_Realloc(PREFLEN,sizeof(int)*nSize); \ | |
RANGELEN = (int*)m_pModule->JBig2_Realloc(RANGELEN,sizeof(int)*nSize); \ | |
RANGELOW = (int*)m_pModule->JBig2_Realloc(RANGELOW,sizeof(int)*nSize); \ | |
} | |
int CJBig2_HuffmanTable::parseFromCodedBuffer(CJBig2_BitStream *pStream) | |
{ | |
unsigned char HTPS, HTRS; | |
int HTLOW, HTHIGH; | |
int CURRANGELOW; | |
int nSize = 16; | |
int CURLEN, LENMAX, CURCODE, CURTEMP, i; | |
int *LENCOUNT; | |
int *FIRSTCODE; | |
unsigned char cTemp; | |
if(pStream->read1Byte(&cTemp) == -1) { | |
goto failed; | |
} | |
HTOOB = cTemp & 0x01; | |
HTPS = ((cTemp >> 1) & 0x07) + 1; | |
HTRS = ((cTemp >> 4) & 0x07) + 1; | |
if(pStream->readInteger((FX_DWORD*)&HTLOW) == -1 || | |
pStream->readInteger((FX_DWORD*)&HTHIGH) == -1) { | |
goto failed; | |
} | |
PREFLEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize); | |
RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize); | |
RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize); | |
CURRANGELOW = HTLOW; | |
NTEMP = 0; | |
do { | |
HT_CHECK_MEMORY_ADJUST | |
if((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) | |
|| (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) { | |
goto failed; | |
} | |
RANGELOW[NTEMP] = CURRANGELOW; | |
CURRANGELOW = CURRANGELOW + (1 << RANGELEN[NTEMP]); | |
NTEMP = NTEMP + 1; | |
} while(CURRANGELOW < HTHIGH); | |
HT_CHECK_MEMORY_ADJUST | |
if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) { | |
goto failed; | |
} | |
RANGELEN[NTEMP] = 32; | |
RANGELOW[NTEMP] = HTLOW - 1; | |
NTEMP = NTEMP + 1; | |
HT_CHECK_MEMORY_ADJUST | |
if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) { | |
goto failed; | |
} | |
RANGELEN[NTEMP] = 32; | |
RANGELOW[NTEMP] = HTHIGH; | |
NTEMP = NTEMP + 1; | |
if(HTOOB) { | |
HT_CHECK_MEMORY_ADJUST | |
if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) { | |
goto failed; | |
} | |
NTEMP = NTEMP + 1; | |
} | |
CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP); | |
LENMAX = 0; | |
for(i = 0; i < NTEMP; i++) { | |
if(PREFLEN[i] > LENMAX) { | |
LENMAX = PREFLEN[i]; | |
} | |
} | |
LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); | |
JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); | |
FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); | |
for(i = 0; i < NTEMP; i++) { | |
LENCOUNT[PREFLEN[i]] ++; | |
} | |
CURLEN = 1; | |
FIRSTCODE[0] = 0; | |
LENCOUNT[0] = 0; | |
while(CURLEN <= LENMAX) { | |
FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; | |
CURCODE = FIRSTCODE[CURLEN]; | |
CURTEMP = 0; | |
while(CURTEMP < NTEMP) { | |
if(PREFLEN[CURTEMP] == CURLEN) { | |
CODES[CURTEMP] = CURCODE; | |
CURCODE = CURCODE + 1; | |
} | |
CURTEMP = CURTEMP + 1; | |
} | |
CURLEN = CURLEN + 1; | |
} | |
m_pModule->JBig2_Free(LENCOUNT); | |
m_pModule->JBig2_Free(FIRSTCODE); | |
return TRUE; | |
failed: | |
return FALSE; | |
} |