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
CJBig2_HuffmanTable(const JBig2TableLine * pTable,int nLines,FX_BOOL bHTOOB)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
CJBig2_HuffmanTable(CJBig2_BitStream * pStream)18 CJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream *pStream)
19 {
20 init();
21 m_bOK = parseFromCodedBuffer(pStream);
22 }
23
~CJBig2_HuffmanTable()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 }
init()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 }
parseFromStandardTable(const JBig2TableLine * pTable,int nLines,FX_BOOL bHTOOB)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 }
parseFromCodedBuffer(CJBig2_BitStream * pStream)103 int CJBig2_HuffmanTable::parseFromCodedBuffer(CJBig2_BitStream *pStream)
104 {
105 unsigned char HTPS, HTRS;
106 FX_DWORD HTLOW, HTHIGH;
107 FX_DWORD CURRANGELOW;
108 FX_DWORD nSize = 16;
109 int CURLEN, LENMAX, CURCODE, CURTEMP;
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(&HTLOW) == -1 ||
120 pStream->readInteger(&HTHIGH) == -1 ||
121 HTLOW > HTHIGH) {
122 goto failed;
123 }
124 PREFLEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
125 RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
126 RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
127 CURRANGELOW = HTLOW;
128 NTEMP = 0;
129 do {
130 HT_CHECK_MEMORY_ADJUST
131 if((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) ||
132 (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) {
133 goto failed;
134 }
135 RANGELOW[NTEMP] = CURRANGELOW;
136 CURRANGELOW = CURRANGELOW + (1 << RANGELEN[NTEMP]);
137 NTEMP = NTEMP + 1;
138 } while(CURRANGELOW < HTHIGH);
139 HT_CHECK_MEMORY_ADJUST
140 if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
141 goto failed;
142 }
143 RANGELEN[NTEMP] = 32;
144 RANGELOW[NTEMP] = HTLOW - 1;
145 NTEMP = NTEMP + 1;
146 HT_CHECK_MEMORY_ADJUST
147 if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
148 goto failed;
149 }
150 RANGELEN[NTEMP] = 32;
151 RANGELOW[NTEMP] = HTHIGH;
152 NTEMP = NTEMP + 1;
153 if(HTOOB) {
154 HT_CHECK_MEMORY_ADJUST
155 if(pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
156 goto failed;
157 }
158 NTEMP = NTEMP + 1;
159 }
160 CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
161 LENMAX = 0;
162 for(int i = 0; i < NTEMP; i++) {
163 if(PREFLEN[i] > LENMAX) {
164 LENMAX = PREFLEN[i];
165 }
166 }
167 LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
168 JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));
169 FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
170 for(int i = 0; i < NTEMP; i++) {
171 LENCOUNT[PREFLEN[i]] ++;
172 }
173 CURLEN = 1;
174 FIRSTCODE[0] = 0;
175 LENCOUNT[0] = 0;
176 while(CURLEN <= LENMAX) {
177 FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;
178 CURCODE = FIRSTCODE[CURLEN];
179 CURTEMP = 0;
180 while(CURTEMP < NTEMP) {
181 if(PREFLEN[CURTEMP] == CURLEN) {
182 CODES[CURTEMP] = CURCODE;
183 CURCODE = CURCODE + 1;
184 }
185 CURTEMP = CURTEMP + 1;
186 }
187 CURLEN = CURLEN + 1;
188 }
189 m_pModule->JBig2_Free(LENCOUNT);
190 m_pModule->JBig2_Free(FIRSTCODE);
191 return TRUE;
192 failed:
193 return FALSE;
194 }
195