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