From 630a28442364f03c1d3d9b48873da42755e1fddf Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Thu, 24 Sep 2015 01:09:57 -0700 Subject: Split up JBig2_GeneralDecoder.cpp. R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1359233002 . --- core/src/fxcodec/jbig2/JBig2_TrdProc.cpp | 438 +++++++++++++++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 core/src/fxcodec/jbig2/JBig2_TrdProc.cpp (limited to 'core/src/fxcodec/jbig2/JBig2_TrdProc.cpp') diff --git a/core/src/fxcodec/jbig2/JBig2_TrdProc.cpp b/core/src/fxcodec/jbig2/JBig2_TrdProc.cpp new file mode 100644 index 0000000000..afa3dba920 --- /dev/null +++ b/core/src/fxcodec/jbig2/JBig2_TrdProc.cpp @@ -0,0 +1,438 @@ +// Copyright 2015 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "JBig2_TrdProc.h" + +#include "../../../../third_party/base/nonstd_unique_ptr.h" +#include "JBig2_ArithDecoder.h" +#include "JBig2_ArithIntDecoder.h" +#include "JBig2_HuffmanDecoder.h" +#include "JBig2_GrrdProc.h" + +CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream, + JBig2ArithCtx* grContext) { + int32_t STRIPT, FIRSTS; + FX_DWORD NINSTANCES; + int32_t DT, DFS, CURS; + uint8_t CURT; + int32_t SI, TI; + FX_DWORD IDI; + CJBig2_Image* IBI; + FX_DWORD WI, HI; + int32_t IDS; + FX_BOOL RI; + int32_t RDWI, RDHI, RDXI, RDYI; + CJBig2_Image* IBOI; + FX_DWORD WOI, HOI; + FX_BOOL bFirst; + FX_DWORD nTmp; + int32_t nVal, nBits; + nonstd::unique_ptr pHuffmanDecoder( + new CJBig2_HuffmanDecoder(pStream)); + nonstd::unique_ptr SBREG(new CJBig2_Image(SBW, SBH)); + SBREG->fill(SBDEFPIXEL); + if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0) + return nullptr; + + STRIPT *= SBSTRIPS; + STRIPT = -STRIPT; + FIRSTS = 0; + NINSTANCES = 0; + while (NINSTANCES < SBNUMINSTANCES) { + if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0) + return nullptr; + + DT *= SBSTRIPS; + STRIPT = STRIPT + DT; + bFirst = TRUE; + for (;;) { + if (bFirst) { + if (pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0) + return nullptr; + + FIRSTS = FIRSTS + DFS; + CURS = FIRSTS; + bFirst = FALSE; + } else { + nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS); + if (nVal == JBIG2_OOB) { + break; + } else if (nVal != 0) { + return nullptr; + } else { + CURS = CURS + IDS + SBDSOFFSET; + } + } + if (SBSTRIPS == 1) { + CURT = 0; + } else { + nTmp = 1; + while ((FX_DWORD)(1 << nTmp) < SBSTRIPS) { + nTmp++; + } + if (pStream->readNBits(nTmp, &nVal) != 0) + return nullptr; + + CURT = nVal; + } + TI = STRIPT + CURT; + nVal = 0; + nBits = 0; + for (;;) { + if (pStream->read1Bit(&nTmp) != 0) + return nullptr; + + nVal = (nVal << 1) | nTmp; + nBits++; + for (IDI = 0; IDI < SBNUMSYMS; IDI++) { + if ((nBits == SBSYMCODES[IDI].codelen) && + (nVal == SBSYMCODES[IDI].code)) { + break; + } + } + if (IDI < SBNUMSYMS) { + break; + } + } + if (SBREFINE == 0) { + RI = 0; + } else { + if (pStream->read1Bit(&RI) != 0) { + return nullptr; + } + } + if (RI == 0) { + IBI = SBSYMS[IDI]; + } else { + if ((pHuffmanDecoder->decodeAValue(SBHUFFRDW, &RDWI) != 0) || + (pHuffmanDecoder->decodeAValue(SBHUFFRDH, &RDHI) != 0) || + (pHuffmanDecoder->decodeAValue(SBHUFFRDX, &RDXI) != 0) || + (pHuffmanDecoder->decodeAValue(SBHUFFRDY, &RDYI) != 0) || + (pHuffmanDecoder->decodeAValue(SBHUFFRSIZE, &nVal) != 0)) { + return nullptr; + } + pStream->alignByte(); + nTmp = pStream->getOffset(); + IBOI = SBSYMS[IDI]; + if (!IBOI) + return nullptr; + + WOI = IBOI->m_nWidth; + HOI = IBOI->m_nHeight; + if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) + return nullptr; + + nonstd::unique_ptr pGRRD(new CJBig2_GRRDProc()); + pGRRD->GRW = WOI + RDWI; + pGRRD->GRH = HOI + RDHI; + pGRRD->GRTEMPLATE = SBRTEMPLATE; + pGRRD->GRREFERENCE = IBOI; + pGRRD->GRREFERENCEDX = (RDWI >> 2) + RDXI; + pGRRD->GRREFERENCEDY = (RDHI >> 2) + RDYI; + pGRRD->TPGRON = 0; + pGRRD->GRAT[0] = SBRAT[0]; + pGRRD->GRAT[1] = SBRAT[1]; + pGRRD->GRAT[2] = SBRAT[2]; + pGRRD->GRAT[3] = SBRAT[3]; + + { + nonstd::unique_ptr pArithDecoder( + new CJBig2_ArithDecoder(pStream)); + IBI = pGRRD->decode(pArithDecoder.get(), grContext); + if (!IBI) + return nullptr; + } + + pStream->alignByte(); + pStream->offset(2); + if ((FX_DWORD)nVal != (pStream->getOffset() - nTmp)) { + delete IBI; + return nullptr; + } + } + if (!IBI) { + continue; + } + WI = IBI->m_nWidth; + HI = IBI->m_nHeight; + if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) || + (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) { + CURS = CURS + WI - 1; + } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) || + (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) { + CURS = CURS + HI - 1; + } + SI = CURS; + if (TRANSPOSED == 0) { + switch (REFCORNER) { + case JBIG2_CORNER_TOPLEFT: + SBREG->composeFrom(SI, TI, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_TOPRIGHT: + SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_BOTTOMLEFT: + SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_BOTTOMRIGHT: + SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP); + break; + } + } else { + switch (REFCORNER) { + case JBIG2_CORNER_TOPLEFT: + SBREG->composeFrom(TI, SI, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_TOPRIGHT: + SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_BOTTOMLEFT: + SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_BOTTOMRIGHT: + SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP); + break; + } + } + if (RI != 0) { + delete IBI; + } + if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) || + (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) { + CURS = CURS + WI - 1; + } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) || + (REFCORNER == JBIG2_CORNER_TOPRIGHT))) { + CURS = CURS + HI - 1; + } + NINSTANCES = NINSTANCES + 1; + } + } + return SBREG.release(); +} + +CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder, + JBig2ArithCtx* grContext, + JBig2IntDecoderState* pIDS) { + int32_t STRIPT, FIRSTS; + FX_DWORD NINSTANCES; + int32_t DT, DFS, CURS; + int32_t CURT; + int32_t SI, TI; + FX_DWORD IDI; + CJBig2_Image* IBI; + FX_DWORD WI, HI; + int32_t IDS; + int RI; + int32_t RDWI, RDHI, RDXI, RDYI; + CJBig2_Image* IBOI; + FX_DWORD WOI, HOI; + FX_BOOL bFirst; + int32_t nRet, nVal; + int32_t bRetained; + CJBig2_ArithIntDecoder* IADT, *IAFS, *IADS, *IAIT, *IARI, *IARDW, *IARDH, + *IARDX, *IARDY; + CJBig2_ArithIaidDecoder* IAID; + if (pIDS) { + IADT = pIDS->IADT; + IAFS = pIDS->IAFS; + IADS = pIDS->IADS; + IAIT = pIDS->IAIT; + IARI = pIDS->IARI; + IARDW = pIDS->IARDW; + IARDH = pIDS->IARDH; + IARDX = pIDS->IARDX; + IARDY = pIDS->IARDY; + IAID = pIDS->IAID; + bRetained = TRUE; + } else { + IADT = new CJBig2_ArithIntDecoder(); + IAFS = new CJBig2_ArithIntDecoder(); + IADS = new CJBig2_ArithIntDecoder(); + IAIT = new CJBig2_ArithIntDecoder(); + IARI = new CJBig2_ArithIntDecoder(); + IARDW = new CJBig2_ArithIntDecoder(); + IARDH = new CJBig2_ArithIntDecoder(); + IARDX = new CJBig2_ArithIntDecoder(); + IARDY = new CJBig2_ArithIntDecoder(); + IAID = new CJBig2_ArithIaidDecoder(SBSYMCODELEN); + bRetained = FALSE; + } + nonstd::unique_ptr SBREG(new CJBig2_Image(SBW, SBH)); + SBREG->fill(SBDEFPIXEL); + if (IADT->decode(pArithDecoder, &STRIPT) == -1) { + goto failed; + } + STRIPT *= SBSTRIPS; + STRIPT = -STRIPT; + FIRSTS = 0; + NINSTANCES = 0; + while (NINSTANCES < SBNUMINSTANCES) { + if (IADT->decode(pArithDecoder, &DT) == -1) { + goto failed; + } + DT *= SBSTRIPS; + STRIPT = STRIPT + DT; + bFirst = TRUE; + for (;;) { + if (bFirst) { + if (IAFS->decode(pArithDecoder, &DFS) == -1) { + goto failed; + } + FIRSTS = FIRSTS + DFS; + CURS = FIRSTS; + bFirst = FALSE; + } else { + nRet = IADS->decode(pArithDecoder, &IDS); + if (nRet == JBIG2_OOB) { + break; + } else if (nRet != 0) { + goto failed; + } else { + CURS = CURS + IDS + SBDSOFFSET; + } + } + if (NINSTANCES >= SBNUMINSTANCES) { + break; + } + if (SBSTRIPS == 1) { + CURT = 0; + } else { + if (IAIT->decode(pArithDecoder, &nVal) == -1) { + goto failed; + } + CURT = nVal; + } + TI = STRIPT + CURT; + if (IAID->decode(pArithDecoder, &nVal) == -1) { + goto failed; + } + IDI = nVal; + if (IDI >= SBNUMSYMS) { + goto failed; + } + if (SBREFINE == 0) { + RI = 0; + } else { + if (IARI->decode(pArithDecoder, &RI) == -1) { + goto failed; + } + } + if (!SBSYMS[IDI]) { + goto failed; + } + if (RI == 0) { + IBI = SBSYMS[IDI]; + } else { + if ((IARDW->decode(pArithDecoder, &RDWI) == -1) || + (IARDH->decode(pArithDecoder, &RDHI) == -1) || + (IARDX->decode(pArithDecoder, &RDXI) == -1) || + (IARDY->decode(pArithDecoder, &RDYI) == -1)) { + goto failed; + } + IBOI = SBSYMS[IDI]; + WOI = IBOI->m_nWidth; + HOI = IBOI->m_nHeight; + if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) { + goto failed; + } + nonstd::unique_ptr pGRRD(new CJBig2_GRRDProc()); + pGRRD->GRW = WOI + RDWI; + pGRRD->GRH = HOI + RDHI; + pGRRD->GRTEMPLATE = SBRTEMPLATE; + pGRRD->GRREFERENCE = IBOI; + pGRRD->GRREFERENCEDX = (RDWI >> 1) + RDXI; + pGRRD->GRREFERENCEDY = (RDHI >> 1) + RDYI; + pGRRD->TPGRON = 0; + pGRRD->GRAT[0] = SBRAT[0]; + pGRRD->GRAT[1] = SBRAT[1]; + pGRRD->GRAT[2] = SBRAT[2]; + pGRRD->GRAT[3] = SBRAT[3]; + IBI = pGRRD->decode(pArithDecoder, grContext); + if (!IBI) + goto failed; + } + WI = IBI->m_nWidth; + HI = IBI->m_nHeight; + if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) || + (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) { + CURS = CURS + WI - 1; + } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) || + (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) { + CURS = CURS + HI - 1; + } + SI = CURS; + if (TRANSPOSED == 0) { + switch (REFCORNER) { + case JBIG2_CORNER_TOPLEFT: + SBREG->composeFrom(SI, TI, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_TOPRIGHT: + SBREG->composeFrom(SI - WI + 1, TI, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_BOTTOMLEFT: + SBREG->composeFrom(SI, TI - HI + 1, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_BOTTOMRIGHT: + SBREG->composeFrom(SI - WI + 1, TI - HI + 1, IBI, SBCOMBOP); + break; + } + } else { + switch (REFCORNER) { + case JBIG2_CORNER_TOPLEFT: + SBREG->composeFrom(TI, SI, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_TOPRIGHT: + SBREG->composeFrom(TI - WI + 1, SI, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_BOTTOMLEFT: + SBREG->composeFrom(TI, SI - HI + 1, IBI, SBCOMBOP); + break; + case JBIG2_CORNER_BOTTOMRIGHT: + SBREG->composeFrom(TI - WI + 1, SI - HI + 1, IBI, SBCOMBOP); + break; + } + } + if (RI != 0) { + delete IBI; + } + if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) || + (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) { + CURS = CURS + WI - 1; + } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) || + (REFCORNER == JBIG2_CORNER_TOPRIGHT))) { + CURS = CURS + HI - 1; + } + NINSTANCES = NINSTANCES + 1; + } + } + if (bRetained == FALSE) { + delete IADT; + delete IAFS; + delete IADS; + delete IAIT; + delete IARI; + delete IARDW; + delete IARDH; + delete IARDX; + delete IARDY; + delete IAID; + } + return SBREG.release(); +failed: + if (bRetained == FALSE) { + delete IADT; + delete IAFS; + delete IADS; + delete IAIT; + delete IARI; + delete IARDW; + delete IARDH; + delete IARDX; + delete IARDY; + delete IAID; + } + return nullptr; +} -- cgit v1.2.3