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