Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
JBig2_HuffmanTable.cpp
Go to the documentation of this file.
1// Copyright 2014 The PDFium Authors
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 "core/fxcodec/jbig2/JBig2_HuffmanTable.h"
8
9#include <iterator>
10#include <limits>
11
12#include "core/fxcodec/jbig2/JBig2_BitStream.h"
13#include "core/fxcodec/jbig2/JBig2_Context.h"
14#include "core/fxcrt/fx_safe_types.h"
15#include "core/fxcrt/unowned_ptr_exclusion.h"
16#include "third_party/base/check.h"
17
18namespace {
19
20struct JBig2TableLine {
21 uint8_t PREFLEN;
22 uint8_t RANDELEN;
23 int32_t RANGELOW;
24};
25
26struct HuffmanTable {
27 bool HTOOB;
28 UNOWNED_PTR_EXCLUSION const JBig2TableLine* lines;
29 size_t size;
30};
31
32constexpr JBig2TableLine kTableLine1[] = {{1, 4, 0},
33 {2, 8, 16},
34 {3, 16, 272},
35 {0, 32, -1},
36 {3, 32, 65808}};
37
38constexpr JBig2TableLine kTableLine2[] = {{1, 0, 0}, {2, 0, 1}, {3, 0, 2},
39 {4, 3, 3}, {5, 6, 11}, {0, 32, -1},
40 {6, 32, 75}, {6, 0, 0}};
41
42constexpr JBig2TableLine kTableLine3[] = {
43 {8, 8, -256}, {1, 0, 0}, {2, 0, 1}, {3, 0, 2}, {4, 3, 3},
44 {5, 6, 11}, {8, 32, -257}, {7, 32, 75}, {6, 0, 0}};
45
46constexpr JBig2TableLine kTableLine4[] = {{1, 0, 1}, {2, 0, 2}, {3, 0, 3},
47 {4, 3, 4}, {5, 6, 12}, {0, 32, -1},
48 {5, 32, 76}};
49
50constexpr JBig2TableLine kTableLine5[] = {{7, 8, -255}, {1, 0, 1}, {2, 0, 2},
51 {3, 0, 3}, {4, 3, 4}, {5, 6, 12},
52 {7, 32, -256}, {6, 32, 76}};
53
54constexpr JBig2TableLine kTableLine6[] = {
55 {5, 10, -2048}, {4, 9, -1024}, {4, 8, -512}, {4, 7, -256}, {5, 6, -128},
56 {5, 5, -64}, {4, 5, -32}, {2, 7, 0}, {3, 7, 128}, {3, 8, 256},
57 {4, 9, 512}, {4, 10, 1024}, {6, 32, -2049}, {6, 32, 2048}};
58
59constexpr JBig2TableLine kTableLine7[] = {
60 {4, 9, -1024}, {3, 8, -512}, {4, 7, -256}, {5, 6, -128}, {5, 5, -64},
61 {4, 5, -32}, {4, 5, 0}, {5, 5, 32}, {5, 6, 64}, {4, 7, 128},
62 {3, 8, 256}, {3, 9, 512}, {3, 10, 1024}, {5, 32, -1025}, {5, 32, 2048}};
63
64constexpr JBig2TableLine kTableLine8[] = {
65 {8, 3, -15}, {9, 1, -7}, {8, 1, -5}, {9, 0, -3}, {7, 0, -2},
66 {4, 0, -1}, {2, 1, 0}, {5, 0, 2}, {6, 0, 3}, {3, 4, 4},
67 {6, 1, 20}, {4, 4, 22}, {4, 5, 38}, {5, 6, 70}, {5, 7, 134},
68 {6, 7, 262}, {7, 8, 390}, {6, 10, 646}, {9, 32, -16}, {9, 32, 1670},
69 {2, 0, 0}};
70
71constexpr JBig2TableLine kTableLine9[] = {
72 {8, 4, -31}, {9, 2, -15}, {8, 2, -11}, {9, 1, -7}, {7, 1, -5},
73 {4, 1, -3}, {3, 1, -1}, {3, 1, 1}, {5, 1, 3}, {6, 1, 5},
74 {3, 5, 7}, {6, 2, 39}, {4, 5, 43}, {4, 6, 75}, {5, 7, 139},
75 {5, 8, 267}, {6, 8, 523}, {7, 9, 779}, {6, 11, 1291}, {9, 32, -32},
76 {9, 32, 3339}, {2, 0, 0}};
77
78constexpr JBig2TableLine kTableLine10[] = {
79 {7, 4, -21}, {8, 0, -5}, {7, 0, -4}, {5, 0, -3}, {2, 2, -2},
80 {5, 0, 2}, {6, 0, 3}, {7, 0, 4}, {8, 0, 5}, {2, 6, 6},
81 {5, 5, 70}, {6, 5, 102}, {6, 6, 134}, {6, 7, 198}, {6, 8, 326},
82 {6, 9, 582}, {6, 10, 1094}, {7, 11, 2118}, {8, 32, -22}, {8, 32, 4166},
83 {2, 0, 0}};
84
85constexpr JBig2TableLine kTableLine11[] = {
86 {1, 0, 1}, {2, 1, 2}, {4, 0, 4}, {4, 1, 5}, {5, 1, 7},
87 {5, 2, 9}, {6, 2, 13}, {7, 2, 17}, {7, 3, 21}, {7, 4, 29},
88 {7, 5, 45}, {7, 6, 77}, {0, 32, 0}, {7, 32, 141}};
89
90constexpr JBig2TableLine kTableLine12[] = {
91 {1, 0, 1}, {2, 0, 2}, {3, 1, 3}, {5, 0, 5}, {5, 1, 6},
92 {6, 1, 8}, {7, 0, 10}, {7, 1, 11}, {7, 2, 13}, {7, 3, 17},
93 {7, 4, 25}, {8, 5, 41}, {0, 32, 0}, {8, 32, 73}};
94
95constexpr JBig2TableLine kTableLine13[] = {
96 {1, 0, 1}, {3, 0, 2}, {4, 0, 3}, {5, 0, 4}, {4, 1, 5},
97 {3, 3, 7}, {6, 1, 15}, {6, 2, 17}, {6, 3, 21}, {6, 4, 29},
98 {6, 5, 45}, {7, 6, 77}, {0, 32, 0}, {7, 32, 141}};
99
100constexpr JBig2TableLine kTableLine14[] = {{3, 0, -2}, {3, 0, -1}, {1, 0, 0},
101 {3, 0, 1}, {3, 0, 2}, {0, 32, -3},
102 {0, 32, 3}};
103
104constexpr JBig2TableLine kTableLine15[] = {
105 {7, 4, -24}, {6, 2, -8}, {5, 1, -4}, {4, 0, -2}, {3, 0, -1},
106 {1, 0, 0}, {3, 0, 1}, {4, 0, 2}, {5, 1, 3}, {6, 2, 5},
107 {7, 4, 9}, {7, 32, -25}, {7, 32, 25}};
108
109constexpr HuffmanTable kHuffmanTables[16] = {
110 {false, nullptr, 0}, // Zero dummy to preserve indexing.
111 {false, kTableLine1, std::size(kTableLine1)},
112 {true, kTableLine2, std::size(kTableLine2)},
113 {true, kTableLine3, std::size(kTableLine3)},
114 {false, kTableLine4, std::size(kTableLine4)},
115 {false, kTableLine5, std::size(kTableLine5)},
116 {false, kTableLine6, std::size(kTableLine6)},
117 {false, kTableLine7, std::size(kTableLine7)},
118 {true, kTableLine8, std::size(kTableLine8)},
119 {true, kTableLine9, std::size(kTableLine9)},
120 {true, kTableLine10, std::size(kTableLine10)},
121 {false, kTableLine11, std::size(kTableLine11)},
122 {false, kTableLine12, std::size(kTableLine12)},
123 {false, kTableLine13, std::size(kTableLine13)},
124 {false, kTableLine14, std::size(kTableLine14)},
125 {false, kTableLine15, std::size(kTableLine15)}};
126
127static_assert(CJBig2_HuffmanTable::kNumHuffmanTables ==
128 std::size(kHuffmanTables),
129 "kNumHuffmanTables must be equal to the size of kHuffmanTables");
130
131} // namespace
132
134 DCHECK(idx > 0);
135 DCHECK(idx < kNumHuffmanTables);
136 const HuffmanTable& table = kHuffmanTables[idx];
137 HTOOB = table.HTOOB;
138 NTEMP = pdfium::base::checked_cast<uint32_t>(table.size);
139 m_bOK = ParseFromStandardTable(idx);
140 DCHECK(m_bOK);
141}
142
144 : HTOOB(false), NTEMP(0) {
145 m_bOK = ParseFromCodedBuffer(pStream);
146}
147
149
150bool CJBig2_HuffmanTable::ParseFromStandardTable(size_t idx) {
151 const JBig2TableLine* pTable = kHuffmanTables[idx].lines;
152 CODES.resize(NTEMP);
153 RANGELEN.resize(NTEMP);
154 RANGELOW.resize(NTEMP);
155 for (uint32_t i = 0; i < NTEMP; ++i) {
156 CODES[i].codelen = pTable[i].PREFLEN;
157 RANGELEN[i] = pTable[i].RANDELEN;
158 RANGELOW[i] = pTable[i].RANGELOW;
159 }
160 return CJBig2_Context::HuffmanAssignCode(CODES.data(), NTEMP);
161}
162
163bool CJBig2_HuffmanTable::ParseFromCodedBuffer(CJBig2_BitStream* pStream) {
164 unsigned char cTemp;
165 if (pStream->read1Byte(&cTemp) == -1)
166 return false;
167
168 HTOOB = !!(cTemp & 0x01);
169 unsigned char HTPS = ((cTemp >> 1) & 0x07) + 1;
170 unsigned char HTRS = ((cTemp >> 4) & 0x07) + 1;
171 uint32_t HTLOW;
172 uint32_t HTHIGH;
173 if (pStream->readInteger(&HTLOW) == -1 ||
174 pStream->readInteger(&HTHIGH) == -1) {
175 return false;
176 }
177
178 const int low = static_cast<int>(HTLOW);
179 const int high = static_cast<int>(HTHIGH);
180 if (low > high)
181 return false;
182
183 ExtendBuffers(false);
184 FX_SAFE_INT32 cur_low = low;
185 do {
186 if ((pStream->readNBits(HTPS, &CODES[NTEMP].codelen) == -1) ||
187 (pStream->readNBits(HTRS, &RANGELEN[NTEMP]) == -1) ||
188 (static_cast<size_t>(RANGELEN[NTEMP]) >= 8 * sizeof(cur_low))) {
189 return false;
190 }
191 RANGELOW[NTEMP] = cur_low.ValueOrDie();
192
193 if (RANGELEN[NTEMP] >= 32)
194 return false;
195
196 cur_low += (1 << RANGELEN[NTEMP]);
197 if (!cur_low.IsValid())
198 return false;
199 ExtendBuffers(true);
200 } while (cur_low.ValueOrDie() < high);
201
202 if (pStream->readNBits(HTPS, &CODES[NTEMP].codelen) == -1)
203 return false;
204
205 RANGELEN[NTEMP] = 32;
206 if (low == std::numeric_limits<int>::min())
207 return false;
208
209 RANGELOW[NTEMP] = low - 1;
210 ExtendBuffers(true);
211
212 if (pStream->readNBits(HTPS, &CODES[NTEMP].codelen) == -1)
213 return false;
214
215 RANGELEN[NTEMP] = 32;
216 RANGELOW[NTEMP] = high;
217 ExtendBuffers(true);
218
219 if (HTOOB) {
220 if (pStream->readNBits(HTPS, &CODES[NTEMP].codelen) == -1)
221 return false;
222
223 ++NTEMP;
224 }
225
226 return CJBig2_Context::HuffmanAssignCode(CODES.data(), NTEMP);
227}
228
229void CJBig2_HuffmanTable::ExtendBuffers(bool increment) {
230 if (increment)
231 ++NTEMP;
232
233 size_t size = CODES.size();
234 if (NTEMP < size)
235 return;
236
237 size += 16;
238 DCHECK(NTEMP < size);
239 CODES.resize(size);
240 RANGELEN.resize(size);
241 RANGELOW.resize(size);
242}
int32_t readInteger(uint32_t *dwResult)
int32_t read1Byte(uint8_t *cResult)
CJBig2_HuffmanTable(CJBig2_BitStream *pStream)
#define UNOWNED_PTR_EXCLUSION