1 // Copyright 2015 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 "core/src/fxcodec/jbig2/JBig2_SddProc.h"
8
9 #include <memory>
10 #include <vector>
11
12 #include "core/include/fxcrt/fx_basic.h"
13 #include "core/src/fxcodec/jbig2/JBig2_ArithIntDecoder.h"
14 #include "core/src/fxcodec/jbig2/JBig2_GrdProc.h"
15 #include "core/src/fxcodec/jbig2/JBig2_GrrdProc.h"
16 #include "core/src/fxcodec/jbig2/JBig2_HuffmanDecoder.h"
17 #include "core/src/fxcodec/jbig2/JBig2_HuffmanTable.h"
18 #include "core/src/fxcodec/jbig2/JBig2_HuffmanTable_Standard.h"
19 #include "core/src/fxcodec/jbig2/JBig2_SymbolDict.h"
20 #include "core/src/fxcodec/jbig2/JBig2_TrdProc.h"
21
decode_Arith(CJBig2_ArithDecoder * pArithDecoder,std::vector<JBig2ArithCtx> * gbContext,std::vector<JBig2ArithCtx> * grContext)22 CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith(
23 CJBig2_ArithDecoder* pArithDecoder,
24 std::vector<JBig2ArithCtx>* gbContext,
25 std::vector<JBig2ArithCtx>* grContext) {
26 CJBig2_Image** SDNEWSYMS;
27 FX_DWORD HCHEIGHT, NSYMSDECODED;
28 int32_t HCDH;
29 FX_DWORD SYMWIDTH, TOTWIDTH;
30 int32_t DW;
31 CJBig2_Image* BS;
32 FX_DWORD I, J, REFAGGNINST;
33 FX_BOOL* EXFLAGS;
34 FX_DWORD EXINDEX;
35 FX_BOOL CUREXFLAG;
36 FX_DWORD EXRUNLENGTH;
37 FX_DWORD nTmp;
38 FX_DWORD SBNUMSYMS;
39 uint8_t SBSYMCODELEN;
40 int32_t RDXI, RDYI;
41 CJBig2_Image** SBSYMS;
42 std::unique_ptr<CJBig2_ArithIaidDecoder> IAID;
43 std::unique_ptr<CJBig2_SymbolDict> pDict;
44 std::unique_ptr<CJBig2_ArithIntDecoder> IADH(new CJBig2_ArithIntDecoder);
45 std::unique_ptr<CJBig2_ArithIntDecoder> IADW(new CJBig2_ArithIntDecoder);
46 std::unique_ptr<CJBig2_ArithIntDecoder> IAAI(new CJBig2_ArithIntDecoder);
47 std::unique_ptr<CJBig2_ArithIntDecoder> IARDX(new CJBig2_ArithIntDecoder);
48 std::unique_ptr<CJBig2_ArithIntDecoder> IARDY(new CJBig2_ArithIntDecoder);
49 std::unique_ptr<CJBig2_ArithIntDecoder> IAEX(new CJBig2_ArithIntDecoder);
50 std::unique_ptr<CJBig2_ArithIntDecoder> IADT(new CJBig2_ArithIntDecoder);
51 std::unique_ptr<CJBig2_ArithIntDecoder> IAFS(new CJBig2_ArithIntDecoder);
52 std::unique_ptr<CJBig2_ArithIntDecoder> IADS(new CJBig2_ArithIntDecoder);
53 std::unique_ptr<CJBig2_ArithIntDecoder> IAIT(new CJBig2_ArithIntDecoder);
54 std::unique_ptr<CJBig2_ArithIntDecoder> IARI(new CJBig2_ArithIntDecoder);
55 std::unique_ptr<CJBig2_ArithIntDecoder> IARDW(new CJBig2_ArithIntDecoder);
56 std::unique_ptr<CJBig2_ArithIntDecoder> IARDH(new CJBig2_ArithIntDecoder);
57 nTmp = 0;
58 while ((FX_DWORD)(1 << nTmp) < (SDNUMINSYMS + SDNUMNEWSYMS)) {
59 nTmp++;
60 }
61 IAID.reset(new CJBig2_ArithIaidDecoder((uint8_t)nTmp));
62 SDNEWSYMS = FX_Alloc(CJBig2_Image*, SDNUMNEWSYMS);
63 FXSYS_memset(SDNEWSYMS, 0, SDNUMNEWSYMS * sizeof(CJBig2_Image*));
64
65 HCHEIGHT = 0;
66 NSYMSDECODED = 0;
67 while (NSYMSDECODED < SDNUMNEWSYMS) {
68 BS = nullptr;
69 IADH->decode(pArithDecoder, &HCDH);
70 HCHEIGHT = HCHEIGHT + HCDH;
71 if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
72 goto failed;
73 }
74 SYMWIDTH = 0;
75 TOTWIDTH = 0;
76 for (;;) {
77 if (!IADW->decode(pArithDecoder, &DW))
78 break;
79
80 if (NSYMSDECODED >= SDNUMNEWSYMS)
81 goto failed;
82
83 SYMWIDTH = SYMWIDTH + DW;
84 if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE)
85 goto failed;
86
87 if (HCHEIGHT == 0 || SYMWIDTH == 0) {
88 TOTWIDTH = TOTWIDTH + SYMWIDTH;
89 SDNEWSYMS[NSYMSDECODED] = nullptr;
90 NSYMSDECODED = NSYMSDECODED + 1;
91 continue;
92 }
93 TOTWIDTH = TOTWIDTH + SYMWIDTH;
94 if (SDREFAGG == 0) {
95 std::unique_ptr<CJBig2_GRDProc> pGRD(new CJBig2_GRDProc());
96 pGRD->MMR = 0;
97 pGRD->GBW = SYMWIDTH;
98 pGRD->GBH = HCHEIGHT;
99 pGRD->GBTEMPLATE = SDTEMPLATE;
100 pGRD->TPGDON = 0;
101 pGRD->USESKIP = 0;
102 pGRD->GBAT[0] = SDAT[0];
103 pGRD->GBAT[1] = SDAT[1];
104 pGRD->GBAT[2] = SDAT[2];
105 pGRD->GBAT[3] = SDAT[3];
106 pGRD->GBAT[4] = SDAT[4];
107 pGRD->GBAT[5] = SDAT[5];
108 pGRD->GBAT[6] = SDAT[6];
109 pGRD->GBAT[7] = SDAT[7];
110 BS = pGRD->decode_Arith(pArithDecoder, gbContext->data());
111 if (!BS) {
112 goto failed;
113 }
114 } else {
115 IAAI->decode(pArithDecoder, (int*)&REFAGGNINST);
116 if (REFAGGNINST > 1) {
117 std::unique_ptr<CJBig2_TRDProc> pDecoder(new CJBig2_TRDProc());
118 pDecoder->SBHUFF = SDHUFF;
119 pDecoder->SBREFINE = 1;
120 pDecoder->SBW = SYMWIDTH;
121 pDecoder->SBH = HCHEIGHT;
122 pDecoder->SBNUMINSTANCES = REFAGGNINST;
123 pDecoder->SBSTRIPS = 1;
124 pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
125 SBNUMSYMS = pDecoder->SBNUMSYMS;
126 nTmp = 0;
127 while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
128 nTmp++;
129 }
130 SBSYMCODELEN = (uint8_t)nTmp;
131 pDecoder->SBSYMCODELEN = SBSYMCODELEN;
132 SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
133 JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
134 JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
135 NSYMSDECODED * sizeof(CJBig2_Image*));
136 pDecoder->SBSYMS = SBSYMS;
137 pDecoder->SBDEFPIXEL = 0;
138 pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
139 pDecoder->TRANSPOSED = 0;
140 pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
141 pDecoder->SBDSOFFSET = 0;
142 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFFS(new CJBig2_HuffmanTable(
143 HuffmanTable_B6, FX_ArraySize(HuffmanTable_B6),
144 HuffmanTable_HTOOB_B6));
145 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFDS(new CJBig2_HuffmanTable(
146 HuffmanTable_B8, FX_ArraySize(HuffmanTable_B8),
147 HuffmanTable_HTOOB_B8));
148 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFDT(new CJBig2_HuffmanTable(
149 HuffmanTable_B11, FX_ArraySize(HuffmanTable_B11),
150 HuffmanTable_HTOOB_B11));
151 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDW(
152 new CJBig2_HuffmanTable(HuffmanTable_B15,
153 FX_ArraySize(HuffmanTable_B15),
154 HuffmanTable_HTOOB_B15));
155 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDH(
156 new CJBig2_HuffmanTable(HuffmanTable_B15,
157 FX_ArraySize(HuffmanTable_B15),
158 HuffmanTable_HTOOB_B15));
159 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDX(
160 new CJBig2_HuffmanTable(HuffmanTable_B15,
161 FX_ArraySize(HuffmanTable_B15),
162 HuffmanTable_HTOOB_B15));
163 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDY(
164 new CJBig2_HuffmanTable(HuffmanTable_B15,
165 FX_ArraySize(HuffmanTable_B15),
166 HuffmanTable_HTOOB_B15));
167 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRSIZE(
168 new CJBig2_HuffmanTable(HuffmanTable_B1,
169 FX_ArraySize(HuffmanTable_B1),
170 HuffmanTable_HTOOB_B1));
171 pDecoder->SBHUFFFS = SBHUFFFS.get();
172 pDecoder->SBHUFFDS = SBHUFFDS.get();
173 pDecoder->SBHUFFDT = SBHUFFDT.get();
174 pDecoder->SBHUFFRDW = SBHUFFRDW.get();
175 pDecoder->SBHUFFRDH = SBHUFFRDH.get();
176 pDecoder->SBHUFFRDX = SBHUFFRDX.get();
177 pDecoder->SBHUFFRDY = SBHUFFRDY.get();
178 pDecoder->SBHUFFRSIZE = SBHUFFRSIZE.get();
179 pDecoder->SBRTEMPLATE = SDRTEMPLATE;
180 pDecoder->SBRAT[0] = SDRAT[0];
181 pDecoder->SBRAT[1] = SDRAT[1];
182 pDecoder->SBRAT[2] = SDRAT[2];
183 pDecoder->SBRAT[3] = SDRAT[3];
184 JBig2IntDecoderState ids;
185 ids.IADT = IADT.get();
186 ids.IAFS = IAFS.get();
187 ids.IADS = IADS.get();
188 ids.IAIT = IAIT.get();
189 ids.IARI = IARI.get();
190 ids.IARDW = IARDW.get();
191 ids.IARDH = IARDH.get();
192 ids.IARDX = IARDX.get();
193 ids.IARDY = IARDY.get();
194 ids.IAID = IAID.get();
195 BS = pDecoder->decode_Arith(pArithDecoder, grContext->data(), &ids);
196 if (!BS) {
197 FX_Free(SBSYMS);
198 goto failed;
199 }
200 FX_Free(SBSYMS);
201 } else if (REFAGGNINST == 1) {
202 SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
203 FX_DWORD IDI;
204 IAID->decode(pArithDecoder, &IDI);
205 IARDX->decode(pArithDecoder, &RDXI);
206 IARDY->decode(pArithDecoder, &RDYI);
207 if (IDI >= SBNUMSYMS) {
208 goto failed;
209 }
210 SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
211 JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
212 JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
213 NSYMSDECODED * sizeof(CJBig2_Image*));
214 if (!SBSYMS[IDI]) {
215 FX_Free(SBSYMS);
216 goto failed;
217 }
218 std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc());
219 pGRRD->GRW = SYMWIDTH;
220 pGRRD->GRH = HCHEIGHT;
221 pGRRD->GRTEMPLATE = SDRTEMPLATE;
222 pGRRD->GRREFERENCE = SBSYMS[IDI];
223 pGRRD->GRREFERENCEDX = RDXI;
224 pGRRD->GRREFERENCEDY = RDYI;
225 pGRRD->TPGRON = 0;
226 pGRRD->GRAT[0] = SDRAT[0];
227 pGRRD->GRAT[1] = SDRAT[1];
228 pGRRD->GRAT[2] = SDRAT[2];
229 pGRRD->GRAT[3] = SDRAT[3];
230 BS = pGRRD->decode(pArithDecoder, grContext->data());
231 if (!BS) {
232 FX_Free(SBSYMS);
233 goto failed;
234 }
235 FX_Free(SBSYMS);
236 }
237 }
238 SDNEWSYMS[NSYMSDECODED] = BS;
239 BS = nullptr;
240 NSYMSDECODED = NSYMSDECODED + 1;
241 }
242 }
243 EXINDEX = 0;
244 CUREXFLAG = 0;
245 EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS);
246 while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
247 IAEX->decode(pArithDecoder, (int*)&EXRUNLENGTH);
248 if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) {
249 FX_Free(EXFLAGS);
250 goto failed;
251 }
252 if (EXRUNLENGTH != 0) {
253 for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) {
254 EXFLAGS[I] = CUREXFLAG;
255 }
256 }
257 EXINDEX = EXINDEX + EXRUNLENGTH;
258 CUREXFLAG = !CUREXFLAG;
259 }
260 pDict.reset(new CJBig2_SymbolDict);
261 I = J = 0;
262 for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
263 if (EXFLAGS[I] && J < SDNUMEXSYMS) {
264 if (I < SDNUMINSYMS) {
265 pDict->AddImage(SDINSYMS[I] ? new CJBig2_Image(*SDINSYMS[I]) : nullptr);
266 } else {
267 pDict->AddImage(SDNEWSYMS[I - SDNUMINSYMS]);
268 }
269 ++J;
270 } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
271 delete SDNEWSYMS[I - SDNUMINSYMS];
272 }
273 }
274 FX_Free(EXFLAGS);
275 FX_Free(SDNEWSYMS);
276 return pDict.release();
277 failed:
278 for (I = 0; I < NSYMSDECODED; I++) {
279 if (SDNEWSYMS[I]) {
280 delete SDNEWSYMS[I];
281 SDNEWSYMS[I] = nullptr;
282 }
283 }
284 FX_Free(SDNEWSYMS);
285 return nullptr;
286 }
287
decode_Huffman(CJBig2_BitStream * pStream,std::vector<JBig2ArithCtx> * gbContext,std::vector<JBig2ArithCtx> * grContext,IFX_Pause * pPause)288 CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman(
289 CJBig2_BitStream* pStream,
290 std::vector<JBig2ArithCtx>* gbContext,
291 std::vector<JBig2ArithCtx>* grContext,
292 IFX_Pause* pPause) {
293 CJBig2_Image** SDNEWSYMS;
294 FX_DWORD* SDNEWSYMWIDTHS;
295 FX_DWORD HCHEIGHT, NSYMSDECODED;
296 int32_t HCDH;
297 FX_DWORD SYMWIDTH, TOTWIDTH, HCFIRSTSYM;
298 int32_t DW;
299 CJBig2_Image* BS, *BHC;
300 FX_DWORD I, J, REFAGGNINST;
301 FX_BOOL* EXFLAGS;
302 FX_DWORD EXINDEX;
303 FX_BOOL CUREXFLAG;
304 FX_DWORD EXRUNLENGTH;
305 int32_t nVal, nBits;
306 FX_DWORD nTmp;
307 FX_DWORD SBNUMSYMS;
308 uint8_t SBSYMCODELEN;
309 JBig2HuffmanCode* SBSYMCODES;
310 FX_DWORD IDI;
311 int32_t RDXI, RDYI;
312 FX_DWORD BMSIZE;
313 FX_DWORD stride;
314 CJBig2_Image** SBSYMS;
315 std::unique_ptr<CJBig2_HuffmanDecoder> pHuffmanDecoder(
316 new CJBig2_HuffmanDecoder(pStream));
317 SDNEWSYMS = FX_Alloc(CJBig2_Image*, SDNUMNEWSYMS);
318 FXSYS_memset(SDNEWSYMS, 0, SDNUMNEWSYMS * sizeof(CJBig2_Image*));
319 SDNEWSYMWIDTHS = nullptr;
320 BHC = nullptr;
321 if (SDREFAGG == 0) {
322 SDNEWSYMWIDTHS = FX_Alloc(FX_DWORD, SDNUMNEWSYMS);
323 FXSYS_memset(SDNEWSYMWIDTHS, 0, SDNUMNEWSYMS * sizeof(FX_DWORD));
324 }
325 std::unique_ptr<CJBig2_SymbolDict> pDict(new CJBig2_SymbolDict());
326 std::unique_ptr<CJBig2_HuffmanTable> pTable;
327
328 HCHEIGHT = 0;
329 NSYMSDECODED = 0;
330 BS = nullptr;
331 while (NSYMSDECODED < SDNUMNEWSYMS) {
332 if (pHuffmanDecoder->decodeAValue(SDHUFFDH, &HCDH) != 0) {
333 goto failed;
334 }
335 HCHEIGHT = HCHEIGHT + HCDH;
336 if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
337 goto failed;
338 }
339 SYMWIDTH = 0;
340 TOTWIDTH = 0;
341 HCFIRSTSYM = NSYMSDECODED;
342 for (;;) {
343 nVal = pHuffmanDecoder->decodeAValue(SDHUFFDW, &DW);
344 if (nVal == JBIG2_OOB) {
345 break;
346 } else if (nVal != 0) {
347 goto failed;
348 } else {
349 if (NSYMSDECODED >= SDNUMNEWSYMS) {
350 goto failed;
351 }
352 SYMWIDTH = SYMWIDTH + DW;
353 if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) {
354 goto failed;
355 } else if (HCHEIGHT == 0 || SYMWIDTH == 0) {
356 TOTWIDTH = TOTWIDTH + SYMWIDTH;
357 SDNEWSYMS[NSYMSDECODED] = nullptr;
358 NSYMSDECODED = NSYMSDECODED + 1;
359 continue;
360 }
361 TOTWIDTH = TOTWIDTH + SYMWIDTH;
362 }
363 if (SDREFAGG == 1) {
364 if (pHuffmanDecoder->decodeAValue(SDHUFFAGGINST, (int*)&REFAGGNINST) !=
365 0) {
366 goto failed;
367 }
368 BS = nullptr;
369 if (REFAGGNINST > 1) {
370 std::unique_ptr<CJBig2_TRDProc> pDecoder(new CJBig2_TRDProc());
371 pDecoder->SBHUFF = SDHUFF;
372 pDecoder->SBREFINE = 1;
373 pDecoder->SBW = SYMWIDTH;
374 pDecoder->SBH = HCHEIGHT;
375 pDecoder->SBNUMINSTANCES = REFAGGNINST;
376 pDecoder->SBSTRIPS = 1;
377 pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
378 SBNUMSYMS = pDecoder->SBNUMSYMS;
379 SBSYMCODES = FX_Alloc(JBig2HuffmanCode, SBNUMSYMS);
380 nTmp = 1;
381 while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
382 nTmp++;
383 }
384 for (I = 0; I < SBNUMSYMS; I++) {
385 SBSYMCODES[I].codelen = nTmp;
386 SBSYMCODES[I].code = I;
387 }
388 pDecoder->SBSYMCODES = SBSYMCODES;
389 SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
390 JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
391 JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
392 NSYMSDECODED * sizeof(CJBig2_Image*));
393 pDecoder->SBSYMS = SBSYMS;
394 pDecoder->SBDEFPIXEL = 0;
395 pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
396 pDecoder->TRANSPOSED = 0;
397 pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
398 pDecoder->SBDSOFFSET = 0;
399 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFFS(new CJBig2_HuffmanTable(
400 HuffmanTable_B6, FX_ArraySize(HuffmanTable_B6),
401 HuffmanTable_HTOOB_B6));
402 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFDS(new CJBig2_HuffmanTable(
403 HuffmanTable_B8, FX_ArraySize(HuffmanTable_B8),
404 HuffmanTable_HTOOB_B8));
405 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFDT(new CJBig2_HuffmanTable(
406 HuffmanTable_B11, FX_ArraySize(HuffmanTable_B11),
407 HuffmanTable_HTOOB_B11));
408 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDW(
409 new CJBig2_HuffmanTable(HuffmanTable_B15,
410 FX_ArraySize(HuffmanTable_B15),
411 HuffmanTable_HTOOB_B15));
412 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDH(
413 new CJBig2_HuffmanTable(HuffmanTable_B15,
414 FX_ArraySize(HuffmanTable_B15),
415 HuffmanTable_HTOOB_B15));
416 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDX(
417 new CJBig2_HuffmanTable(HuffmanTable_B15,
418 FX_ArraySize(HuffmanTable_B15),
419 HuffmanTable_HTOOB_B15));
420 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDY(
421 new CJBig2_HuffmanTable(HuffmanTable_B15,
422 FX_ArraySize(HuffmanTable_B15),
423 HuffmanTable_HTOOB_B15));
424 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRSIZE(
425 new CJBig2_HuffmanTable(HuffmanTable_B1,
426 FX_ArraySize(HuffmanTable_B1),
427 HuffmanTable_HTOOB_B1));
428 pDecoder->SBHUFFFS = SBHUFFFS.get();
429 pDecoder->SBHUFFDS = SBHUFFDS.get();
430 pDecoder->SBHUFFDT = SBHUFFDT.get();
431 pDecoder->SBHUFFRDW = SBHUFFRDW.get();
432 pDecoder->SBHUFFRDH = SBHUFFRDH.get();
433 pDecoder->SBHUFFRDX = SBHUFFRDX.get();
434 pDecoder->SBHUFFRDY = SBHUFFRDY.get();
435 pDecoder->SBHUFFRSIZE = SBHUFFRSIZE.get();
436 pDecoder->SBRTEMPLATE = SDRTEMPLATE;
437 pDecoder->SBRAT[0] = SDRAT[0];
438 pDecoder->SBRAT[1] = SDRAT[1];
439 pDecoder->SBRAT[2] = SDRAT[2];
440 pDecoder->SBRAT[3] = SDRAT[3];
441 BS = pDecoder->decode_Huffman(pStream, grContext->data());
442 if (!BS) {
443 FX_Free(SBSYMCODES);
444 FX_Free(SBSYMS);
445 goto failed;
446 }
447 FX_Free(SBSYMCODES);
448 FX_Free(SBSYMS);
449 } else if (REFAGGNINST == 1) {
450 SBNUMSYMS = SDNUMINSYMS + SDNUMNEWSYMS;
451 nTmp = 1;
452 while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
453 nTmp++;
454 }
455 SBSYMCODELEN = (uint8_t)nTmp;
456 SBSYMCODES = FX_Alloc(JBig2HuffmanCode, SBNUMSYMS);
457 for (I = 0; I < SBNUMSYMS; I++) {
458 SBSYMCODES[I].codelen = SBSYMCODELEN;
459 SBSYMCODES[I].code = I;
460 }
461 nVal = 0;
462 nBits = 0;
463 for (;;) {
464 if (pStream->read1Bit(&nTmp) != 0) {
465 FX_Free(SBSYMCODES);
466 goto failed;
467 }
468 nVal = (nVal << 1) | nTmp;
469 for (IDI = 0; IDI < SBNUMSYMS; IDI++) {
470 if ((nVal == SBSYMCODES[IDI].code) &&
471 (nBits == SBSYMCODES[IDI].codelen)) {
472 break;
473 }
474 }
475 if (IDI < SBNUMSYMS) {
476 break;
477 }
478 }
479 FX_Free(SBSYMCODES);
480 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDX(
481 new CJBig2_HuffmanTable(HuffmanTable_B15,
482 FX_ArraySize(HuffmanTable_B15),
483 HuffmanTable_HTOOB_B15));
484 std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRSIZE(
485 new CJBig2_HuffmanTable(HuffmanTable_B1,
486 FX_ArraySize(HuffmanTable_B1),
487 HuffmanTable_HTOOB_B1));
488 if ((pHuffmanDecoder->decodeAValue(SBHUFFRDX.get(), &RDXI) != 0) ||
489 (pHuffmanDecoder->decodeAValue(SBHUFFRDX.get(), &RDYI) != 0) ||
490 (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE.get(), &nVal) != 0)) {
491 goto failed;
492 }
493 pStream->alignByte();
494 nTmp = pStream->getOffset();
495 SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
496 JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
497 JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
498 NSYMSDECODED * sizeof(CJBig2_Image*));
499 std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc());
500 pGRRD->GRW = SYMWIDTH;
501 pGRRD->GRH = HCHEIGHT;
502 pGRRD->GRTEMPLATE = SDRTEMPLATE;
503 pGRRD->GRREFERENCE = SBSYMS[IDI];
504 pGRRD->GRREFERENCEDX = RDXI;
505 pGRRD->GRREFERENCEDY = RDYI;
506 pGRRD->TPGRON = 0;
507 pGRRD->GRAT[0] = SDRAT[0];
508 pGRRD->GRAT[1] = SDRAT[1];
509 pGRRD->GRAT[2] = SDRAT[2];
510 pGRRD->GRAT[3] = SDRAT[3];
511 std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder(
512 new CJBig2_ArithDecoder(pStream));
513 BS = pGRRD->decode(pArithDecoder.get(), grContext->data());
514 if (!BS) {
515 FX_Free(SBSYMS);
516 goto failed;
517 }
518 pStream->alignByte();
519 pStream->offset(2);
520 if ((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
521 delete BS;
522 FX_Free(SBSYMS);
523 goto failed;
524 }
525 FX_Free(SBSYMS);
526 }
527 SDNEWSYMS[NSYMSDECODED] = BS;
528 }
529 if (SDREFAGG == 0) {
530 SDNEWSYMWIDTHS[NSYMSDECODED] = SYMWIDTH;
531 }
532 NSYMSDECODED = NSYMSDECODED + 1;
533 }
534 if (SDREFAGG == 0) {
535 if (pHuffmanDecoder->decodeAValue(SDHUFFBMSIZE, (int32_t*)&BMSIZE) != 0) {
536 goto failed;
537 }
538 pStream->alignByte();
539 if (BMSIZE == 0) {
540 stride = (TOTWIDTH + 7) >> 3;
541 if (pStream->getByteLeft() >= stride * HCHEIGHT) {
542 BHC = new CJBig2_Image(TOTWIDTH, HCHEIGHT);
543 for (I = 0; I < HCHEIGHT; I++) {
544 JBIG2_memcpy(BHC->m_pData + I * BHC->m_nStride,
545 pStream->getPointer(), stride);
546 pStream->offset(stride);
547 }
548 } else {
549 goto failed;
550 }
551 } else {
552 std::unique_ptr<CJBig2_GRDProc> pGRD(new CJBig2_GRDProc());
553 pGRD->MMR = 1;
554 pGRD->GBW = TOTWIDTH;
555 pGRD->GBH = HCHEIGHT;
556 FXCODEC_STATUS status = pGRD->Start_decode_MMR(&BHC, pStream, nullptr);
557 while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
558 pGRD->Continue_decode(pPause);
559 }
560 pStream->alignByte();
561 }
562 nTmp = 0;
563 if (!BHC) {
564 continue;
565 }
566 for (I = HCFIRSTSYM; I < NSYMSDECODED; I++) {
567 SDNEWSYMS[I] = BHC->subImage(nTmp, 0, SDNEWSYMWIDTHS[I], HCHEIGHT);
568 nTmp += SDNEWSYMWIDTHS[I];
569 }
570 delete BHC;
571 BHC = nullptr;
572 }
573 }
574 EXINDEX = 0;
575 CUREXFLAG = 0;
576 pTable.reset(new CJBig2_HuffmanTable(
577 HuffmanTable_B1, FX_ArraySize(HuffmanTable_B1), HuffmanTable_HTOOB_B1));
578 EXFLAGS = FX_Alloc(FX_BOOL, SDNUMINSYMS + SDNUMNEWSYMS);
579 while (EXINDEX < SDNUMINSYMS + SDNUMNEWSYMS) {
580 if (pHuffmanDecoder->decodeAValue(pTable.get(), (int*)&EXRUNLENGTH) != 0) {
581 FX_Free(EXFLAGS);
582 goto failed;
583 }
584 if (EXINDEX + EXRUNLENGTH > SDNUMINSYMS + SDNUMNEWSYMS) {
585 FX_Free(EXFLAGS);
586 goto failed;
587 }
588 if (EXRUNLENGTH != 0) {
589 for (I = EXINDEX; I < EXINDEX + EXRUNLENGTH; I++) {
590 EXFLAGS[I] = CUREXFLAG;
591 }
592 }
593 EXINDEX = EXINDEX + EXRUNLENGTH;
594 CUREXFLAG = !CUREXFLAG;
595 }
596 I = J = 0;
597 for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
598 if (EXFLAGS[I] && J < SDNUMEXSYMS) {
599 if (I < SDNUMINSYMS) {
600 pDict->AddImage(SDINSYMS[I] ? new CJBig2_Image(*SDINSYMS[I]) : nullptr);
601 } else {
602 pDict->AddImage(SDNEWSYMS[I - SDNUMINSYMS]);
603 }
604 ++J;
605 } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
606 delete SDNEWSYMS[I - SDNUMINSYMS];
607 }
608 }
609 FX_Free(EXFLAGS);
610 FX_Free(SDNEWSYMS);
611 if (SDREFAGG == 0) {
612 FX_Free(SDNEWSYMWIDTHS);
613 }
614 return pDict.release();
615 failed:
616 for (I = 0; I < NSYMSDECODED; I++) {
617 delete SDNEWSYMS[I];
618 }
619 FX_Free(SDNEWSYMS);
620 if (SDREFAGG == 0) {
621 FX_Free(SDNEWSYMWIDTHS);
622 }
623 return nullptr;
624 }
625