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 "JBig2_ArithIntDecoder.h"
8 
9 #include "core/include/fxcrt/fx_basic.h"
10 
11 namespace {
12 
ShiftOr(int val,int bitwise_or_val)13 int ShiftOr(int val, int bitwise_or_val) {
14   return (val << 1) | bitwise_or_val;
15 }
16 
17 const struct ArithIntDecodeData {
18   int nNeedBits;
19   int nValue;
20 } g_ArithIntDecodeData[] = {
21     {2, 0},
22     {4, 4},
23     {6, 20},
24     {8, 84},
25     {12, 340},
26     {32, 4436},
27 };
28 
RecursiveDecode(CJBig2_ArithDecoder * decoder,std::vector<JBig2ArithCtx> * context,int * prev,size_t depth)29 size_t RecursiveDecode(CJBig2_ArithDecoder* decoder,
30                        std::vector<JBig2ArithCtx>* context,
31                        int* prev,
32                        size_t depth) {
33   static const size_t kDepthEnd = FX_ArraySize(g_ArithIntDecodeData) - 1;
34   if (depth == kDepthEnd)
35     return kDepthEnd;
36 
37   JBig2ArithCtx* pCX = &(*context)[*prev];
38   int D = decoder->DECODE(pCX);
39   *prev = ShiftOr(*prev, D);
40   if (!D)
41     return depth;
42   return RecursiveDecode(decoder, context, prev, depth + 1);
43 }
44 
45 }  // namespace
46 
CJBig2_ArithIntDecoder()47 CJBig2_ArithIntDecoder::CJBig2_ArithIntDecoder() {
48   m_IAx.resize(512);
49 }
50 
~CJBig2_ArithIntDecoder()51 CJBig2_ArithIntDecoder::~CJBig2_ArithIntDecoder() {
52 }
53 
decode(CJBig2_ArithDecoder * pArithDecoder,int * nResult)54 bool CJBig2_ArithIntDecoder::decode(CJBig2_ArithDecoder* pArithDecoder,
55                                     int* nResult) {
56   int PREV = 1;
57   const int S = pArithDecoder->DECODE(&m_IAx[PREV]);
58   PREV = ShiftOr(PREV, S);
59 
60   const size_t nDecodeDataIndex =
61       RecursiveDecode(pArithDecoder, &m_IAx, &PREV, 0);
62 
63   int nTemp = 0;
64   for (int i = 0; i < g_ArithIntDecodeData[nDecodeDataIndex].nNeedBits; ++i) {
65     int D = pArithDecoder->DECODE(&m_IAx[PREV]);
66     PREV = ShiftOr(PREV, D);
67     if (PREV >= 256)
68       PREV = (PREV & 511) | 256;
69     nTemp = ShiftOr(nTemp, D);
70   }
71   int nValue = g_ArithIntDecodeData[nDecodeDataIndex].nValue;
72   nValue += nTemp;
73   if (S == 1 && nValue > 0)
74     nValue = -nValue;
75 
76   *nResult = nValue;
77   return S != 1 || nValue != 0;
78 }
79 
CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA)80 CJBig2_ArithIaidDecoder::CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA)
81     : SBSYMCODELEN(SBSYMCODELENA) {
82   m_IAID.resize(1 << SBSYMCODELEN);
83 }
84 
~CJBig2_ArithIaidDecoder()85 CJBig2_ArithIaidDecoder::~CJBig2_ArithIaidDecoder() {
86 }
87 
decode(CJBig2_ArithDecoder * pArithDecoder,FX_DWORD * nResult)88 void CJBig2_ArithIaidDecoder::decode(CJBig2_ArithDecoder* pArithDecoder,
89                                      FX_DWORD* nResult) {
90   int PREV = 1;
91   for (unsigned char i = 0; i < SBSYMCODELEN; ++i) {
92     JBig2ArithCtx* pCX = &m_IAID[PREV];
93     int D = pArithDecoder->DECODE(pCX);
94     PREV = ShiftOr(PREV, D);
95   }
96   *nResult = PREV - (1 << SBSYMCODELEN);
97 }
98