0a5bc8e6459b8db1e9a35c5d5222c9b336b78ac6
[pdfium.git] / core / src / fxcodec / jbig2 / JBig2_HuffmanTable.cpp
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 }