CJBig2_Image* CJBig2_TRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder, JBig2ArithCtx* grContext, JBig2IntDecoderState* pIDS) { std::unique_ptr<CJBig2_ArithIntDecoder> IADT; std::unique_ptr<CJBig2_ArithIntDecoder> IAFS; std::unique_ptr<CJBig2_ArithIntDecoder> IADS; std::unique_ptr<CJBig2_ArithIntDecoder> IAIT; std::unique_ptr<CJBig2_ArithIntDecoder> IARI; std::unique_ptr<CJBig2_ArithIntDecoder> IARDW; std::unique_ptr<CJBig2_ArithIntDecoder> IARDH; std::unique_ptr<CJBig2_ArithIntDecoder> IARDX; std::unique_ptr<CJBig2_ArithIntDecoder> IARDY; std::unique_ptr<CJBig2_ArithIaidDecoder> IAID; CJBig2_ArithIntDecoder* pIADT; CJBig2_ArithIntDecoder* pIAFS; CJBig2_ArithIntDecoder* pIADS; CJBig2_ArithIntDecoder* pIAIT; CJBig2_ArithIntDecoder* pIARI; CJBig2_ArithIntDecoder* pIARDW; CJBig2_ArithIntDecoder* pIARDH; CJBig2_ArithIntDecoder* pIARDX; CJBig2_ArithIntDecoder* pIARDY; CJBig2_ArithIaidDecoder* pIAID; if (pIDS) { pIADT = pIDS->IADT; pIAFS = pIDS->IAFS; pIADS = pIDS->IADS; pIAIT = pIDS->IAIT; pIARI = pIDS->IARI; pIARDW = pIDS->IARDW; pIARDH = pIDS->IARDH; pIARDX = pIDS->IARDX; pIARDY = pIDS->IARDY; pIAID = pIDS->IAID; } else { IADT = pdfium::MakeUnique<CJBig2_ArithIntDecoder>(); IAFS = pdfium::MakeUnique<CJBig2_ArithIntDecoder>(); IADS = pdfium::MakeUnique<CJBig2_ArithIntDecoder>(); IAIT = pdfium::MakeUnique<CJBig2_ArithIntDecoder>(); IARI = pdfium::MakeUnique<CJBig2_ArithIntDecoder>(); IARDW = pdfium::MakeUnique<CJBig2_ArithIntDecoder>(); IARDH = pdfium::MakeUnique<CJBig2_ArithIntDecoder>(); IARDX = pdfium::MakeUnique<CJBig2_ArithIntDecoder>(); IARDY = pdfium::MakeUnique<CJBig2_ArithIntDecoder>(); IAID = pdfium::MakeUnique<CJBig2_ArithIaidDecoder>(SBSYMCODELEN); pIADT = IADT.get(); pIAFS = IAFS.get(); pIADS = IADS.get(); pIAIT = IAIT.get(); pIARI = IARI.get(); pIARDW = IARDW.get(); pIARDH = IARDH.get(); pIARDX = IARDX.get(); pIARDY = IARDY.get(); pIAID = IAID.get(); } std::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH)); SBREG->fill(SBDEFPIXEL); int32_t STRIPT; if (!pIADT->decode(pArithDecoder, &STRIPT)) return nullptr; STRIPT *= SBSTRIPS; STRIPT = -STRIPT; int32_t FIRSTS = 0; uint32_t NINSTANCES = 0; while (NINSTANCES < SBNUMINSTANCES) { int32_t CURS = 0; int32_t DT; if (!pIADT->decode(pArithDecoder, &DT)) return nullptr; DT *= SBSTRIPS; STRIPT += DT; bool bFirst = true; for (;;) { if (bFirst) { int32_t DFS; pIAFS->decode(pArithDecoder, &DFS); FIRSTS += DFS; CURS = FIRSTS; bFirst = false; } else { int32_t IDS; if (!pIADS->decode(pArithDecoder, &IDS)) break; CURS += IDS + SBDSOFFSET; } if (NINSTANCES >= SBNUMINSTANCES) { break; } int CURT = 0; if (SBSTRIPS != 1) pIAIT->decode(pArithDecoder, &CURT); int32_t TI = STRIPT + CURT; uint32_t IDI; pIAID->decode(pArithDecoder, &IDI); if (IDI >= SBNUMSYMS) return nullptr; int RI; if (SBREFINE == 0) RI = 0; else pIARI->decode(pArithDecoder, &RI); std::unique_ptr<CJBig2_Image> IBI; CJBig2_Image* pIBI; if (RI == 0) { pIBI = SBSYMS[IDI]; } else { int32_t RDWI; int32_t RDHI; int32_t RDXI; int32_t RDYI; pIARDW->decode(pArithDecoder, &RDWI); pIARDH->decode(pArithDecoder, &RDHI); pIARDX->decode(pArithDecoder, &RDXI); pIARDY->decode(pArithDecoder, &RDYI); CJBig2_Image* IBOI = SBSYMS[IDI]; if (!IBOI) return nullptr; uint32_t WOI = IBOI->width(); uint32_t HOI = IBOI->height(); if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) return nullptr; std::unique_ptr<CJBig2_GRRDProc> 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.reset(pGRRD->decode(pArithDecoder, grContext)); pIBI = IBI.get(); } if (!pIBI) return nullptr; uint32_t WI = pIBI->width(); uint32_t HI = pIBI->height(); if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPRIGHT) || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) { CURS += WI - 1; } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_BOTTOMLEFT) || (REFCORNER == JBIG2_CORNER_BOTTOMRIGHT))) { CURS += HI - 1; } int32_t SI = CURS; if (TRANSPOSED == 0) { switch (REFCORNER) { case JBIG2_CORNER_TOPLEFT: SBREG->composeFrom(SI, TI, pIBI, SBCOMBOP); break; case JBIG2_CORNER_TOPRIGHT: SBREG->composeFrom(SI - WI + 1, TI, pIBI, SBCOMBOP); break; case JBIG2_CORNER_BOTTOMLEFT: SBREG->composeFrom(SI, TI - HI + 1, pIBI, SBCOMBOP); break; case JBIG2_CORNER_BOTTOMRIGHT: SBREG->composeFrom(SI - WI + 1, TI - HI + 1, pIBI, SBCOMBOP); break; } } else { switch (REFCORNER) { case JBIG2_CORNER_TOPLEFT: SBREG->composeFrom(TI, SI, pIBI, SBCOMBOP); break; case JBIG2_CORNER_TOPRIGHT: SBREG->composeFrom(TI - WI + 1, SI, pIBI, SBCOMBOP); break; case JBIG2_CORNER_BOTTOMLEFT: SBREG->composeFrom(TI, SI - HI + 1, pIBI, SBCOMBOP); break; case JBIG2_CORNER_BOTTOMRIGHT: SBREG->composeFrom(TI - WI + 1, SI - HI + 1, pIBI, SBCOMBOP); break; } } if (TRANSPOSED == 0 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) || (REFCORNER == JBIG2_CORNER_BOTTOMLEFT))) { CURS += WI - 1; } else if (TRANSPOSED == 1 && ((REFCORNER == JBIG2_CORNER_TOPLEFT) || (REFCORNER == JBIG2_CORNER_TOPRIGHT))) { CURS += HI - 1; } ++NINSTANCES; } } return SBREG.release(); }
CJBig2_SymbolDict* CJBig2_SDDProc::decode_Arith( CJBig2_ArithDecoder* pArithDecoder, std::vector<JBig2ArithCtx>* gbContext, std::vector<JBig2ArithCtx>* grContext) { CJBig2_Image** SDNEWSYMS; FX_DWORD HCHEIGHT, NSYMSDECODED; int32_t HCDH; FX_DWORD SYMWIDTH, TOTWIDTH; int32_t DW; CJBig2_Image* BS; FX_DWORD I, J, REFAGGNINST; FX_BOOL* EXFLAGS; FX_DWORD EXINDEX; FX_BOOL CUREXFLAG; FX_DWORD EXRUNLENGTH; FX_DWORD nTmp; FX_DWORD SBNUMSYMS; uint8_t SBSYMCODELEN; int32_t RDXI, RDYI; CJBig2_Image** SBSYMS; std::unique_ptr<CJBig2_ArithIaidDecoder> IAID; std::unique_ptr<CJBig2_SymbolDict> pDict; std::unique_ptr<CJBig2_ArithIntDecoder> IADH(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IADW(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IAAI(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IARDX(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IARDY(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IAEX(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IADT(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IAFS(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IADS(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IAIT(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IARI(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IARDW(new CJBig2_ArithIntDecoder); std::unique_ptr<CJBig2_ArithIntDecoder> IARDH(new CJBig2_ArithIntDecoder); nTmp = 0; while ((FX_DWORD)(1 << nTmp) < (SDNUMINSYMS + SDNUMNEWSYMS)) { nTmp++; } IAID.reset(new CJBig2_ArithIaidDecoder((uint8_t)nTmp)); SDNEWSYMS = FX_Alloc(CJBig2_Image*, SDNUMNEWSYMS); FXSYS_memset(SDNEWSYMS, 0, SDNUMNEWSYMS * sizeof(CJBig2_Image*)); HCHEIGHT = 0; NSYMSDECODED = 0; while (NSYMSDECODED < SDNUMNEWSYMS) { BS = nullptr; IADH->decode(pArithDecoder, &HCDH); HCHEIGHT = HCHEIGHT + HCDH; if ((int)HCHEIGHT < 0 || (int)HCHEIGHT > JBIG2_MAX_IMAGE_SIZE) { goto failed; } SYMWIDTH = 0; TOTWIDTH = 0; for (;;) { if (!IADW->decode(pArithDecoder, &DW)) break; if (NSYMSDECODED >= SDNUMNEWSYMS) goto failed; SYMWIDTH = SYMWIDTH + DW; if ((int)SYMWIDTH < 0 || (int)SYMWIDTH > JBIG2_MAX_IMAGE_SIZE) goto failed; if (HCHEIGHT == 0 || SYMWIDTH == 0) { TOTWIDTH = TOTWIDTH + SYMWIDTH; SDNEWSYMS[NSYMSDECODED] = nullptr; NSYMSDECODED = NSYMSDECODED + 1; continue; } TOTWIDTH = TOTWIDTH + SYMWIDTH; if (SDREFAGG == 0) { std::unique_ptr<CJBig2_GRDProc> pGRD(new CJBig2_GRDProc()); pGRD->MMR = 0; pGRD->GBW = SYMWIDTH; pGRD->GBH = HCHEIGHT; pGRD->GBTEMPLATE = SDTEMPLATE; pGRD->TPGDON = 0; pGRD->USESKIP = 0; pGRD->GBAT[0] = SDAT[0]; pGRD->GBAT[1] = SDAT[1]; pGRD->GBAT[2] = SDAT[2]; pGRD->GBAT[3] = SDAT[3]; pGRD->GBAT[4] = SDAT[4]; pGRD->GBAT[5] = SDAT[5]; pGRD->GBAT[6] = SDAT[6]; pGRD->GBAT[7] = SDAT[7]; BS = pGRD->decode_Arith(pArithDecoder, gbContext->data()); if (!BS) { goto failed; } } else { IAAI->decode(pArithDecoder, (int*)&REFAGGNINST); if (REFAGGNINST > 1) { std::unique_ptr<CJBig2_TRDProc> pDecoder(new CJBig2_TRDProc()); pDecoder->SBHUFF = SDHUFF; pDecoder->SBREFINE = 1; pDecoder->SBW = SYMWIDTH; pDecoder->SBH = HCHEIGHT; pDecoder->SBNUMINSTANCES = REFAGGNINST; pDecoder->SBSTRIPS = 1; pDecoder->SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED; SBNUMSYMS = pDecoder->SBNUMSYMS; nTmp = 0; while ((FX_DWORD)(1 << nTmp) < SBNUMSYMS) { nTmp++; } SBSYMCODELEN = (uint8_t)nTmp; pDecoder->SBSYMCODELEN = SBSYMCODELEN; SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS); JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*)); JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*)); pDecoder->SBSYMS = SBSYMS; pDecoder->SBDEFPIXEL = 0; pDecoder->SBCOMBOP = JBIG2_COMPOSE_OR; pDecoder->TRANSPOSED = 0; pDecoder->REFCORNER = JBIG2_CORNER_TOPLEFT; pDecoder->SBDSOFFSET = 0; std::unique_ptr<CJBig2_HuffmanTable> SBHUFFFS(new CJBig2_HuffmanTable( HuffmanTable_B6, FX_ArraySize(HuffmanTable_B6), HuffmanTable_HTOOB_B6)); std::unique_ptr<CJBig2_HuffmanTable> SBHUFFDS(new CJBig2_HuffmanTable( HuffmanTable_B8, FX_ArraySize(HuffmanTable_B8), HuffmanTable_HTOOB_B8)); std::unique_ptr<CJBig2_HuffmanTable> SBHUFFDT(new CJBig2_HuffmanTable( HuffmanTable_B11, FX_ArraySize(HuffmanTable_B11), HuffmanTable_HTOOB_B11)); std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDW( new CJBig2_HuffmanTable(HuffmanTable_B15, FX_ArraySize(HuffmanTable_B15), HuffmanTable_HTOOB_B15)); std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDH( new CJBig2_HuffmanTable(HuffmanTable_B15, FX_ArraySize(HuffmanTable_B15), HuffmanTable_HTOOB_B15)); std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDX( new CJBig2_HuffmanTable(HuffmanTable_B15, FX_ArraySize(HuffmanTable_B15), HuffmanTable_HTOOB_B15)); std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRDY( new CJBig2_HuffmanTable(HuffmanTable_B15, FX_ArraySize(HuffmanTable_B15), HuffmanTable_HTOOB_B15)); std::unique_ptr<CJBig2_HuffmanTable> SBHUFFRSIZE( new CJBig2_HuffmanTable(HuffmanTable_B1, FX_ArraySize(HuffmanTable_B1), HuffmanTable_HTOOB_B1)); pDecoder->SBHUFFFS = SBHUFFFS.get(); pDecoder->SBHUFFDS = SBHUFFDS.get(); pDecoder->SBHUFFDT = SBHUFFDT.get(); pDecoder->SBHUFFRDW = SBHUFFRDW.get(); pDecoder->SBHUFFRDH = SBHUFFRDH.get(); pDecoder->SBHUFFRDX = SBHUFFRDX.get(); pDecoder->SBHUFFRDY = SBHUFFRDY.get(); pDecoder->SBHUFFRSIZE = SBHUFFRSIZE.get(); pDecoder->SBRTEMPLATE = SDRTEMPLATE; pDecoder->SBRAT[0] = SDRAT[0]; pDecoder->SBRAT[1] = SDRAT[1]; pDecoder->SBRAT[2] = SDRAT[2]; pDecoder->SBRAT[3] = SDRAT[3]; JBig2IntDecoderState ids; ids.IADT = IADT.get(); ids.IAFS = IAFS.get(); ids.IADS = IADS.get(); ids.IAIT = IAIT.get(); ids.IARI = IARI.get(); ids.IARDW = IARDW.get(); ids.IARDH = IARDH.get(); ids.IARDX = IARDX.get(); ids.IARDY = IARDY.get(); ids.IAID = IAID.get(); BS = pDecoder->decode_Arith(pArithDecoder, grContext->data(), &ids); if (!BS) { FX_Free(SBSYMS); goto failed; } FX_Free(SBSYMS); } else if (REFAGGNINST == 1) { SBNUMSYMS = SDNUMINSYMS + NSYMSDECODED; FX_DWORD IDI; IAID->decode(pArithDecoder, &IDI); IARDX->decode(pArithDecoder, &RDXI); IARDY->decode(pArithDecoder, &RDYI); if (IDI >= SBNUMSYMS) { goto failed; } SBSYMS = FX_Alloc(CJBig2_Image*, SBNUMSYMS); JBIG2_memcpy(SBSYMS, SDINSYMS, SDNUMINSYMS * sizeof(CJBig2_Image*)); JBIG2_memcpy(SBSYMS + SDNUMINSYMS, SDNEWSYMS, NSYMSDECODED * sizeof(CJBig2_Image*)); if (!SBSYMS[IDI]) { FX_Free(SBSYMS); goto failed; } std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc()); pGRRD->GRW = SYMWIDTH; pGRRD->GRH = HCHEIGHT; pGRRD->GRTEMPLATE = SDRTEMPLATE; pGRRD->GRREFERENCE = SBSYMS[IDI]; pGRRD->GRREFERENCEDX = RDXI; pGRRD->GRREFERENCEDY = RDYI; pGRRD->TPGRON = 0; pGRRD->GRAT[0] = SDRAT[0]; pGRRD->GRAT[1] = SDRAT[1]; pGRRD->GRAT[2] = SDRAT[2]; pGRRD->GRAT[3] = SDRAT[3]; BS = pGRRD->decode(pArithDecoder, grContext->data()); if (!BS) { FX_Free(SBSYMS); goto failed; } FX_Free(SBSYMS); } }
CJBig2_Image* CJBig2_TRDProc::decode_Huffman(CJBig2_BitStream* pStream, JBig2ArithCtx* grContext) { std::unique_ptr<CJBig2_HuffmanDecoder> pHuffmanDecoder( new CJBig2_HuffmanDecoder(pStream)); std::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH)); SBREG->fill(SBDEFPIXEL); int32_t STRIPT; if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &STRIPT) != 0) return nullptr; STRIPT *= SBSTRIPS; STRIPT = -STRIPT; int32_t FIRSTS = 0; uint32_t NINSTANCES = 0; while (NINSTANCES < SBNUMINSTANCES) { int32_t DT; if (pHuffmanDecoder->decodeAValue(SBHUFFDT, &DT) != 0) return nullptr; DT *= SBSTRIPS; STRIPT = STRIPT + DT; bool bFirst = true; int32_t CURS = 0; for (;;) { if (bFirst) { int32_t DFS; if (pHuffmanDecoder->decodeAValue(SBHUFFFS, &DFS) != 0) return nullptr; FIRSTS = FIRSTS + DFS; CURS = FIRSTS; bFirst = false; } else { int32_t IDS; int32_t nVal = pHuffmanDecoder->decodeAValue(SBHUFFDS, &IDS); if (nVal == JBIG2_OOB) { break; } else if (nVal != 0) { return nullptr; } else { CURS = CURS + IDS + SBDSOFFSET; } } uint8_t CURT = 0; if (SBSTRIPS != 1) { uint32_t nTmp = 1; while ((uint32_t)(1 << nTmp) < SBSTRIPS) { nTmp++; } int32_t nVal; if (pStream->readNBits(nTmp, &nVal) != 0) return nullptr; CURT = nVal; } int32_t TI = STRIPT + CURT; int32_t nVal = 0; int32_t nBits = 0; uint32_t IDI; for (;;) { uint32_t nTmp; 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; } } bool RI = 0; if (SBREFINE != 0 && pStream->read1Bit(&RI) != 0) { return nullptr; } CJBig2_Image* IBI = nullptr; if (RI == 0) { IBI = SBSYMS[IDI]; } else { int32_t RDWI; int32_t RDHI; int32_t RDXI; int32_t RDYI; 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(); uint32_t nTmp = pStream->getOffset(); CJBig2_Image* IBOI = SBSYMS[IDI]; if (!IBOI) return nullptr; uint32_t WOI = IBOI->width(); uint32_t HOI = IBOI->height(); if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) return nullptr; std::unique_ptr<CJBig2_GRRDProc> 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]; { std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( new CJBig2_ArithDecoder(pStream)); IBI = pGRRD->decode(pArithDecoder.get(), grContext); if (!IBI) return nullptr; } pStream->alignByte(); pStream->offset(2); if ((uint32_t)nVal != (pStream->getOffset() - nTmp)) { delete IBI; return nullptr; } } if (!IBI) { continue; } uint32_t WI = IBI->width(); uint32_t HI = IBI->height(); 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; } int32_t 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 SI, TI; 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 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; } std::unique_ptr<CJBig2_Image> SBREG(new CJBig2_Image(SBW, SBH)); SBREG->fill(SBDEFPIXEL); IADT->decode(pArithDecoder, &STRIPT); STRIPT *= SBSTRIPS; STRIPT = -STRIPT; FIRSTS = 0; NINSTANCES = 0; while (NINSTANCES < SBNUMINSTANCES) { IADT->decode(pArithDecoder, &DT); DT *= SBSTRIPS; STRIPT = STRIPT + DT; bFirst = TRUE; for (;;) { if (bFirst) { IAFS->decode(pArithDecoder, &DFS); FIRSTS = FIRSTS + DFS; CURS = FIRSTS; bFirst = FALSE; } else { if (!IADS->decode(pArithDecoder, &IDS)) break; CURS = CURS + IDS + SBDSOFFSET; } if (NINSTANCES >= SBNUMINSTANCES) { break; } int CURT = 0; if (SBSTRIPS != 1) IAIT->decode(pArithDecoder, &CURT); TI = STRIPT + CURT; FX_DWORD IDI; IAID->decode(pArithDecoder, &IDI); if (IDI >= SBNUMSYMS) goto failed; if (SBREFINE == 0) RI = 0; else IARI->decode(pArithDecoder, &RI); if (!SBSYMS[IDI]) goto failed; if (RI == 0) { IBI = SBSYMS[IDI]; } else { IARDW->decode(pArithDecoder, &RDWI); IARDH->decode(pArithDecoder, &RDHI); IARDX->decode(pArithDecoder, &RDXI); IARDY->decode(pArithDecoder, &RDYI); IBOI = SBSYMS[IDI]; WOI = IBOI->m_nWidth; HOI = IBOI->m_nHeight; if ((int)(WOI + RDWI) < 0 || (int)(HOI + RDHI) < 0) { goto failed; } std::unique_ptr<CJBig2_GRRDProc> 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; }