blob: 228e16ec09a13361424275ef5b11858848ddae6c [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Nico Weber9d8ec5a2015-08-04 13:00:21 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Dan Sinclair764ec512016-03-14 13:35:12 -04007#include "core/fxcodec/jbig2/JBig2_ArithIntDecoder.h"
Lei Zhanga7f53862015-09-10 16:34:17 -07008
Dan Sinclair3ebd1212016-03-09 09:59:23 -05009#include <vector>
10
dsinclaira52ab742016-09-29 13:59:29 -070011#include "core/fxcrt/fx_basic.h"
Lei Zhang61d25612015-10-01 14:03:33 -070012
13namespace {
14
15int ShiftOr(int val, int bitwise_or_val) {
16 return (val << 1) | bitwise_or_val;
17}
18
19const struct ArithIntDecodeData {
20 int nNeedBits;
21 int nValue;
22} g_ArithIntDecodeData[] = {
Dan Sinclair764ec512016-03-14 13:35:12 -040023 {2, 0}, {4, 4}, {6, 20}, {8, 84}, {12, 340}, {32, 4436},
Lei Zhang61d25612015-10-01 14:03:33 -070024};
25
26size_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
Lei Zhanga7f53862015-09-10 16:34:17 -070043
Nico Weber9d8ec5a2015-08-04 13:00:21 -070044CJBig2_ArithIntDecoder::CJBig2_ArithIntDecoder() {
Lei Zhang61d25612015-10-01 14:03:33 -070045 m_IAx.resize(512);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070046}
Lei Zhang61d25612015-10-01 14:03:33 -070047
Dan Sinclair764ec512016-03-14 13:35:12 -040048CJBig2_ArithIntDecoder::~CJBig2_ArithIntDecoder() {}
Lei Zhang61d25612015-10-01 14:03:33 -070049
50bool CJBig2_ArithIntDecoder::decode(CJBig2_ArithDecoder* pArithDecoder,
Nico Weber9d8ec5a2015-08-04 13:00:21 -070051 int* nResult) {
Lei Zhang61d25612015-10-01 14:03:33 -070052 int PREV = 1;
53 const int S = pArithDecoder->DECODE(&m_IAx[PREV]);
54 PREV = ShiftOr(PREV, S);
55
56 const size_t nDecodeDataIndex =
57 RecursiveDecode(pArithDecoder, &m_IAx, &PREV, 0);
58
59 int nTemp = 0;
60 for (int i = 0; i < g_ArithIntDecodeData[nDecodeDataIndex].nNeedBits; ++i) {
61 int D = pArithDecoder->DECODE(&m_IAx[PREV]);
62 PREV = ShiftOr(PREV, D);
63 if (PREV >= 256)
64 PREV = (PREV & 511) | 256;
65 nTemp = ShiftOr(nTemp, D);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070066 }
Lei Zhang61d25612015-10-01 14:03:33 -070067 int nValue = g_ArithIntDecodeData[nDecodeDataIndex].nValue;
68 nValue += nTemp;
69 if (S == 1 && nValue > 0)
70 nValue = -nValue;
71
72 *nResult = nValue;
73 return S != 1 || nValue != 0;
74}
75
76CJBig2_ArithIaidDecoder::CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA)
77 : SBSYMCODELEN(SBSYMCODELENA) {
Bruce Dawson5a839e92016-03-30 15:26:59 -070078 m_IAID.resize(static_cast<size_t>(1) << SBSYMCODELEN);
Lei Zhang61d25612015-10-01 14:03:33 -070079}
80
Dan Sinclair764ec512016-03-14 13:35:12 -040081CJBig2_ArithIaidDecoder::~CJBig2_ArithIaidDecoder() {}
Lei Zhang61d25612015-10-01 14:03:33 -070082
83void CJBig2_ArithIaidDecoder::decode(CJBig2_ArithDecoder* pArithDecoder,
tsepezb5e8f142016-03-25 15:18:35 -070084 uint32_t* nResult) {
Lei Zhang61d25612015-10-01 14:03:33 -070085 int PREV = 1;
86 for (unsigned char i = 0; i < SBSYMCODELEN; ++i) {
87 JBig2ArithCtx* pCX = &m_IAID[PREV];
88 int D = pArithDecoder->DECODE(pCX);
89 PREV = ShiftOr(PREV, D);
90 }
91 *nResult = PREV - (1 << SBSYMCODELEN);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070092}