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