John Abd-El-Malek | 3f3b45c | 2014-05-23 17:28:10 -0700 | [diff] [blame] | 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. |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 4 | |
John Abd-El-Malek | 3f3b45c | 2014-05-23 17:28:10 -0700 | [diff] [blame] | 5 | // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | |
Dan Sinclair | 764ec51 | 2016-03-14 13:35:12 -0400 | [diff] [blame] | 7 | #include "core/fxcodec/jbig2/JBig2_ArithIntDecoder.h" |
Lei Zhang | a7f5386 | 2015-09-10 16:34:17 -0700 | [diff] [blame] | 8 | |
Dan Sinclair | 3ebd121 | 2016-03-09 09:59:23 -0500 | [diff] [blame] | 9 | #include <vector> |
| 10 | |
dsinclair | a52ab74 | 2016-09-29 13:59:29 -0700 | [diff] [blame] | 11 | #include "core/fxcrt/fx_basic.h" |
Lei Zhang | 61d2561 | 2015-10-01 14:03:33 -0700 | [diff] [blame] | 12 | |
| 13 | namespace { |
| 14 | |
| 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[] = { |
Dan Sinclair | 764ec51 | 2016-03-14 13:35:12 -0400 | [diff] [blame] | 23 | {2, 0}, {4, 4}, {6, 20}, {8, 84}, {12, 340}, {32, 4436}, |
Lei Zhang | 61d2561 | 2015-10-01 14:03:33 -0700 | [diff] [blame] | 24 | }; |
| 25 | |
| 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 |
Lei Zhang | a7f5386 | 2015-09-10 16:34:17 -0700 | [diff] [blame] | 43 | |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 44 | CJBig2_ArithIntDecoder::CJBig2_ArithIntDecoder() { |
Lei Zhang | 61d2561 | 2015-10-01 14:03:33 -0700 | [diff] [blame] | 45 | m_IAx.resize(512); |
John Abd-El-Malek | 3f3b45c | 2014-05-23 17:28:10 -0700 | [diff] [blame] | 46 | } |
Lei Zhang | 61d2561 | 2015-10-01 14:03:33 -0700 | [diff] [blame] | 47 | |
Dan Sinclair | 764ec51 | 2016-03-14 13:35:12 -0400 | [diff] [blame] | 48 | CJBig2_ArithIntDecoder::~CJBig2_ArithIntDecoder() {} |
Lei Zhang | 61d2561 | 2015-10-01 14:03:33 -0700 | [diff] [blame] | 49 | |
| 50 | bool CJBig2_ArithIntDecoder::decode(CJBig2_ArithDecoder* pArithDecoder, |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 51 | int* nResult) { |
Lei Zhang | 61d2561 | 2015-10-01 14:03:33 -0700 | [diff] [blame] | 52 | 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 Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 66 | } |
Lei Zhang | 61d2561 | 2015-10-01 14:03:33 -0700 | [diff] [blame] | 67 | 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 | |
| 76 | CJBig2_ArithIaidDecoder::CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA) |
| 77 | : SBSYMCODELEN(SBSYMCODELENA) { |
Bruce Dawson | 5a839e9 | 2016-03-30 15:26:59 -0700 | [diff] [blame] | 78 | m_IAID.resize(static_cast<size_t>(1) << SBSYMCODELEN); |
Lei Zhang | 61d2561 | 2015-10-01 14:03:33 -0700 | [diff] [blame] | 79 | } |
| 80 | |
Dan Sinclair | 764ec51 | 2016-03-14 13:35:12 -0400 | [diff] [blame] | 81 | CJBig2_ArithIaidDecoder::~CJBig2_ArithIaidDecoder() {} |
Lei Zhang | 61d2561 | 2015-10-01 14:03:33 -0700 | [diff] [blame] | 82 | |
| 83 | void CJBig2_ArithIaidDecoder::decode(CJBig2_ArithDecoder* pArithDecoder, |
tsepez | b5e8f14 | 2016-03-25 15:18:35 -0700 | [diff] [blame] | 84 | uint32_t* nResult) { |
Lei Zhang | 61d2561 | 2015-10-01 14:03:33 -0700 | [diff] [blame] | 85 | 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-Malek | 3f3b45c | 2014-05-23 17:28:10 -0700 | [diff] [blame] | 92 | } |