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