| // 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; |
| } |