• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The PDFium Authors
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_ArithIntDecoder.h"
8 
9 #include <vector>
10 
11 #include "core/fxcrt/fx_safe_types.h"
12 
13 namespace {
14 
ShiftOr(int val,int bitwise_or_val)15 int ShiftOr(int val, int bitwise_or_val) {
16   return (val << 1) | bitwise_or_val;
17 }
18 
19 struct ArithIntDecodeData {
20   int nNeedBits;
21   int nValue;
22 };
23 
24 constexpr ArithIntDecodeData kArithIntDecodeData[] = {
25     {2, 0}, {4, 4}, {6, 20}, {8, 84}, {12, 340}, {32, 4436},
26 };
27 
RecursiveDecode(CJBig2_ArithDecoder * decoder,std::vector<JBig2ArithCtx> * context,int * prev,size_t depth)28 size_t RecursiveDecode(CJBig2_ArithDecoder* decoder,
29                        std::vector<JBig2ArithCtx>* context,
30                        int* prev,
31                        size_t depth) {
32   static const size_t kDepthEnd = std::size(kArithIntDecodeData) - 1;
33   if (depth == kDepthEnd)
34     return kDepthEnd;
35 
36   JBig2ArithCtx* pCX = &(*context)[*prev];
37   int D = decoder->Decode(pCX);
38   *prev = ShiftOr(*prev, D);
39   if (!D)
40     return depth;
41   return RecursiveDecode(decoder, context, prev, depth + 1);
42 }
43 
44 }  // namespace
45 
CJBig2_ArithIntDecoder()46 CJBig2_ArithIntDecoder::CJBig2_ArithIntDecoder() {
47   m_IAx.resize(512);
48 }
49 
50 CJBig2_ArithIntDecoder::~CJBig2_ArithIntDecoder() = default;
51 
Decode(CJBig2_ArithDecoder * pArithDecoder,int * nResult)52 bool CJBig2_ArithIntDecoder::Decode(CJBig2_ArithDecoder* pArithDecoder,
53                                     int* nResult) {
54   // This decoding algorithm is explained in "Annex A - Arithmetic Integer
55   // Decoding Procedure" on page 113 of the JBIG2 specification (ISO/IEC FCD
56   // 14492).
57   int PREV = 1;
58   const int S = pArithDecoder->Decode(&m_IAx[PREV]);
59   PREV = ShiftOr(PREV, S);
60 
61   const size_t nDecodeDataIndex =
62       RecursiveDecode(pArithDecoder, &m_IAx, &PREV, 0);
63 
64   int nTemp = 0;
65   for (int i = 0; i < kArithIntDecodeData[nDecodeDataIndex].nNeedBits; ++i) {
66     int D = pArithDecoder->Decode(&m_IAx[PREV]);
67     PREV = ShiftOr(PREV, D);
68     if (PREV >= 256)
69       PREV = (PREV & 511) | 256;
70     nTemp = ShiftOr(nTemp, D);
71   }
72   FX_SAFE_INT32 safeValue = kArithIntDecodeData[nDecodeDataIndex].nValue;
73   safeValue += nTemp;
74 
75   // Value does not fit in int.
76   if (!safeValue.IsValid()) {
77     *nResult = 0;
78     return false;
79   }
80 
81   int nValue = safeValue.ValueOrDie();
82   if (S == 1 && nValue > 0)
83     nValue = -nValue;
84 
85   *nResult = nValue;
86   return S != 1 || nValue != 0;
87 }
88 
CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA)89 CJBig2_ArithIaidDecoder::CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA)
90     : SBSYMCODELEN(SBSYMCODELENA) {
91   m_IAID.resize(static_cast<size_t>(1) << SBSYMCODELEN);
92 }
93 
94 CJBig2_ArithIaidDecoder::~CJBig2_ArithIaidDecoder() = default;
95 
Decode(CJBig2_ArithDecoder * pArithDecoder,uint32_t * nResult)96 void CJBig2_ArithIaidDecoder::Decode(CJBig2_ArithDecoder* pArithDecoder,
97                                      uint32_t* nResult) {
98   int PREV = 1;
99   for (unsigned char i = 0; i < SBSYMCODELEN; ++i) {
100     JBig2ArithCtx* pCX = &m_IAID[PREV];
101     int D = pArithDecoder->Decode(pCX);
102     PREV = ShiftOr(PREV, D);
103   }
104   *nResult = PREV - (1 << SBSYMCODELEN);
105 }
106