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