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