// 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 "core/fxcodec/jbig2/JBig2_HtrdProc.h" #include #include #include "core/fxcodec/jbig2/JBig2_BitStream.h" #include "core/fxcodec/jbig2/JBig2_GrdProc.h" #include "core/fxcodec/jbig2/JBig2_Image.h" #include "third_party/base/ptr_util.h" std::unique_ptr CJBig2_HTRDProc::DecodeArith( CJBig2_ArithDecoder* pArithDecoder, JBig2ArithCtx* gbContext, PauseIndicatorIface* pPause) { std::unique_ptr HSKIP; if (HENABLESKIP == 1) { HSKIP = pdfium::MakeUnique(HGW, HGH); for (uint32_t mg = 0; mg < HGH; ++mg) { for (uint32_t ng = 0; ng < HGW; ++ng) { int32_t x = (HGX + mg * HRY + ng * HRX) >> 8; int32_t y = (HGY + mg * HRX - ng * HRY) >> 8; if ((x + HPW <= 0) | (x >= static_cast(HBW)) | (y + HPH <= 0) | (y >= static_cast(HPH))) { HSKIP->setPixel(ng, mg, 1); } else { HSKIP->setPixel(ng, mg, 0); } } } } uint32_t HBPP = 1; while (static_cast(1 << HBPP) < HNUMPATS) ++HBPP; CJBig2_GRDProc GRD; GRD.MMR = HMMR; GRD.GBW = HGW; GRD.GBH = HGH; GRD.GBTEMPLATE = HTEMPLATE; GRD.TPGDON = 0; GRD.USESKIP = HENABLESKIP; GRD.SKIP = HSKIP.get(); if (HTEMPLATE <= 1) GRD.GBAT[0] = 3; else GRD.GBAT[0] = 2; GRD.GBAT[1] = -1; if (GRD.GBTEMPLATE == 0) { GRD.GBAT[2] = -3; GRD.GBAT[3] = -1; GRD.GBAT[4] = 2; GRD.GBAT[5] = -2; GRD.GBAT[6] = -2; GRD.GBAT[7] = -2; } uint8_t GSBPP = static_cast(HBPP); std::vector> GSPLANES(GSBPP); for (int32_t i = GSBPP - 1; i >= 0; --i) { std::unique_ptr pImage; FXCODEC_STATUS status = GRD.StartDecodeArith(&pImage, pArithDecoder, gbContext, nullptr); while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) status = GRD.ContinueDecode(pPause, pArithDecoder); if (!pImage) return nullptr; GSPLANES[i] = std::move(pImage); if (i < GSBPP - 1) GSPLANES[i]->composeFrom(0, 0, GSPLANES[i + 1].get(), JBIG2_COMPOSE_XOR); } return DecodeImage(GSPLANES); } std::unique_ptr CJBig2_HTRDProc::DecodeMMR( CJBig2_BitStream* pStream) { uint32_t HBPP = 1; while (static_cast(1 << HBPP) < HNUMPATS) ++HBPP; CJBig2_GRDProc GRD; GRD.MMR = HMMR; GRD.GBW = HGW; GRD.GBH = HGH; uint8_t GSBPP = static_cast(HBPP); std::vector> GSPLANES(GSBPP); GRD.StartDecodeMMR(&GSPLANES[GSBPP - 1], pStream); if (!GSPLANES[GSBPP - 1]) return nullptr; pStream->alignByte(); pStream->offset(3); for (int32_t J = GSBPP - 2; J >= 0; --J) { GRD.StartDecodeMMR(&GSPLANES[J], pStream); if (!GSPLANES[J]) return nullptr; pStream->alignByte(); pStream->offset(3); GSPLANES[J]->composeFrom(0, 0, GSPLANES[J + 1].get(), JBIG2_COMPOSE_XOR); } return DecodeImage(GSPLANES); } std::unique_ptr CJBig2_HTRDProc::DecodeImage( const std::vector>& GSPLANES) { auto HTREG = pdfium::MakeUnique(HBW, HBH); HTREG->fill(HDEFPIXEL); std::vector GSVALS(HGW * HGH); for (uint32_t y = 0; y < HGH; ++y) { for (uint32_t x = 0; x < HGW; ++x) { for (uint8_t J = 0; J < GSPLANES.size(); ++J) GSVALS[y * HGW + x] |= GSPLANES[J]->getPixel(x, y) << J; } } for (uint32_t mg = 0; mg < HGH; ++mg) { for (uint32_t ng = 0; ng < HGW; ++ng) { int32_t x = (HGX + mg * HRY + ng * HRX) >> 8; int32_t y = (HGY + mg * HRX - ng * HRY) >> 8; uint32_t pat_index = std::min(GSVALS[mg * HGW + ng], HNUMPATS - 1); HTREG->composeFrom(x, y, (*HPATS)[pat_index].get(), HCOMBOP); } } return HTREG; }