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