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