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