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 <memory>
10 
11 #include "core/fxcodec/jbig2/JBig2_GsidProc.h"
12 #include "core/fxcrt/fx_basic.h"
13 #include "third_party/base/ptr_util.h"
14 
decode_Arith(CJBig2_ArithDecoder * pArithDecoder,JBig2ArithCtx * gbContext,IFX_Pause * pPause)15 CJBig2_Image* CJBig2_HTRDProc::decode_Arith(CJBig2_ArithDecoder* pArithDecoder,
16                                             JBig2ArithCtx* gbContext,
17                                             IFX_Pause* pPause) {
18   uint32_t ng, mg;
19   int32_t x, y;
20   uint32_t HBPP;
21   uint32_t* GI;
22   std::unique_ptr<CJBig2_Image> HSKIP;
23   std::unique_ptr<CJBig2_Image> HTREG(new CJBig2_Image(HBW, HBH));
24   HTREG->fill(HDEFPIXEL);
25   if (HENABLESKIP == 1) {
26     HSKIP = pdfium::MakeUnique<CJBig2_Image>(HGW, HGH);
27     for (mg = 0; mg < HGH; mg++) {
28       for (ng = 0; ng < HGW; ng++) {
29         x = (HGX + mg * HRY + ng * HRX) >> 8;
30         y = (HGY + mg * HRX - ng * HRY) >> 8;
31         if ((x + HPW <= 0) | (x >= (int32_t)HBW) | (y + HPH <= 0) |
32             (y >= (int32_t)HPH)) {
33           HSKIP->setPixel(ng, mg, 1);
34         } else {
35           HSKIP->setPixel(ng, mg, 0);
36         }
37       }
38     }
39   }
40   HBPP = 1;
41   while ((uint32_t)(1 << HBPP) < HNUMPATS) {
42     HBPP++;
43   }
44   std::unique_ptr<CJBig2_GSIDProc> pGID(new CJBig2_GSIDProc());
45   pGID->GSMMR = HMMR;
46   pGID->GSW = HGW;
47   pGID->GSH = HGH;
48   pGID->GSBPP = (uint8_t)HBPP;
49   pGID->GSUSESKIP = HENABLESKIP;
50   pGID->GSKIP = HSKIP.get();
51   pGID->GSTEMPLATE = HTEMPLATE;
52   GI = pGID->decode_Arith(pArithDecoder, gbContext, pPause);
53   if (!GI)
54     return nullptr;
55 
56   for (mg = 0; mg < HGH; mg++) {
57     for (ng = 0; ng < HGW; ng++) {
58       x = (HGX + mg * HRY + ng * HRX) >> 8;
59       y = (HGY + mg * HRX - ng * HRY) >> 8;
60       uint32_t pat_index = GI[mg * HGW + ng];
61       if (pat_index >= HNUMPATS) {
62         pat_index = HNUMPATS - 1;
63       }
64       HTREG->composeFrom(x, y, HPATS[pat_index], HCOMBOP);
65     }
66   }
67   FX_Free(GI);
68   return HTREG.release();
69 }
70 
decode_MMR(CJBig2_BitStream * pStream,IFX_Pause * pPause)71 CJBig2_Image* CJBig2_HTRDProc::decode_MMR(CJBig2_BitStream* pStream,
72                                           IFX_Pause* pPause) {
73   uint32_t ng, mg;
74   int32_t x, y;
75   uint32_t* GI;
76   std::unique_ptr<CJBig2_Image> HTREG(new CJBig2_Image(HBW, HBH));
77   HTREG->fill(HDEFPIXEL);
78   uint32_t HBPP = 1;
79   while ((uint32_t)(1 << HBPP) < HNUMPATS) {
80     HBPP++;
81   }
82   std::unique_ptr<CJBig2_GSIDProc> pGID(new CJBig2_GSIDProc());
83   pGID->GSMMR = HMMR;
84   pGID->GSW = HGW;
85   pGID->GSH = HGH;
86   pGID->GSBPP = (uint8_t)HBPP;
87   pGID->GSUSESKIP = 0;
88   GI = pGID->decode_MMR(pStream, pPause);
89   if (!GI)
90     return nullptr;
91 
92   for (mg = 0; mg < HGH; mg++) {
93     for (ng = 0; ng < HGW; ng++) {
94       x = (HGX + mg * HRY + ng * HRX) >> 8;
95       y = (HGY + mg * HRX - ng * HRY) >> 8;
96       uint32_t pat_index = GI[mg * HGW + ng];
97       if (pat_index >= HNUMPATS) {
98         pat_index = HNUMPATS - 1;
99       }
100       HTREG->composeFrom(x, y, HPATS[pat_index], HCOMBOP);
101     }
102   }
103   FX_Free(GI);
104   return HTREG.release();
105 }
106