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 "JBig2_TrdProc.h"
      8 
      9 #include <memory>
     10 
     11 #include "JBig2_ArithDecoder.h"
     12 #include "JBig2_ArithIntDecoder.h"
     13 #include "JBig2_GrrdProc.h"
     14 #include "JBig2_HuffmanDecoder.h"
     15 
     16 CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream,
     17                                              JBig2ArithCtx* grContext) {
     18   int32_t STRIPT, FIRSTS;
     19   FX_DWORD NINSTANCES;
     20   int32_t DT, DFS, CURS;
     21   int32_t SI, TI;
     22   CJBig2_Image* IBI;
     23   FX_DWORD WI, HI;
     24   int32_t IDS;
     25   FX_BOOL RI;
     26   int32_t RDWI, RDHI, RDXI, RDYI;
     27   CJBig2_Image* IBOI;
     28   FX_DWORD WOI, HOI;
     29   FX_BOOL bFirst;
     30   FX_DWORD nTmp;
     31   int32_t nVal, nBits;
     32   std::unique_ptr<CJBig2_HuffmanDecoder> pHuffmanDecoder(
     33       new CJBig2_HuffmanDecoder(pStream));
     34   std::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH));
     35   SBREG->fill(SBDEFPIXEL);
     36   if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0)
     37     return nullptr;
     38 
     39   STRIPT *= SBSTRIPS;
     40   STRIPT = -STRIPT;
     41   FIRSTS = 0;
     42   NINSTANCES = 0;
     43   while (NINSTANCES < SBNUMINSTANCES) {
     44     if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0)
     45       return nullptr;
     46 
     47     DT *= SBSTRIPS;
     48     STRIPT = STRIPT + DT;
     49     bFirst = TRUE;
     50     for (;;) {
     51       if (bFirst) {
     52         if (pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0)
     53           return nullptr;
     54 
     55         FIRSTS = FIRSTS + DFS;
     56         CURS = FIRSTS;
     57         bFirst = FALSE;
     58       } else {
     59         nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS);
     60         if (nVal == JBIG2_OOB) {
     61           break;
     62         } else if (nVal != 0) {
     63           return nullptr;
     64         } else {
     65           CURS = CURS + IDS + SBDSOFFSET;
     66         }
     67       }
     68       uint8_t CURT = 0;
     69       if (SBSTRIPS != 1) {
     70         nTmp = 1;
     71         while ((FX_DWORD)(1 << nTmp) < SBSTRIPS) {
     72           nTmp++;
     73         }
     74         if (pStream->readNBits(nTmp, &nVal) != 0)
     75           return nullptr;
     76 
     77         CURT = nVal;
     78       }
     79       TI = STRIPT + CURT;
     80       nVal = 0;
     81       nBits = 0;
     82       FX_DWORD IDI;
     83       for (;;) {
     84         if (pStream->read1Bit(&nTmp) != 0)
     85           return nullptr;
     86 
     87         nVal = (nVal << 1) | nTmp;
     88         nBits++;
     89         for (IDI = 0; IDI < SBNUMSYMS; IDI++) {
     90           if ((nBits == SBSYMCODES[IDI].codelen) &&
     91               (nVal == SBSYMCODES[IDI].code)) {
     92             break;
     93           }
     94         }
     95         if (IDI < SBNUMSYMS) {
     96           break;
     97         }
     98       }
     99       if (SBREFINE == 0) {
    100         RI = 0;
    101       } else {
    102         if (pStream->read1Bit(&RI) != 0) {
    103           return nullptr;
    104         }
    105       }
    106       if (RI == 0) {
    107         IBI = SBSYMS[IDI];
    108       } else {
    109         if ((pHuffmanDecoder->decodeAValue(SBHUFFRDW, &RDWI) != 0) ||
    110             (pHuffmanDecoder->decodeAValue(SBHUFFRDH, &RDHI) != 0) ||
    111             (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0) ||
    112             (pHuffmanDecoder->decodeAValue(SBHUFFRDY, &RDYI) != 0) ||
    113             (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) {
    114           return nullptr;
    115         }
    116         pStream->alignByte();
    117         nTmp = pStream->getOffset();
    118         IBOI = SBSYMS[IDI];
    119         if (!IBOI)
    120           return nullptr;
    121 
    122         WOI = IBOI->m_nWidth;
    123         HOI = IBOI->m_nHeight;
    124         if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0)
    125           return nullptr;
    126 
    127         std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc());
    128         pGRRD->GRW = WOI + RDWI;
    129         pGRRD->GRH = HOI + RDHI;
    130         pGRRD->GRTEMPLATE = SBRTEMPLATE;
    131         pGRRD->GRREFERENCE = IBOI;
    132         pGRRD->GRREFERENCEDX = (RDWI >> 2) + RDXI;
    133         pGRRD->GRREFERENCEDY = (RDHI >> 2) + RDYI;
    134         pGRRD->TPGRON = 0;
    135         pGRRD->GRAT[0] = SBRAT[0];
    136         pGRRD->GRAT[1] = SBRAT[1];
    137         pGRRD->GRAT[2] = SBRAT[2];
    138         pGRRD->GRAT[3] = SBRAT[3];
    139 
    140         {
    141           std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder(
    142               new CJBig2_ArithDecoder(pStream));
    143           IBI = pGRRD->decode(pArithDecoder.get(), grContext);
    144           if (!IBI)
    145             return nullptr;
    146         }
    147 
    148         pStream->alignByte();
    149         pStream->offset(2);
    150         if ((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) {
    151           delete IBI;
    152           return nullptr;
    153         }
    154       }
    155       if (!IBI) {
    156         continue;
    157       }
    158       WI = IBI->m_nWidth;
    159       HI = IBI->m_nHeight;
    160       if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
    161                               (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
    162         CURS = CURS + WI - 1;
    163       } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) ||
    164                                      (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
    165         CURS = CURS + HI - 1;
    166       }
    167       SI = CURS;
    168       if (TRANSPOSED == 0) {
    169         switch (REFCORNER) {
    170           case JBIG2_CORNER_TOPLEFT:
    171             SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
    172             break;
    173           case JBIG2_CORNER_TOPRIGHT:
    174             SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
    175             break;
    176           case JBIG2_CORNER_BOTTOMLEFT:
    177             SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
    178             break;
    179           case JBIG2_CORNER_BOTTOMRIGHT:
    180             SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
    181             break;
    182         }
    183       } else {
    184         switch (REFCORNER) {
    185           case JBIG2_CORNER_TOPLEFT:
    186             SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
    187             break;
    188           case JBIG2_CORNER_TOPRIGHT:
    189             SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
    190             break;
    191           case JBIG2_CORNER_BOTTOMLEFT:
    192             SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
    193             break;
    194           case JBIG2_CORNER_BOTTOMRIGHT:
    195             SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
    196             break;
    197         }
    198       }
    199       if (RI != 0) {
    200         delete IBI;
    201       }
    202       if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
    203                               (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
    204         CURS = CURS + WI - 1;
    205       } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
    206                                      (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
    207         CURS = CURS + HI - 1;
    208       }
    209       NINSTANCES = NINSTANCES + 1;
    210     }
    211   }
    212   return SBREG.release();
    213 }
    214 
    215 CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
    216                                            JBig2ArithCtx* grContext,
    217                                            JBig2IntDecoderState* pIDS) {
    218   int32_t STRIPT, FIRSTS;
    219   FX_DWORD NINSTANCES;
    220   int32_t DT, DFS, CURS;
    221   int32_t SI, TI;
    222   CJBig2_Image* IBI;
    223   FX_DWORD WI, HI;
    224   int32_t IDS;
    225   int RI;
    226   int32_t RDWI, RDHI, RDXI, RDYI;
    227   CJBig2_Image* IBOI;
    228   FX_DWORD WOI, HOI;
    229   FX_BOOL bFirst;
    230   int32_t bRetained;
    231   CJBig2_ArithIntDecoder* IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH,
    232       *IARDX, *IARDY;
    233   CJBig2_ArithIaidDecoder* IAID;
    234   if (pIDS) {
    235     IADT = pIDS->IADT;
    236     IAFS = pIDS->IAFS;
    237     IADS = pIDS->IADS;
    238     IAIT = pIDS->IAIT;
    239     IARI = pIDS->IARI;
    240     IARDW = pIDS->IARDW;
    241     IARDH = pIDS->IARDH;
    242     IARDX = pIDS->IARDX;
    243     IARDY = pIDS->IARDY;
    244     IAID = pIDS->IAID;
    245     bRetained = TRUE;
    246   } else {
    247     IADT = new CJBig2_ArithIntDecoder();
    248     IAFS = new CJBig2_ArithIntDecoder();
    249     IADS = new CJBig2_ArithIntDecoder();
    250     IAIT = new CJBig2_ArithIntDecoder();
    251     IARI = new CJBig2_ArithIntDecoder();
    252     IARDW = new CJBig2_ArithIntDecoder();
    253     IARDH = new CJBig2_ArithIntDecoder();
    254     IARDX = new CJBig2_ArithIntDecoder();
    255     IARDY = new CJBig2_ArithIntDecoder();
    256     IAID = new CJBig2_ArithIaidDecoder(SBSYMCODELEN);
    257     bRetained = FALSE;
    258   }
    259   std::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH));
    260   SBREG->fill(SBDEFPIXEL);
    261   IADT->decode(pArithDecoder, &STRIPT);
    262   STRIPT *= SBSTRIPS;
    263   STRIPT = -STRIPT;
    264   FIRSTS = 0;
    265   NINSTANCES = 0;
    266   while (NINSTANCES < SBNUMINSTANCES) {
    267     IADT->decode(pArithDecoder, &DT);
    268     DT *= SBSTRIPS;
    269     STRIPT = STRIPT + DT;
    270     bFirst = TRUE;
    271     for (;;) {
    272       if (bFirst) {
    273         IAFS->decode(pArithDecoder, &DFS);
    274         FIRSTS = FIRSTS + DFS;
    275         CURS = FIRSTS;
    276         bFirst = FALSE;
    277       } else {
    278         if (!IADS->decode(pArithDecoder, &IDS))
    279           break;
    280         CURS = CURS + IDS + SBDSOFFSET;
    281       }
    282       if (NINSTANCES >= SBNUMINSTANCES) {
    283         break;
    284       }
    285       int CURT = 0;
    286       if (SBSTRIPS != 1)
    287         IAIT->decode(pArithDecoder, &CURT);
    288 
    289       TI = STRIPT + CURT;
    290       FX_DWORD IDI;
    291       IAID->decode(pArithDecoder, &IDI);
    292       if (IDI >= SBNUMSYMS)
    293         goto failed;
    294 
    295       if (SBREFINE == 0)
    296         RI = 0;
    297       else
    298         IARI->decode(pArithDecoder, &RI);
    299 
    300       if (!SBSYMS[IDI])
    301         goto failed;
    302 
    303       if (RI == 0) {
    304         IBI = SBSYMS[IDI];
    305       } else {
    306         IARDW->decode(pArithDecoder, &RDWI);
    307         IARDH->decode(pArithDecoder, &RDHI);
    308         IARDX->decode(pArithDecoder, &RDXI);
    309         IARDY->decode(pArithDecoder, &RDYI);
    310         IBOI = SBSYMS[IDI];
    311         WOI = IBOI->m_nWidth;
    312         HOI = IBOI->m_nHeight;
    313         if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) {
    314           goto failed;
    315         }
    316         std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc());
    317         pGRRD->GRW = WOI + RDWI;
    318         pGRRD->GRH = HOI + RDHI;
    319         pGRRD->GRTEMPLATE = SBRTEMPLATE;
    320         pGRRD->GRREFERENCE = IBOI;
    321         pGRRD->GRREFERENCEDX = (RDWI >> 1) + RDXI;
    322         pGRRD->GRREFERENCEDY = (RDHI >> 1) + RDYI;
    323         pGRRD->TPGRON = 0;
    324         pGRRD->GRAT[0] = SBRAT[0];
    325         pGRRD->GRAT[1] = SBRAT[1];
    326         pGRRD->GRAT[2] = SBRAT[2];
    327         pGRRD->GRAT[3] = SBRAT[3];
    328         IBI = pGRRD->decode(pArithDecoder, grContext);
    329         if (!IBI)
    330           goto failed;
    331       }
    332       WI = IBI->m_nWidth;
    333       HI = IBI->m_nHeight;
    334       if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) ||
    335                               (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
    336         CURS = CURS + WI - 1;
    337       } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) ||
    338                                      (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) {
    339         CURS = CURS + HI - 1;
    340       }
    341       SI = CURS;
    342       if (TRANSPOSED == 0) {
    343         switch (REFCORNER) {
    344           case JBIG2_CORNER_TOPLEFT:
    345             SBREG->composeFrom(SI, TI, IBI, SBCOMBOP);
    346             break;
    347           case JBIG2_CORNER_TOPRIGHT:
    348             SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP);
    349             break;
    350           case JBIG2_CORNER_BOTTOMLEFT:
    351             SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP);
    352             break;
    353           case JBIG2_CORNER_BOTTOMRIGHT:
    354             SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP);
    355             break;
    356         }
    357       } else {
    358         switch (REFCORNER) {
    359           case JBIG2_CORNER_TOPLEFT:
    360             SBREG->composeFrom(TI, SI, IBI, SBCOMBOP);
    361             break;
    362           case JBIG2_CORNER_TOPRIGHT:
    363             SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP);
    364             break;
    365           case JBIG2_CORNER_BOTTOMLEFT:
    366             SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP);
    367             break;
    368           case JBIG2_CORNER_BOTTOMRIGHT:
    369             SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP);
    370             break;
    371         }
    372       }
    373       if (RI != 0) {
    374         delete IBI;
    375       }
    376       if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
    377                               (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) {
    378         CURS = CURS + WI - 1;
    379       } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) ||
    380                                      (REFCORNER == JBIG2_CORNER_TOPRIGHT))) {
    381         CURS = CURS + HI - 1;
    382       }
    383       NINSTANCES = NINSTANCES + 1;
    384     }
    385   }
    386   if (bRetained == FALSE) {
    387     delete IADT;
    388     delete IAFS;
    389     delete IADS;
    390     delete IAIT;
    391     delete IARI;
    392     delete IARDW;
    393     delete IARDH;
    394     delete IARDX;
    395     delete IARDY;
    396     delete IAID;
    397   }
    398   return SBREG.release();
    399 failed:
    400   if (bRetained == FALSE) {
    401     delete IADT;
    402     delete IAFS;
    403     delete IADS;
    404     delete IAIT;
    405     delete IARI;
    406     delete IARDW;
    407     delete IARDH;
    408     delete IARDX;
    409     delete IARDY;
    410     delete IAID;
    411   }
    412   return nullptr;
    413 }
    414