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_SddProc.cpp
Go to the documentation of this file.
1// Copyright 2015 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_SddProc.h"
8
9#include <stddef.h>
10
11#include <algorithm>
12#include <memory>
13#include <utility>
14#include <vector>
15
16#include "core/fxcodec/jbig2/JBig2_ArithIntDecoder.h"
17#include "core/fxcodec/jbig2/JBig2_GrdProc.h"
18#include "core/fxcodec/jbig2/JBig2_GrrdProc.h"
19#include "core/fxcodec/jbig2/JBig2_HuffmanDecoder.h"
20#include "core/fxcodec/jbig2/JBig2_HuffmanTable.h"
21#include "core/fxcodec/jbig2/JBig2_SymbolDict.h"
22#include "core/fxcodec/jbig2/JBig2_TrdProc.h"
23#include "core/fxcrt/fx_memcpy_wrappers.h"
24#include "core/fxcrt/fx_safe_types.h"
25#include "core/fxcrt/stl_util.h"
26
28
29CJBig2_SDDProc::~CJBig2_SDDProc() = default;
30
32 CJBig2_ArithDecoder* pArithDecoder,
33 pdfium::span<JBig2ArithCtx> gbContexts,
34 pdfium::span<JBig2ArithCtx> grContexts) {
35 auto IADH = std::make_unique<CJBig2_ArithIntDecoder>();
36 auto IADW = std::make_unique<CJBig2_ArithIntDecoder>();
37 auto IAAI = std::make_unique<CJBig2_ArithIntDecoder>();
38 auto IARDX = std::make_unique<CJBig2_ArithIntDecoder>();
39 auto IARDY = std::make_unique<CJBig2_ArithIntDecoder>();
40 auto IAEX = std::make_unique<CJBig2_ArithIntDecoder>();
41 auto IADT = std::make_unique<CJBig2_ArithIntDecoder>();
42 auto IAFS = std::make_unique<CJBig2_ArithIntDecoder>();
43 auto IADS = std::make_unique<CJBig2_ArithIntDecoder>();
44 auto IAIT = std::make_unique<CJBig2_ArithIntDecoder>();
45 auto IARI = std::make_unique<CJBig2_ArithIntDecoder>();
46 auto IARDW = std::make_unique<CJBig2_ArithIntDecoder>();
47 auto IARDH = std::make_unique<CJBig2_ArithIntDecoder>();
48
49 uint32_t SBSYMCODELENA = 0;
50 while ((uint32_t)(1 << SBSYMCODELENA) < (SDNUMINSYMS + SDNUMNEWSYMS)) {
51 SBSYMCODELENA++;
52 }
53 auto IAID = std::make_unique<CJBig2_ArithIaidDecoder>((uint8_t)SBSYMCODELENA);
54
55 std::vector<std::unique_ptr<CJBig2_Image>> SDNEWSYMS(SDNUMNEWSYMS);
56 uint32_t HCHEIGHT = 0;
57 uint32_t NSYMSDECODED = 0;
58 while (NSYMSDECODED < SDNUMNEWSYMS) {
59 std::unique_ptr<CJBig2_Image> BS;
60 int32_t HCDH;
61 IADH->Decode(pArithDecoder, &HCDH);
62 HCHEIGHT = HCHEIGHT + HCDH;
63 if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > kJBig2MaxImageSize)
64 return nullptr;
65
66 uint32_t SYMWIDTH = 0;
67 for (;;) {
68 int32_t DW;
69 if (!IADW->Decode(pArithDecoder, &DW))
70 break;
71
72 if (NSYMSDECODED >= SDNUMNEWSYMS)
73 return nullptr;
74
75 SYMWIDTH = SYMWIDTH + DW;
76 if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > kJBig2MaxImageSize)
77 return nullptr;
78
79 if (HCHEIGHT == 0 || SYMWIDTH == 0) {
80 ++NSYMSDECODED;
81 continue;
82 }
83 if (SDREFAGG == 0) {
84 auto pGRD = std::make_unique<CJBig2_GRDProc>();
85 pGRD->MMR = false;
86 pGRD->GBW = SYMWIDTH;
87 pGRD->GBH = HCHEIGHT;
88 pGRD->GBTEMPLATE = SDTEMPLATE;
89 pGRD->TPGDON = false;
90 pGRD->USESKIP = false;
91 pGRD->GBAT[0] = SDAT[0];
92 pGRD->GBAT[1] = SDAT[1];
93 pGRD->GBAT[2] = SDAT[2];
94 pGRD->GBAT[3] = SDAT[3];
95 pGRD->GBAT[4] = SDAT[4];
96 pGRD->GBAT[5] = SDAT[5];
97 pGRD->GBAT[6] = SDAT[6];
98 pGRD->GBAT[7] = SDAT[7];
99 BS = pGRD->DecodeArith(pArithDecoder, gbContexts);
100 if (!BS)
101 return nullptr;
102 } else {
103 uint32_t REFAGGNINST;
104 IAAI->Decode(pArithDecoder, (int*)&REFAGGNINST);
105 if (REFAGGNINST > 1) {
106 // Huffman tables must not outlive |pDecoder|.
107 auto SBHUFFFS = std::make_unique<CJBig2_HuffmanTable>(6);
108 auto SBHUFFDS = std::make_unique<CJBig2_HuffmanTable>(8);
109 auto SBHUFFDT = std::make_unique<CJBig2_HuffmanTable>(11);
110 auto SBHUFFRDW = std::make_unique<CJBig2_HuffmanTable>(15);
111 auto SBHUFFRDH = std::make_unique<CJBig2_HuffmanTable>(15);
112 auto SBHUFFRDX = std::make_unique<CJBig2_HuffmanTable>(15);
113 auto SBHUFFRDY = std::make_unique<CJBig2_HuffmanTable>(15);
114 auto SBHUFFRSIZE = std::make_unique<CJBig2_HuffmanTable>(1);
115 auto pDecoder = std::make_unique<CJBig2_TRDProc>();
116 pDecoder->SBHUFF = SDHUFF;
117 pDecoder->SBREFINE = true;
118 pDecoder->SBW = SYMWIDTH;
119 pDecoder->SBH = HCHEIGHT;
120 pDecoder->SBNUMINSTANCES = REFAGGNINST;
121 pDecoder->SBSTRIPS = 1;
122 pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
123 uint32_t nTmp = 0;
124 while ((uint32_t)(1 << nTmp) < pDecoder->SBNUMSYMS) {
125 nTmp++;
126 }
127 uint8_t SBSYMCODELEN = (uint8_t)nTmp;
128 pDecoder->SBSYMCODELEN = SBSYMCODELEN;
129 std::vector<UnownedPtr<CJBig2_Image>> SBSYMS(pDecoder->SBNUMSYMS);
130 fxcrt::Copy(pdfium::make_span(SDINSYMS).first(SDNUMINSYMS),
131 pdfium::make_span(SBSYMS));
132 for (size_t i = 0; i < NSYMSDECODED; ++i) {
133 SBSYMS[i + SDNUMINSYMS] = SDNEWSYMS[i].get();
134 }
135 pDecoder->SBSYMS = std::move(SBSYMS);
136 pDecoder->SBDEFPIXEL = false;
137 pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
138 pDecoder->TRANSPOSED = false;
139 pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
140 pDecoder->SBDSOFFSET = 0;
141 pDecoder->SBHUFFFS = SBHUFFFS.get();
142 pDecoder->SBHUFFDS = SBHUFFDS.get();
143 pDecoder->SBHUFFDT = SBHUFFDT.get();
144 pDecoder->SBHUFFRDW = SBHUFFRDW.get();
145 pDecoder->SBHUFFRDH = SBHUFFRDH.get();
146 pDecoder->SBHUFFRDX = SBHUFFRDX.get();
147 pDecoder->SBHUFFRDY = SBHUFFRDY.get();
148 pDecoder->SBHUFFRSIZE = SBHUFFRSIZE.get();
149 pDecoder->SBRTEMPLATE = SDRTEMPLATE;
150 pDecoder->SBRAT[0] = SDRAT[0];
151 pDecoder->SBRAT[1] = SDRAT[1];
152 pDecoder->SBRAT[2] = SDRAT[2];
153 pDecoder->SBRAT[3] = SDRAT[3];
155 ids.IADT = IADT.get();
156 ids.IAFS = IAFS.get();
157 ids.IADS = IADS.get();
158 ids.IAIT = IAIT.get();
159 ids.IARI = IARI.get();
160 ids.IARDW = IARDW.get();
161 ids.IARDH = IARDH.get();
162 ids.IARDX = IARDX.get();
163 ids.IARDY = IARDY.get();
164 ids.IAID = IAID.get();
165 BS = pDecoder->DecodeArith(pArithDecoder, grContexts, &ids);
166 if (!BS)
167 return nullptr;
168 } else if (REFAGGNINST == 1) {
169 uint32_t SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
170 uint32_t IDI;
171 IAID->Decode(pArithDecoder, &IDI);
172 if (IDI >= SBNUMSYMS)
173 return nullptr;
174
175 CJBig2_Image* sbsyms_idi = GetImage(IDI, SDNEWSYMS);
176 if (!sbsyms_idi)
177 return nullptr;
178
179 int32_t RDXI;
180 int32_t RDYI;
181 IARDX->Decode(pArithDecoder, &RDXI);
182 IARDY->Decode(pArithDecoder, &RDYI);
183
184 auto pGRRD = std::make_unique<CJBig2_GRRDProc>();
185 pGRRD->GRW = SYMWIDTH;
186 pGRRD->GRH = HCHEIGHT;
187 pGRRD->GRTEMPLATE = SDRTEMPLATE;
188 pGRRD->GRREFERENCE = sbsyms_idi;
189 pGRRD->GRREFERENCEDX = RDXI;
190 pGRRD->GRREFERENCEDY = RDYI;
191 pGRRD->TPGRON = false;
192 pGRRD->GRAT[0] = SDRAT[0];
193 pGRRD->GRAT[1] = SDRAT[1];
194 pGRRD->GRAT[2] = SDRAT[2];
195 pGRRD->GRAT[3] = SDRAT[3];
196 BS = pGRRD->Decode(pArithDecoder, grContexts);
197 if (!BS)
198 return nullptr;
199 }
200 }
201 SDNEWSYMS[NSYMSDECODED] = std::move(BS);
202 ++NSYMSDECODED;
203 }
204 }
205
206 std::vector<bool> EXFLAGS;
207 EXFLAGS.resize(SDNUMINSYMS + SDNUMNEWSYMS);
208 bool CUREXFLAG = false;
209 uint32_t EXINDEX = 0;
210 uint32_t num_ex_syms = 0;
211 while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
212 uint32_t EXRUNLENGTH;
213 IAEX->Decode(pArithDecoder, (int*)&EXRUNLENGTH);
214 FX_SAFE_UINT32 new_ex_size = EXINDEX;
215 new_ex_size += EXRUNLENGTH;
216 if (!new_ex_size.IsValid() ||
217 new_ex_size.ValueOrDie() > SDNUMINSYMS + SDNUMNEWSYMS) {
218 return nullptr;
219 }
220
221 if (CUREXFLAG)
222 num_ex_syms += EXRUNLENGTH;
223 std::fill_n(EXFLAGS.begin() + EXINDEX, EXRUNLENGTH, CUREXFLAG);
224 EXINDEX = new_ex_size.ValueOrDie();
225 CUREXFLAG = !CUREXFLAG;
226 }
227 if (num_ex_syms > SDNUMEXSYMS)
228 return nullptr;
229
230 std::unique_ptr<CJBig2_SymbolDict> pDict =
231 std::make_unique<CJBig2_SymbolDict>();
232 for (uint32_t i = 0, j = 0; i < SDNUMINSYMS + SDNUMNEWSYMS; ++i) {
233 if (!EXFLAGS[i] || j >= SDNUMEXSYMS)
234 continue;
235 if (i < SDNUMINSYMS) {
236 pDict->AddImage(
237 UNSAFE_TODO(SDINSYMS[i] ? std::make_unique<CJBig2_Image>(*SDINSYMS[i])
238 : nullptr));
239 } else {
240 pDict->AddImage(std::move(SDNEWSYMS[i - SDNUMINSYMS]));
241 }
242 ++j;
243 }
244 return pDict;
245}
246
248 CJBig2_BitStream* pStream,
249 pdfium::span<JBig2ArithCtx> gbContexts,
250 pdfium::span<JBig2ArithCtx> grContexts) {
251 auto pHuffmanDecoder = std::make_unique<CJBig2_HuffmanDecoder>(pStream);
252 std::vector<std::unique_ptr<CJBig2_Image>> SDNEWSYMS(SDNUMNEWSYMS);
253 std::vector<uint32_t> SDNEWSYMWIDTHS;
254 if (SDREFAGG == 0)
255 SDNEWSYMWIDTHS.resize(SDNUMNEWSYMS);
256 uint32_t HCHEIGHT = 0;
257 uint32_t NSYMSDECODED = 0;
258 std::unique_ptr<CJBig2_Image> BS;
259 while (NSYMSDECODED < SDNUMNEWSYMS) {
260 int32_t HCDH;
261 if (pHuffmanDecoder->DecodeAValue(SDHUFFDH, &HCDH) != 0)
262 return nullptr;
263
264 HCHEIGHT = HCHEIGHT + HCDH;
265 if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > kJBig2MaxImageSize)
266 return nullptr;
267
268 uint32_t SYMWIDTH = 0;
269 uint32_t TOTWIDTH = 0;
270 uint32_t HCFIRSTSYM = NSYMSDECODED;
271 for (;;) {
272 int32_t DW;
273 int32_t nVal = pHuffmanDecoder->DecodeAValue(SDHUFFDW, &DW);
274 if (nVal == kJBig2OOB)
275 break;
276 if (nVal != 0)
277 return nullptr;
278 if (NSYMSDECODED >= SDNUMNEWSYMS)
279 return nullptr;
280
281 SYMWIDTH = SYMWIDTH + DW;
282 if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > kJBig2MaxImageSize)
283 return nullptr;
284
285 TOTWIDTH += SYMWIDTH;
286 if (HCHEIGHT == 0 || SYMWIDTH == 0) {
287 ++NSYMSDECODED;
288 continue;
289 }
290 if (SDREFAGG == 1) {
291 uint32_t REFAGGNINST;
292 if (pHuffmanDecoder->DecodeAValue(SDHUFFAGGINST, (int*)&REFAGGNINST) !=
293 0) {
294 return nullptr;
295 }
296 BS = nullptr;
297 if (REFAGGNINST > 1) {
298 // Huffman tables must outlive |pDecoder|.
299 auto SBHUFFFS = std::make_unique<CJBig2_HuffmanTable>(6);
300 auto SBHUFFDS = std::make_unique<CJBig2_HuffmanTable>(8);
301 auto SBHUFFDT = std::make_unique<CJBig2_HuffmanTable>(11);
302 auto SBHUFFRDW = std::make_unique<CJBig2_HuffmanTable>(15);
303 auto SBHUFFRDH = std::make_unique<CJBig2_HuffmanTable>(15);
304 auto SBHUFFRDX = std::make_unique<CJBig2_HuffmanTable>(15);
305 auto SBHUFFRDY = std::make_unique<CJBig2_HuffmanTable>(15);
306 auto SBHUFFRSIZE = std::make_unique<CJBig2_HuffmanTable>(1);
307 auto pDecoder = std::make_unique<CJBig2_TRDProc>();
308 pDecoder->SBHUFF = SDHUFF;
309 pDecoder->SBREFINE = true;
310 pDecoder->SBW = SYMWIDTH;
311 pDecoder->SBH = HCHEIGHT;
312 pDecoder->SBNUMINSTANCES = REFAGGNINST;
313 pDecoder->SBSTRIPS = 1;
314 pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
315 std::vector<JBig2HuffmanCode> SBSYMCODES(pDecoder->SBNUMSYMS);
316 uint32_t nTmp = 1;
317 while (static_cast<uint32_t>(1 << nTmp) < pDecoder->SBNUMSYMS)
318 ++nTmp;
319 for (uint32_t i = 0; i < pDecoder->SBNUMSYMS; ++i) {
320 SBSYMCODES[i].codelen = nTmp;
321 SBSYMCODES[i].code = i;
322 }
323 pDecoder->SBSYMCODES = std::move(SBSYMCODES);
324 std::vector<UnownedPtr<CJBig2_Image>> SBSYMS(pDecoder->SBNUMSYMS);
325 fxcrt::Copy(pdfium::make_span(SDINSYMS).first(SDNUMINSYMS),
326 pdfium::make_span(SBSYMS));
327 for (size_t i = 0; i < NSYMSDECODED; ++i) {
328 SBSYMS[i + SDNUMINSYMS] = SDNEWSYMS[i].get();
329 }
330 pDecoder->SBSYMS = std::move(SBSYMS);
331 pDecoder->SBDEFPIXEL = false;
332 pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
333 pDecoder->TRANSPOSED = false;
334 pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
335 pDecoder->SBDSOFFSET = 0;
336 pDecoder->SBHUFFFS = SBHUFFFS.get();
337 pDecoder->SBHUFFDS = SBHUFFDS.get();
338 pDecoder->SBHUFFDT = SBHUFFDT.get();
339 pDecoder->SBHUFFRDW = SBHUFFRDW.get();
340 pDecoder->SBHUFFRDH = SBHUFFRDH.get();
341 pDecoder->SBHUFFRDX = SBHUFFRDX.get();
342 pDecoder->SBHUFFRDY = SBHUFFRDY.get();
343 pDecoder->SBHUFFRSIZE = SBHUFFRSIZE.get();
344 pDecoder->SBRTEMPLATE = SDRTEMPLATE;
345 pDecoder->SBRAT[0] = SDRAT[0];
346 pDecoder->SBRAT[1] = SDRAT[1];
347 pDecoder->SBRAT[2] = SDRAT[2];
348 pDecoder->SBRAT[3] = SDRAT[3];
349 BS = pDecoder->DecodeHuffman(pStream, grContexts);
350 if (!BS)
351 return nullptr;
352
353 } else if (REFAGGNINST == 1) {
354 uint32_t SBNUMSYMS = SDNUMINSYMS + SDNUMNEWSYMS;
355 uint32_t nTmp = 1;
356 while ((uint32_t)(1 << nTmp) < SBNUMSYMS) {
357 nTmp++;
358 }
359 uint8_t SBSYMCODELEN = (uint8_t)nTmp;
360 uint32_t uVal = 0;
361 uint32_t IDI;
362 for (;;) {
363 if (pStream->read1Bit(&nTmp) != 0)
364 return nullptr;
365
366 uVal = (uVal << 1) | nTmp;
367 if (uVal >= SBNUMSYMS)
368 return nullptr;
369
370 IDI = SBSYMCODELEN == 0 ? uVal : SBNUMSYMS;
371 if (IDI < SBNUMSYMS)
372 break;
373 }
374
375 CJBig2_Image* sbsyms_idi = GetImage(IDI, SDNEWSYMS);
376 if (!sbsyms_idi)
377 return nullptr;
378
379 auto SBHUFFRDX = std::make_unique<CJBig2_HuffmanTable>(15);
380 auto SBHUFFRSIZE = std::make_unique<CJBig2_HuffmanTable>(1);
381 int32_t RDXI;
382 int32_t RDYI;
383 if ((pHuffmanDecoder->DecodeAValue(SBHUFFRDX.get(), &RDXI) != 0) ||
384 (pHuffmanDecoder->DecodeAValue(SBHUFFRDX.get(), &RDYI) != 0) ||
385 (pHuffmanDecoder->DecodeAValue(SBHUFFRSIZE.get(), &nVal) != 0)) {
386 return nullptr;
387 }
388
389 pStream->alignByte();
390 nTmp = pStream->getOffset();
391
392 auto pGRRD = std::make_unique<CJBig2_GRRDProc>();
393 pGRRD->GRW = SYMWIDTH;
394 pGRRD->GRH = HCHEIGHT;
395 pGRRD->GRTEMPLATE = SDRTEMPLATE;
396 pGRRD->GRREFERENCE = sbsyms_idi;
397 pGRRD->GRREFERENCEDX = RDXI;
398 pGRRD->GRREFERENCEDY = RDYI;
399 pGRRD->TPGRON = false;
400 pGRRD->GRAT[0] = SDRAT[0];
401 pGRRD->GRAT[1] = SDRAT[1];
402 pGRRD->GRAT[2] = SDRAT[2];
403 pGRRD->GRAT[3] = SDRAT[3];
404 auto pArithDecoder = std::make_unique<CJBig2_ArithDecoder>(pStream);
405 BS = pGRRD->Decode(pArithDecoder.get(), grContexts);
406 if (!BS)
407 return nullptr;
408
409 pStream->alignByte();
410 pStream->addOffset(2);
411 if ((uint32_t)nVal != (pStream->getOffset() - nTmp))
412 return nullptr;
413 }
414 SDNEWSYMS[NSYMSDECODED] = std::move(BS);
415 }
416 if (SDREFAGG == 0)
417 SDNEWSYMWIDTHS[NSYMSDECODED] = SYMWIDTH;
418 ++NSYMSDECODED;
419 }
420 if (SDREFAGG == 0) {
421 uint32_t BMSIZE;
422 if (pHuffmanDecoder->DecodeAValue(SDHUFFBMSIZE, (int32_t*)&BMSIZE) != 0) {
423 return nullptr;
424 }
425 pStream->alignByte();
426 std::unique_ptr<CJBig2_Image> BHC;
427 if (BMSIZE == 0) {
428 if (static_cast<int>(TOTWIDTH) > kJBig2MaxImageSize)
429 return nullptr;
430
431 // OK to not use FX_SAFE_UINT32 to calculate `stride` because
432 // `kJBig2MaxImageSize` is limiting the size.
433 const uint32_t stride = (TOTWIDTH + 7) / 8;
434 FX_SAFE_UINT32 safe_image_size = stride;
435 safe_image_size *= HCHEIGHT;
436 if (!safe_image_size.IsValid() ||
437 pStream->getByteLeft() < safe_image_size.ValueOrDie()) {
438 return nullptr;
439 }
440
441 BHC = std::make_unique<CJBig2_Image>(TOTWIDTH, HCHEIGHT);
442 for (uint32_t i = 0; i < HCHEIGHT; ++i) {
443 UNSAFE_TODO(FXSYS_memcpy(BHC->data() + i * BHC->stride(),
444 pStream->getPointer(), stride));
445 pStream->addOffset(stride);
446 }
447 } else {
448 auto pGRD = std::make_unique<CJBig2_GRDProc>();
449 pGRD->MMR = true;
450 pGRD->GBW = TOTWIDTH;
451 pGRD->GBH = HCHEIGHT;
452 pGRD->StartDecodeMMR(&BHC, pStream);
453 pStream->alignByte();
454 }
455 if (!BHC)
456 continue;
457
458 uint32_t nTmp = 0;
459 for (uint32_t i = HCFIRSTSYM; i < NSYMSDECODED; ++i) {
460 SDNEWSYMS[i] = BHC->SubImage(nTmp, 0, SDNEWSYMWIDTHS[i], HCHEIGHT);
461 nTmp += SDNEWSYMWIDTHS[i];
462 }
463 }
464 }
465
466 std::unique_ptr<CJBig2_HuffmanTable> pTable =
467 std::make_unique<CJBig2_HuffmanTable>(1);
468 std::vector<bool> EXFLAGS;
469 EXFLAGS.resize(SDNUMINSYMS + SDNUMNEWSYMS);
470 bool CUREXFLAG = false;
471 uint32_t EXINDEX = 0;
472 uint32_t num_ex_syms = 0;
473 while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
474 uint32_t EXRUNLENGTH;
475 if (pHuffmanDecoder->DecodeAValue(pTable.get(), (int*)&EXRUNLENGTH) != 0)
476 return nullptr;
477
478 FX_SAFE_UINT32 new_ex_size = EXINDEX;
479 new_ex_size += EXRUNLENGTH;
480 if (!new_ex_size.IsValid() ||
481 new_ex_size.ValueOrDie() > SDNUMINSYMS + SDNUMNEWSYMS) {
482 return nullptr;
483 }
484
485 if (CUREXFLAG)
486 num_ex_syms += EXRUNLENGTH;
487 std::fill_n(EXFLAGS.begin() + EXINDEX, EXRUNLENGTH, CUREXFLAG);
488 EXINDEX = new_ex_size.ValueOrDie();
489 CUREXFLAG = !CUREXFLAG;
490 }
491 if (num_ex_syms > SDNUMEXSYMS)
492 return nullptr;
493
494 auto pDict = std::make_unique<CJBig2_SymbolDict>();
495 for (uint32_t i = 0, j = 0; i < SDNUMINSYMS + SDNUMNEWSYMS; ++i) {
496 if (!EXFLAGS[i] || j >= SDNUMEXSYMS)
497 continue;
498 if (i < SDNUMINSYMS) {
499 pDict->AddImage(
500 UNSAFE_TODO(SDINSYMS[i] ? std::make_unique<CJBig2_Image>(*SDINSYMS[i])
501 : nullptr));
502 } else {
503 pDict->AddImage(std::move(SDNEWSYMS[i - SDNUMINSYMS]));
504 }
505 ++j;
506 }
507 return pDict;
508}
509
511 uint32_t i,
512 pdfium::span<const std::unique_ptr<CJBig2_Image>> new_syms) const {
513 return i < SDNUMINSYMS ? SDINSYMS[i].get() : new_syms[i - SDNUMINSYMS].get();
514}
constexpr int32_t kJBig2OOB
constexpr int32_t kJBig2MaxImageSize
@ JBIG2_COMPOSE_OR
Definition JBig2_Image.h:23
@ JBIG2_CORNER_TOPLEFT
uint32_t getByteLeft() const
void addOffset(uint32_t dwDelta)
int32_t read1Bit(uint32_t *dwResult)
const uint8_t * getPointer() const
uint32_t getOffset() const
uint32_t SDNUMINSYMS
uint32_t SDNUMEXSYMS
std::unique_ptr< CJBig2_SymbolDict > DecodeHuffman(CJBig2_BitStream *pStream, pdfium::span< JBig2ArithCtx > gbContexts, pdfium::span< JBig2ArithCtx > grContexts)
uint32_t SDNUMNEWSYMS
std::unique_ptr< CJBig2_SymbolDict > DecodeArith(CJBig2_ArithDecoder *pArithDecoder, pdfium::span< JBig2ArithCtx > gbContexts, pdfium::span< JBig2ArithCtx > grContexts)
#define UNSAFE_TODO(...)
pdfium::CheckedNumeric< uint32_t > FX_SAFE_UINT32