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