Home | History | Annotate | Download | only in jbig2
      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 
     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 
    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