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