1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved. 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file. 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "JBig2_HuffmanTable.h" 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "JBig2_BitStream.h" 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <string.h> 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCJBig2_HuffmanTable::CJBig2_HuffmanTable(const JBig2TableLine *pTable, int nLines, 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_BOOL bHTOOB) 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov init(); 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_bOK = parseFromStandardTable(pTable, nLines, bHTOOB); 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream *pStream) 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov init(); 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_bOK = parseFromCodedBuffer(pStream); 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCJBig2_HuffmanTable::~CJBig2_HuffmanTable() 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(CODES) { 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pModule->JBig2_Free(CODES); 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(PREFLEN) { 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pModule->JBig2_Free(PREFLEN); 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(RANGELEN) { 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pModule->JBig2_Free(RANGELEN); 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(RANGELOW) { 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pModule->JBig2_Free(RANGELOW); 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CJBig2_HuffmanTable::init() 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov HTOOB = FALSE; 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NTEMP = 0; 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CODES = NULL; 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PREFLEN = NULL; 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELEN = NULL; 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELOW = NULL; 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CJBig2_HuffmanTable::parseFromStandardTable(const JBig2TableLine *pTable, int nLines, FX_BOOL bHTOOB) 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int CURLEN, LENMAX, CURCODE, CURTEMP, i; 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int *LENCOUNT; 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int *FIRSTCODE; 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov HTOOB = bHTOOB; 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NTEMP = nLines; 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP); 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PREFLEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP); 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP); 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP); 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LENMAX = 0; 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for(i = 0; i < NTEMP; i++) { 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PREFLEN[i] = pTable[i].PREFLEN; 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELEN[i] = pTable[i].RANDELEN; 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELOW[i] = pTable[i].RANGELOW; 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(PREFLEN[i] > LENMAX) { 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LENMAX = PREFLEN[i]; 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for(i = 0; i < NTEMP; i++) { 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LENCOUNT[PREFLEN[i]] ++; 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURLEN = 1; 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIRSTCODE[0] = 0; 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LENCOUNT[0] = 0; 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(CURLEN <= LENMAX) { 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURCODE = FIRSTCODE[CURLEN]; 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURTEMP = 0; 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(CURTEMP < NTEMP) { 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(PREFLEN[CURTEMP] == CURLEN) { 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CODES[CURTEMP] = CURCODE; 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURCODE = CURCODE + 1; 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURTEMP = CURTEMP + 1; 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURLEN = CURLEN + 1; 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pModule->JBig2_Free(LENCOUNT); 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pModule->JBig2_Free(FIRSTCODE); 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 1; 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define HT_CHECK_MEMORY_ADJUST \ 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(NTEMP >= nSize) \ 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { \ 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nSize += 16; \ 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PREFLEN = (int*)m_pModule->JBig2_Realloc(PREFLEN,sizeof(int)*nSize); \ 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELEN = (int*)m_pModule->JBig2_Realloc(RANGELEN,sizeof(int)*nSize); \ 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELOW = (int*)m_pModule->JBig2_Realloc(RANGELOW,sizeof(int)*nSize); \ 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CJBig2_HuffmanTable::parseFromCodedBuffer(CJBig2_BitStream *pStream) 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned char HTPS, HTRS; 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int HTLOW, HTHIGH; 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int CURRANGELOW; 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int nSize = 16; 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int CURLEN, LENMAX, CURCODE, CURTEMP, i; 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int *LENCOUNT; 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int *FIRSTCODE; 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned char cTemp; 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(pStream->read1Byte(&cTemp) == -1) { 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto failed; 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov HTOOB = cTemp & 0x01; 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov HTPS = ((cTemp >> 1) & 0x07) + 1; 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov HTRS = ((cTemp >> 4) & 0x07) + 1; 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(pStream->readInteger((FX_DWORD*)&HTLOW) == -1 || 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pStream->readInteger((FX_DWORD*)&HTHIGH) == -1) { 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto failed; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PREFLEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize); 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize); 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize); 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURRANGELOW = HTLOW; 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NTEMP = 0; 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do { 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov HT_CHECK_MEMORY_ADJUST 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov || (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) { 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto failed; 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELOW[NTEMP] = CURRANGELOW; 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURRANGELOW = CURRANGELOW + (1 << RANGELEN[NTEMP]); 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NTEMP = NTEMP + 1; 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while(CURRANGELOW < HTHIGH); 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov HT_CHECK_MEMORY_ADJUST 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) { 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto failed; 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELEN[NTEMP] = 32; 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELOW[NTEMP] = HTLOW - 1; 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NTEMP = NTEMP + 1; 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov HT_CHECK_MEMORY_ADJUST 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) { 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto failed; 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELEN[NTEMP] = 32; 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov RANGELOW[NTEMP] = HTHIGH; 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NTEMP = NTEMP + 1; 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(HTOOB) { 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov HT_CHECK_MEMORY_ADJUST 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) { 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto failed; 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NTEMP = NTEMP + 1; 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP); 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LENMAX = 0; 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for(i = 0; i < NTEMP; i++) { 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(PREFLEN[i] > LENMAX) { 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LENMAX = PREFLEN[i]; 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1)); 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for(i = 0; i < NTEMP; i++) { 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LENCOUNT[PREFLEN[i]] ++; 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURLEN = 1; 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIRSTCODE[0] = 0; 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LENCOUNT[0] = 0; 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(CURLEN <= LENMAX) { 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURCODE = FIRSTCODE[CURLEN]; 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURTEMP = 0; 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(CURTEMP < NTEMP) { 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(PREFLEN[CURTEMP] == CURLEN) { 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CODES[CURTEMP] = CURCODE; 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURCODE = CURCODE + 1; 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURTEMP = CURTEMP + 1; 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CURLEN = CURLEN + 1; 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pModule->JBig2_Free(LENCOUNT); 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_pModule->JBig2_Free(FIRSTCODE); 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovfailed: 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 194