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_HtrdProc.h" 8 9 #include <algorithm> 10 #include <utility> 11 12 #include "core/fxcodec/jbig2/JBig2_BitStream.h" 13 #include "core/fxcodec/jbig2/JBig2_GrdProc.h" 14 #include "core/fxcodec/jbig2/JBig2_Image.h" 15 #include "third_party/base/ptr_util.h" 16 17 std::unique_ptr<CJBig2_Image> CJBig2_HTRDProc::decode_Arith( 18 CJBig2_ArithDecoder* pArithDecoder, 19 JBig2ArithCtx* gbContext, 20 IFX_PauseIndicator* pPause) { 21 std::unique_ptr<CJBig2_Image> HSKIP; 22 if (HENABLESKIP == 1) { 23 HSKIP = pdfium::MakeUnique<CJBig2_Image>(HGW, HGH); 24 for (uint32_t mg = 0; mg < HGH; ++mg) { 25 for (uint32_t ng = 0; ng < HGW; ++ng) { 26 int32_t x = (HGX + mg * HRY + ng * HRX) >> 8; 27 int32_t y = (HGY + mg * HRX - ng * HRY) >> 8; 28 if ((x + HPW <= 0) | (x >= static_cast<int32_t>(HBW)) | (y + HPH <= 0) | 29 (y >= static_cast<int32_t>(HPH))) { 30 HSKIP->setPixel(ng, mg, 1); 31 } else { 32 HSKIP->setPixel(ng, mg, 0); 33 } 34 } 35 } 36 } 37 uint32_t HBPP = 1; 38 while (static_cast<uint32_t>(1 << HBPP) < HNUMPATS) 39 ++HBPP; 40 41 CJBig2_GRDProc GRD; 42 GRD.MMR = HMMR; 43 GRD.GBW = HGW; 44 GRD.GBH = HGH; 45 GRD.GBTEMPLATE = HTEMPLATE; 46 GRD.TPGDON = 0; 47 GRD.USESKIP = HENABLESKIP; 48 GRD.SKIP = HSKIP.get(); 49 if (HTEMPLATE <= 1) 50 GRD.GBAT[0] = 3; 51 else 52 GRD.GBAT[0] = 2; 53 GRD.GBAT[1] = -1; 54 if (GRD.GBTEMPLATE == 0) { 55 GRD.GBAT[2] = -3; 56 GRD.GBAT[3] = -1; 57 GRD.GBAT[4] = 2; 58 GRD.GBAT[5] = -2; 59 GRD.GBAT[6] = -2; 60 GRD.GBAT[7] = -2; 61 } 62 63 uint8_t GSBPP = static_cast<uint8_t>(HBPP); 64 std::vector<std::unique_ptr<CJBig2_Image>> GSPLANES(GSBPP); 65 for (int32_t i = GSBPP - 1; i >= 0; --i) { 66 std::unique_ptr<CJBig2_Image> pImage; 67 FXCODEC_STATUS status = 68 GRD.Start_decode_Arith(&pImage, pArithDecoder, gbContext, nullptr); 69 while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) 70 status = GRD.Continue_decode(pPause, pArithDecoder); 71 72 if (!pImage) 73 return nullptr; 74 75 GSPLANES[i] = std::move(pImage); 76 if (i < GSBPP - 1) 77 GSPLANES[i]->composeFrom(0, 0, GSPLANES[i + 1].get(), JBIG2_COMPOSE_XOR); 78 } 79 return decode_image(GSPLANES); 80 } 81 82 std::unique_ptr<CJBig2_Image> CJBig2_HTRDProc::decode_MMR( 83 CJBig2_BitStream* pStream) { 84 uint32_t HBPP = 1; 85 while (static_cast<uint32_t>(1 << HBPP) < HNUMPATS) 86 ++HBPP; 87 88 CJBig2_GRDProc GRD; 89 GRD.MMR = HMMR; 90 GRD.GBW = HGW; 91 GRD.GBH = HGH; 92 93 uint8_t GSBPP = static_cast<uint8_t>(HBPP); 94 std::vector<std::unique_ptr<CJBig2_Image>> GSPLANES(GSBPP); 95 GRD.Start_decode_MMR(&GSPLANES[GSBPP - 1], pStream); 96 if (!GSPLANES[GSBPP - 1]) 97 return nullptr; 98 99 pStream->alignByte(); 100 pStream->offset(3); 101 for (int32_t J = GSBPP - 2; J >= 0; --J) { 102 GRD.Start_decode_MMR(&GSPLANES[J], pStream); 103 if (!GSPLANES[J]) 104 return nullptr; 105 106 pStream->alignByte(); 107 pStream->offset(3); 108 GSPLANES[J]->composeFrom(0, 0, GSPLANES[J + 1].get(), JBIG2_COMPOSE_XOR); 109 } 110 return decode_image(GSPLANES); 111 } 112 113 std::unique_ptr<CJBig2_Image> CJBig2_HTRDProc::decode_image( 114 const std::vector<std::unique_ptr<CJBig2_Image>>& GSPLANES) { 115 auto HTREG = pdfium::MakeUnique<CJBig2_Image>(HBW, HBH); 116 HTREG->fill(HDEFPIXEL); 117 std::vector<uint32_t> GSVALS(HGW * HGH); 118 for (uint32_t y = 0; y < HGH; ++y) { 119 for (uint32_t x = 0; x < HGW; ++x) { 120 for (uint8_t J = 0; J < GSPLANES.size(); ++J) 121 GSVALS[y * HGW + x] |= GSPLANES[J]->getPixel(x, y) << J; 122 } 123 } 124 for (uint32_t mg = 0; mg < HGH; ++mg) { 125 for (uint32_t ng = 0; ng < HGW; ++ng) { 126 int32_t x = (HGX + mg * HRY + ng * HRX) >> 8; 127 int32_t y = (HGY + mg * HRX - ng * HRY) >> 8; 128 uint32_t pat_index = std::min(GSVALS[mg * HGW + ng], HNUMPATS - 1); 129 HTREG->composeFrom(x, y, (*HPATS)[pat_index].get(), HCOMBOP); 130 } 131 } 132 return HTREG; 133 } 134