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_BitStream.cpp
Go to the documentation of this file.
1// Copyright 2015 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_BitStream.h"
8
9#include <algorithm>
10
11#include "core/fxcrt/fx_safe_types.h"
12#include "core/fxcrt/numerics/safe_conversions.h"
13
14namespace {
15
16pdfium::span<const uint8_t> ValidatedSpan(pdfium::span<const uint8_t> sp) {
17 if (sp.size() > 256 * 1024 * 1024)
18 return {};
19 return sp;
20}
21
22} // namespace
23
24CJBig2_BitStream::CJBig2_BitStream(pdfium::span<const uint8_t> pSrcStream,
25 uint64_t key)
26 : m_Span(ValidatedSpan(pSrcStream)), m_Key(key) {}
27
29
30int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, uint32_t* dwResult) {
31 if (!IsInBounds())
32 return -1;
33
34 uint32_t dwBitPos = getBitPos();
35 if (dwBitPos > LengthInBits())
36 return -1;
37
38 *dwResult = 0;
39 if (dwBitPos + dwBits <= LengthInBits())
40 dwBitPos = dwBits;
41 else
42 dwBitPos = LengthInBits() - dwBitPos;
43
44 for (; dwBitPos > 0; --dwBitPos) {
45 *dwResult =
46 (*dwResult << 1) | ((m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
47 AdvanceBit();
48 }
49 return 0;
50}
51
52int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, int32_t* nResult) {
53 if (!IsInBounds())
54 return -1;
55
56 uint32_t dwBitPos = getBitPos();
57 if (dwBitPos > LengthInBits())
58 return -1;
59
60 *nResult = 0;
61 if (dwBitPos + dwBits <= LengthInBits())
62 dwBitPos = dwBits;
63 else
64 dwBitPos = LengthInBits() - dwBitPos;
65
66 for (; dwBitPos > 0; --dwBitPos) {
67 *nResult =
68 (*nResult << 1) | ((m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
69 AdvanceBit();
70 }
71 return 0;
72}
73
74int32_t CJBig2_BitStream::read1Bit(uint32_t* dwResult) {
75 if (!IsInBounds())
76 return -1;
77
78 *dwResult = (m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
79 AdvanceBit();
80 return 0;
81}
82
83int32_t CJBig2_BitStream::read1Bit(bool* bResult) {
84 if (!IsInBounds())
85 return -1;
86
87 *bResult = (m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
88 AdvanceBit();
89 return 0;
90}
91
92int32_t CJBig2_BitStream::read1Byte(uint8_t* cResult) {
93 if (!IsInBounds())
94 return -1;
95
96 *cResult = m_Span[m_dwByteIdx];
97 ++m_dwByteIdx;
98 return 0;
99}
100
101int32_t CJBig2_BitStream::readInteger(uint32_t* dwResult) {
102 if (m_dwByteIdx + 3 >= m_Span.size())
103 return -1;
104
105 *dwResult = (m_Span[m_dwByteIdx] << 24) | (m_Span[m_dwByteIdx + 1] << 16) |
106 (m_Span[m_dwByteIdx + 2] << 8) | m_Span[m_dwByteIdx + 3];
107 m_dwByteIdx += 4;
108 return 0;
109}
110
111int32_t CJBig2_BitStream::readShortInteger(uint16_t* dwResult) {
112 if (m_dwByteIdx + 1 >= m_Span.size())
113 return -1;
114
115 *dwResult = (m_Span[m_dwByteIdx] << 8) | m_Span[m_dwByteIdx + 1];
116 m_dwByteIdx += 2;
117 return 0;
118}
119
121 if (m_dwBitIdx != 0) {
123 m_dwBitIdx = 0;
124 }
125}
126
127uint8_t CJBig2_BitStream::getCurByte() const {
128 return IsInBounds() ? m_Span[m_dwByteIdx] : 0;
129}
130
134
136 return IsInBounds() ? m_Span[m_dwByteIdx] : 0xFF;
137}
138
140 return m_dwByteIdx + 1 < m_Span.size() ? m_Span[m_dwByteIdx + 1] : 0xFF;
141}
142
143uint32_t CJBig2_BitStream::getOffset() const {
144 return m_dwByteIdx;
145}
146
147void CJBig2_BitStream::setOffset(uint32_t dwOffset) {
148 m_dwByteIdx =
149 std::min(dwOffset, pdfium::checked_cast<uint32_t>(getBufSpan().size()));
150}
151
152void CJBig2_BitStream::addOffset(uint32_t dwDelta) {
153 FX_SAFE_UINT32 new_offset = m_dwByteIdx;
154 new_offset += dwDelta;
155 if (new_offset.IsValid()) {
156 setOffset(new_offset.ValueOrDie());
157 }
158}
159
160uint32_t CJBig2_BitStream::getBitPos() const {
161 return (m_dwByteIdx << 3) + m_dwBitIdx;
162}
163
164void CJBig2_BitStream::setBitPos(uint32_t dwBitPos) {
165 m_dwByteIdx = dwBitPos >> 3;
166 m_dwBitIdx = dwBitPos & 7;
167}
168
169const uint8_t* CJBig2_BitStream::getPointer() const {
170 return m_Span.subspan(m_dwByteIdx).data();
171}
172
173uint32_t CJBig2_BitStream::getByteLeft() const {
174 FX_SAFE_UINT32 result = getBufSpan().size();
175 result -= m_dwByteIdx;
176 return result.ValueOrDie();
177}
178
179void CJBig2_BitStream::AdvanceBit() {
180 if (m_dwBitIdx == 7) {
181 ++m_dwByteIdx;
182 m_dwBitIdx = 0;
183 } else {
184 ++m_dwBitIdx;
185 }
186}
187
189 return m_dwByteIdx < getBufSpan().size();
190}
191
192uint32_t CJBig2_BitStream::LengthInBits() const {
193 FX_SAFE_UINT32 result = getBufSpan().size();
194 result *= 8;
195 return result.ValueOrDie();
196}
int32_t readNBits(uint32_t dwBits, int32_t *nResult)
uint8_t getCurByte() const
uint32_t getBitPos() const
uint8_t getCurByte_arith() const
void setOffset(uint32_t dwOffset)
int32_t readInteger(uint32_t *dwResult)
uint32_t getByteLeft() const
void addOffset(uint32_t dwDelta)
int32_t read1Bit(uint32_t *dwResult)
const uint8_t * getPointer() const
int32_t read1Bit(bool *bResult)
CJBig2_BitStream(pdfium::span< const uint8_t > pSrcStream, uint64_t key)
uint8_t getNextByte_arith() const
uint32_t getOffset() const
void setBitPos(uint32_t dwBitPos)
bool IsInBounds() const
int32_t read1Byte(uint8_t *cResult)
int32_t readNBits(uint32_t dwBits, uint32_t *dwResult)
int32_t readShortInteger(uint16_t *wResult)
pdfium::CheckedNumeric< uint32_t > FX_SAFE_UINT32