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