Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
JBig2_ArithIntDecoder.cpp
Go to the documentation of this file.
1// Copyright 2014 The PDFium Authors
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 <array>
10#include <vector>
11
12#include "core/fxcrt/fx_safe_types.h"
13#include "core/fxcrt/stl_util.h"
14
15namespace {
16
17int ShiftOr(int val, int bitwise_or_val) {
18 return (val << 1) | bitwise_or_val;
19}
20
21struct ArithIntDecodeData {
22 int nNeedBits;
23 int nValue;
24};
25
26constexpr auto kArithIntDecodeData = fxcrt::ToArray<ArithIntDecodeData>({
27 {2, 0},
28 {4, 4},
29 {6, 20},
30 {8, 84},
31 {12, 340},
32 {32, 4436},
33});
34
35size_t RecursiveDecode(CJBig2_ArithDecoder* decoder,
36 std::vector<JBig2ArithCtx>* context,
37 int* prev,
38 size_t depth) {
39 static const size_t kDepthEnd = std::size(kArithIntDecodeData) - 1;
40 if (depth == kDepthEnd)
41 return kDepthEnd;
42
43 JBig2ArithCtx* pCX = &(*context)[*prev];
44 int D = decoder->Decode(pCX);
45 *prev = ShiftOr(*prev, D);
46 if (!D)
47 return depth;
48 return RecursiveDecode(decoder, context, prev, depth + 1);
49}
50
51} // namespace
52
54 m_IAx.resize(512);
55}
56
58
60 int* nResult) {
61 // This decoding algorithm is explained in "Annex A - Arithmetic Integer
62 // Decoding Procedure" on page 113 of the JBIG2 specification (ISO/IEC FCD
63 // 14492).
64 int PREV = 1;
65 const int S = pArithDecoder->Decode(&m_IAx[PREV]);
66 PREV = ShiftOr(PREV, S);
67
68 const size_t nDecodeDataIndex =
69 RecursiveDecode(pArithDecoder, &m_IAx, &PREV, 0);
70
71 int nTemp = 0;
72 for (int i = 0; i < kArithIntDecodeData[nDecodeDataIndex].nNeedBits; ++i) {
73 int D = pArithDecoder->Decode(&m_IAx[PREV]);
74 PREV = ShiftOr(PREV, D);
75 if (PREV >= 256)
76 PREV = (PREV & 511) | 256;
77 nTemp = ShiftOr(nTemp, D);
78 }
79 FX_SAFE_INT32 safeValue = kArithIntDecodeData[nDecodeDataIndex].nValue;
80 safeValue += nTemp;
81
82 // Value does not fit in int.
83 if (!safeValue.IsValid()) {
84 *nResult = 0;
85 return false;
86 }
87
88 int nValue = safeValue.ValueOrDie();
89 if (S == 1 && nValue > 0)
90 nValue = -nValue;
91
92 *nResult = nValue;
93 return S != 1 || nValue != 0;
94}
95
97 : SBSYMCODELEN(SBSYMCODELENA) {
98 m_IAID.resize(static_cast<size_t>(1) << SBSYMCODELEN);
99}
100
102
104 uint32_t* nResult) {
105 int PREV = 1;
106 for (unsigned char i = 0; i < SBSYMCODELEN; ++i) {
107 JBig2ArithCtx* pCX = &m_IAID[PREV];
108 int D = pArithDecoder->Decode(pCX);
109 PREV = ShiftOr(PREV, D);
110 }
111 *nResult = PREV - (1 << SBSYMCODELEN);
112}
int Decode(JBig2ArithCtx *pCX)
void Decode(CJBig2_ArithDecoder *pArithDecoder, uint32_t *nResult)
CJBig2_ArithIaidDecoder(unsigned char SBSYMCODELENA)
bool Decode(CJBig2_ArithDecoder *pArithDecoder, int *nResult)
pdfium::CheckedNumeric< int32_t > FX_SAFE_INT32