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