Stop inlining CJBig2_BitStream.
[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   FX_DWORD nTmp;
35   FX_DWORD SBNUMSYMS;
36   uint8_t SBSYMCODELEN;
37   int32_t RDXI, RDYI;
38   CJBig2_Image** SBSYMS;
39   nonstd::unique_ptr<CJBig2_ArithIaidDecoder> IAID;
40   nonstd::unique_ptr<CJBig2_SymbolDict> pDict;
41   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IADH(new CJBig2_ArithIntDecoder);
42   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IADW(new CJBig2_ArithIntDecoder);
43   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IAAI(new CJBig2_ArithIntDecoder);
44   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IARDX(new CJBig2_ArithIntDecoder);
45   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IARDY(new CJBig2_ArithIntDecoder);
46   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IAEX(new CJBig2_ArithIntDecoder);
47   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IADT(new CJBig2_ArithIntDecoder);
48   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IAFS(new CJBig2_ArithIntDecoder);
49   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IADS(new CJBig2_ArithIntDecoder);
50   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IAIT(new CJBig2_ArithIntDecoder);
51   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IARI(new CJBig2_ArithIntDecoder);
52   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IARDW(new CJBig2_ArithIntDecoder);
53   nonstd::unique_ptr<CJBig2_ArithIntDecoder> IARDH(new CJBig2_ArithIntDecoder);
54   nTmp = 0;
55   while ((FX_DWORD)(1 << nTmp) < (SDNUMINSYMS + SDNUMNEWSYMS)) {
56     nTmp++;
57   }
58   IAID.reset(new CJBig2_ArithIaidDecoder((uint8_t)nTmp));
59   SDNEWSYMS = FX_Alloc(CJBig2_Image*, SDNUMNEWSYMS);
60   FXSYS_memset(SDNEWSYMS, 0, SDNUMNEWSYMS * sizeof(CJBig2_Image*));
61
62   HCHEIGHT = 0;
63   NSYMSDECODED = 0;
64   while (NSYMSDECODED < SDNUMNEWSYMS) {
65     BS = nullptr;
66     IADH->decode(pArithDecoder, &HCDH);
67     HCHEIGHT = HCHEIGHT + HCDH;
68     if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) {
69       goto failed;
70     }
71     SYMWIDTH = 0;
72     TOTWIDTH = 0;
73     for (;;) {
74       if (!IADW->decode(pArithDecoder, &DW))
75         break;
76
77       if (NSYMSDECODED >= SDNUMNEWSYMS)
78         goto failed;
79
80       SYMWIDTH = SYMWIDTH + DW;
81       if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE)
82         goto failed;
83
84       if (HCHEIGHT == 0 || SYMWIDTH == 0) {
85         TOTWIDTH = TOTWIDTH + SYMWIDTH;
86         SDNEWSYMS[NSYMSDECODED] = nullptr;
87         NSYMSDECODED = NSYMSDECODED + 1;
88         continue;
89       }
90       TOTWIDTH = TOTWIDTH + SYMWIDTH;
91       if (SDREFAGG == 0) {
92         nonstd::unique_ptr<CJBig2_GRDProc> pGRD(new CJBig2_GRDProc());
93         pGRD->MMR = 0;
94         pGRD->GBW = SYMWIDTH;
95         pGRD->GBH = HCHEIGHT;
96         pGRD->GBTEMPLATE = SDTEMPLATE;
97         pGRD->TPGDON = 0;
98         pGRD->USESKIP = 0;
99         pGRD->GBAT[0] = SDAT[0];
100         pGRD->GBAT[1] = SDAT[1];
101         pGRD->GBAT[2] = SDAT[2];
102         pGRD->GBAT[3] = SDAT[3];
103         pGRD->GBAT[4] = SDAT[4];
104         pGRD->GBAT[5] = SDAT[5];
105         pGRD->GBAT[6] = SDAT[6];
106         pGRD->GBAT[7] = SDAT[7];
107         BS = pGRD->decode_Arith(pArithDecoder, gbContext);
108         if (!BS) {
109           goto failed;
110         }
111       } else {
112         IAAI->decode(pArithDecoder, (int*)&REFAGGNINST);
113         if (REFAGGNINST > 1) {
114           nonstd::unique_ptr<CJBig2_TRDProc> pDecoder(new CJBig2_TRDProc());
115           pDecoder->SBHUFF = SDHUFF;
116           pDecoder->SBREFINE = 1;
117           pDecoder->SBW = SYMWIDTH;
118           pDecoder->SBH = HCHEIGHT;
119           pDecoder->SBNUMINSTANCES = REFAGGNINST;
120           pDecoder->SBSTRIPS = 1;
121           pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED;
122           SBNUMSYMS = pDecoder->SBNUMSYMS;
123           nTmp = 0;
124           while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) {
125             nTmp++;
126           }
127           SBSYMCODELEN = (uint8_t)nTmp;
128           pDecoder->SBSYMCODELEN = SBSYMCODELEN;
129           SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS);
130           JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*));
131           JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS,
132                        NSYMSDECODED * sizeof(CJBig2_Image*));
133           pDecoder->SBSYMS = SBSYMS;
134           pDecoder->SBDEFPIXEL = 0;
135           pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR;
136           pDecoder->TRANSPOSED = 0;
137           pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT;
138           pDecoder->SBDSOFFSET = 0;
139           nonstd::unique_ptr<CJBig2_HuffmanTable> SBHUFFFS(
140               new CJBig2_HuffmanTable(HuffmanTable_B6,
141                                       FX_ArraySize(HuffmanTable_B6),
142                                       HuffmanTable_HTOOB_B6));
143           nonstd::unique_ptr<CJBig2_HuffmanTable> SBHUFFDS(
144               new CJBig2_HuffmanTable(HuffmanTable_B8,
145                                       FX_ArraySize(HuffmanTable_B8),
146                                       HuffmanTable_HTOOB_B8));
147           nonstd::unique_ptr<CJBig2_HuffmanTable> SBHUFFDT(
148               new CJBig2_HuffmanTable(HuffmanTable_B11,
149                                       FX_ArraySize(HuffmanTable_B11),
150                                       HuffmanTable_HTOOB_B11));
151           nonstd::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDW(
152               new CJBig2_HuffmanTable(HuffmanTable_B15,
153                                       FX_ArraySize(HuffmanTable_B15),
154                                       HuffmanTable_HTOOB_B15));
155           nonstd::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDH(
156               new CJBig2_HuffmanTable(HuffmanTable_B15,
157                                       FX_ArraySize(HuffmanTable_B15),
158                                       HuffmanTable_HTOOB_B15));
159           nonstd::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDX(
160               new CJBig2_HuffmanTable(HuffmanTable_B15,
161                                       FX_ArraySize(HuffmanTable_B15),
162                                       HuffmanTable_HTOOB_B15));
163           nonstd::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDY(
164               new CJBig2_HuffmanTable(HuffmanTable_B15,
165                                       FX_ArraySize(HuffmanTable_B15),
166                                       HuffmanTable_HTOOB_B15));
167           nonstd::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, &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           nonstd::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);
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   pDict->SDNUMEXSYMS = SDNUMEXSYMS;
262   pDict->SDEXSYMS = FX_Alloc(CJBig2_Image*, SDNUMEXSYMS);
263   I = J = 0;
264   for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
265     if (EXFLAGS[I] && J < SDNUMEXSYMS) {
266       if (I < SDNUMINSYMS) {
267         pDict->SDEXSYMS[J] = new CJBig2_Image(*SDINSYMS[I]);
268       } else {
269         pDict->SDEXSYMS[J] = SDNEWSYMS[I - SDNUMINSYMS];
270       }
271       J = J + 1;
272     } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
273       delete SDNEWSYMS[I - SDNUMINSYMS];
274     }
275   }
276   if (J < SDNUMEXSYMS) {
277     pDict->SDNUMEXSYMS = J;
278   }
279   FX_Free(EXFLAGS);
280   FX_Free(SDNEWSYMS);
281   return pDict.release();
282 failed:
283   for (I = 0; I < NSYMSDECODED; I++) {
284     if (SDNEWSYMS[I]) {
285       delete SDNEWSYMS[I];
286       SDNEWSYMS[I] = nullptr;
287     }
288   }
289   FX_Free(SDNEWSYMS);
290   return nullptr;
291 }
292
293 CJBig2_SymbolDict* CJBig2_SDDProc::decode_Huffman(CJBig2_BitStream* pStream,
294                                                   JBig2ArithCtx* gbContext,
295                                                   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, 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(), 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   pDict->SDNUMEXSYMS = SDNUMEXSYMS;
604   pDict->SDEXSYMS = FX_Alloc(CJBig2_Image*, SDNUMEXSYMS);
605   I = J = 0;
606   for (I = 0; I < SDNUMINSYMS + SDNUMNEWSYMS; I++) {
607     if (EXFLAGS[I] && J < SDNUMEXSYMS) {
608       if (I < SDNUMINSYMS) {
609         pDict->SDEXSYMS[J] = new CJBig2_Image(*SDINSYMS[I]);
610       } else {
611         pDict->SDEXSYMS[J] = SDNEWSYMS[I - SDNUMINSYMS];
612       }
613       J = J + 1;
614     } else if (!EXFLAGS[I] && I >= SDNUMINSYMS) {
615       delete SDNEWSYMS[I - SDNUMINSYMS];
616     }
617   }
618   if (J < SDNUMEXSYMS) {
619     pDict->SDNUMEXSYMS = J;
620   }
621   FX_Free(EXFLAGS);
622   FX_Free(SDNEWSYMS);
623   if (SDREFAGG == 0) {
624     FX_Free(SDNEWSYMWIDTHS);
625   }
626   return pDict.release();
627 failed:
628   for (I = 0; I < NSYMSDECODED; I++) {
629     delete SDNEWSYMS[I];
630   }
631   FX_Free(SDNEWSYMS);
632   if (SDREFAGG == 0) {
633     FX_Free(SDNEWSYMWIDTHS);
634   }
635   return nullptr;
636 }