clang-format all pdfium code.
[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,
12                                          int nLines,
13                                          FX_BOOL bHTOOB) {
14   init();
15   m_bOK = parseFromStandardTable(pTable, nLines, bHTOOB);
16 }
17
18 CJBig2_HuffmanTable::CJBig2_HuffmanTable(CJBig2_BitStream* pStream) {
19   init();
20   m_bOK = parseFromCodedBuffer(pStream);
21 }
22
23 CJBig2_HuffmanTable::~CJBig2_HuffmanTable() {
24   if (CODES) {
25     m_pModule->JBig2_Free(CODES);
26   }
27   if (PREFLEN) {
28     m_pModule->JBig2_Free(PREFLEN);
29   }
30   if (RANGELEN) {
31     m_pModule->JBig2_Free(RANGELEN);
32   }
33   if (RANGELOW) {
34     m_pModule->JBig2_Free(RANGELOW);
35   }
36 }
37 void CJBig2_HuffmanTable::init() {
38   HTOOB = FALSE;
39   NTEMP = 0;
40   CODES = NULL;
41   PREFLEN = NULL;
42   RANGELEN = NULL;
43   RANGELOW = NULL;
44 }
45 int CJBig2_HuffmanTable::parseFromStandardTable(const JBig2TableLine* pTable,
46                                                 int nLines,
47                                                 FX_BOOL bHTOOB) {
48   int CURLEN, LENMAX, CURCODE, CURTEMP, i;
49   int* LENCOUNT;
50   int* FIRSTCODE;
51   HTOOB = bHTOOB;
52   NTEMP = nLines;
53   CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
54   PREFLEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
55   RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
56   RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
57   LENMAX = 0;
58   for (i = 0; i < NTEMP; i++) {
59     PREFLEN[i] = pTable[i].PREFLEN;
60     RANGELEN[i] = pTable[i].RANDELEN;
61     RANGELOW[i] = pTable[i].RANGELOW;
62     if (PREFLEN[i] > LENMAX) {
63       LENMAX = PREFLEN[i];
64     }
65   }
66   LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
67   JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));
68   FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
69   for (i = 0; i < NTEMP; i++) {
70     LENCOUNT[PREFLEN[i]]++;
71   }
72   CURLEN = 1;
73   FIRSTCODE[0] = 0;
74   LENCOUNT[0] = 0;
75   while (CURLEN <= LENMAX) {
76     FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;
77     CURCODE = FIRSTCODE[CURLEN];
78     CURTEMP = 0;
79     while (CURTEMP < NTEMP) {
80       if (PREFLEN[CURTEMP] == CURLEN) {
81         CODES[CURTEMP] = CURCODE;
82         CURCODE = CURCODE + 1;
83       }
84       CURTEMP = CURTEMP + 1;
85     }
86     CURLEN = CURLEN + 1;
87   }
88   m_pModule->JBig2_Free(LENCOUNT);
89   m_pModule->JBig2_Free(FIRSTCODE);
90   return 1;
91 }
92
93 #define HT_CHECK_MEMORY_ADJUST                                                \
94   if (NTEMP >= nSize) {                                                       \
95     nSize += 16;                                                              \
96     PREFLEN = (int*)m_pModule->JBig2_Realloc(PREFLEN, sizeof(int) * nSize);   \
97     RANGELEN = (int*)m_pModule->JBig2_Realloc(RANGELEN, sizeof(int) * nSize); \
98     RANGELOW = (int*)m_pModule->JBig2_Realloc(RANGELOW, sizeof(int) * nSize); \
99   }
100 int CJBig2_HuffmanTable::parseFromCodedBuffer(CJBig2_BitStream* pStream) {
101   unsigned char HTPS, HTRS;
102   FX_DWORD HTLOW, HTHIGH;
103   FX_DWORD CURRANGELOW;
104   FX_DWORD nSize = 16;
105   int CURLEN, LENMAX, CURCODE, CURTEMP;
106   int* LENCOUNT;
107   int* FIRSTCODE;
108   unsigned char cTemp;
109   if (pStream->read1Byte(&cTemp) == -1) {
110     goto failed;
111   }
112   HTOOB = cTemp & 0x01;
113   HTPS = ((cTemp >> 1) & 0x07) + 1;
114   HTRS = ((cTemp >> 4) & 0x07) + 1;
115   if (pStream->readInteger(&HTLOW) == -1 ||
116       pStream->readInteger(&HTHIGH) == -1 || HTLOW > HTHIGH) {
117     goto failed;
118   }
119   PREFLEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
120   RANGELEN = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
121   RANGELOW = (int*)m_pModule->JBig2_Malloc2(sizeof(int), nSize);
122   CURRANGELOW = HTLOW;
123   NTEMP = 0;
124   do {
125     HT_CHECK_MEMORY_ADJUST
126     if ((pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) ||
127         (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1)) {
128       goto failed;
129     }
130     RANGELOW[NTEMP] = CURRANGELOW;
131     CURRANGELOW = CURRANGELOW + (1 << RANGELEN[NTEMP]);
132     NTEMP = NTEMP + 1;
133   } while (CURRANGELOW < HTHIGH);
134   HT_CHECK_MEMORY_ADJUST
135   if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
136     goto failed;
137   }
138   RANGELEN[NTEMP] = 32;
139   RANGELOW[NTEMP] = HTLOW - 1;
140   NTEMP = NTEMP + 1;
141   HT_CHECK_MEMORY_ADJUST
142   if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
143     goto failed;
144   }
145   RANGELEN[NTEMP] = 32;
146   RANGELOW[NTEMP] = HTHIGH;
147   NTEMP = NTEMP + 1;
148   if (HTOOB) {
149     HT_CHECK_MEMORY_ADJUST
150     if (pStream->readNBits(HTPS, &PREFLEN[NTEMP]) == -1) {
151       goto failed;
152     }
153     NTEMP = NTEMP + 1;
154   }
155   CODES = (int*)m_pModule->JBig2_Malloc2(sizeof(int), NTEMP);
156   LENMAX = 0;
157   for (int i = 0; i < NTEMP; i++) {
158     if (PREFLEN[i] > LENMAX) {
159       LENMAX = PREFLEN[i];
160     }
161   }
162   LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
163   JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));
164   FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
165   for (int i = 0; i < NTEMP; i++) {
166     LENCOUNT[PREFLEN[i]]++;
167   }
168   CURLEN = 1;
169   FIRSTCODE[0] = 0;
170   LENCOUNT[0] = 0;
171   while (CURLEN <= LENMAX) {
172     FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;
173     CURCODE = FIRSTCODE[CURLEN];
174     CURTEMP = 0;
175     while (CURTEMP < NTEMP) {
176       if (PREFLEN[CURTEMP] == CURLEN) {
177         CODES[CURTEMP] = CURCODE;
178         CURCODE = CURCODE + 1;
179       }
180       CURTEMP = CURTEMP + 1;
181     }
182     CURLEN = CURLEN + 1;
183   }
184   m_pModule->JBig2_Free(LENCOUNT);
185   m_pModule->JBig2_Free(FIRSTCODE);
186   return TRUE;
187 failed:
188   return FALSE;
189 }