• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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 "core/fxcodec/jbig2/JBig2_BitStream.h"
8 
9 #include <algorithm>
10 
11 namespace {
12 
ValidatedSpan(pdfium::span<const uint8_t> sp)13 pdfium::span<const uint8_t> ValidatedSpan(pdfium::span<const uint8_t> sp) {
14   if (sp.size() > 256 * 1024 * 1024)
15     return {};
16   return sp;
17 }
18 
19 }  // namespace
20 
CJBig2_BitStream(pdfium::span<const uint8_t> pSrcStream,uint32_t dwObjNum)21 CJBig2_BitStream::CJBig2_BitStream(pdfium::span<const uint8_t> pSrcStream,
22                                    uint32_t dwObjNum)
23     : m_Span(ValidatedSpan(pSrcStream)), m_dwObjNum(dwObjNum) {}
24 
25 CJBig2_BitStream::~CJBig2_BitStream() = default;
26 
readNBits(uint32_t dwBits,uint32_t * dwResult)27 int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, uint32_t* dwResult) {
28   if (!IsInBounds())
29     return -1;
30 
31   uint32_t dwBitPos = getBitPos();
32   if (dwBitPos > LengthInBits())
33     return -1;
34 
35   *dwResult = 0;
36   if (dwBitPos + dwBits <= LengthInBits())
37     dwBitPos = dwBits;
38   else
39     dwBitPos = LengthInBits() - dwBitPos;
40 
41   for (; dwBitPos > 0; --dwBitPos) {
42     *dwResult =
43         (*dwResult << 1) | ((m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
44     AdvanceBit();
45   }
46   return 0;
47 }
48 
readNBits(uint32_t dwBits,int32_t * nResult)49 int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, int32_t* nResult) {
50   if (!IsInBounds())
51     return -1;
52 
53   uint32_t dwBitPos = getBitPos();
54   if (dwBitPos > LengthInBits())
55     return -1;
56 
57   *nResult = 0;
58   if (dwBitPos + dwBits <= LengthInBits())
59     dwBitPos = dwBits;
60   else
61     dwBitPos = LengthInBits() - dwBitPos;
62 
63   for (; dwBitPos > 0; --dwBitPos) {
64     *nResult =
65         (*nResult << 1) | ((m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
66     AdvanceBit();
67   }
68   return 0;
69 }
70 
read1Bit(uint32_t * dwResult)71 int32_t CJBig2_BitStream::read1Bit(uint32_t* dwResult) {
72   if (!IsInBounds())
73     return -1;
74 
75   *dwResult = (m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
76   AdvanceBit();
77   return 0;
78 }
79 
read1Bit(bool * bResult)80 int32_t CJBig2_BitStream::read1Bit(bool* bResult) {
81   if (!IsInBounds())
82     return -1;
83 
84   *bResult = (m_Span[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
85   AdvanceBit();
86   return 0;
87 }
88 
read1Byte(uint8_t * cResult)89 int32_t CJBig2_BitStream::read1Byte(uint8_t* cResult) {
90   if (!IsInBounds())
91     return -1;
92 
93   *cResult = m_Span[m_dwByteIdx];
94   ++m_dwByteIdx;
95   return 0;
96 }
97 
readInteger(uint32_t * dwResult)98 int32_t CJBig2_BitStream::readInteger(uint32_t* dwResult) {
99   if (m_dwByteIdx + 3 >= m_Span.size())
100     return -1;
101 
102   *dwResult = (m_Span[m_dwByteIdx] << 24) | (m_Span[m_dwByteIdx + 1] << 16) |
103               (m_Span[m_dwByteIdx + 2] << 8) | m_Span[m_dwByteIdx + 3];
104   m_dwByteIdx += 4;
105   return 0;
106 }
107 
readShortInteger(uint16_t * dwResult)108 int32_t CJBig2_BitStream::readShortInteger(uint16_t* dwResult) {
109   if (m_dwByteIdx + 1 >= m_Span.size())
110     return -1;
111 
112   *dwResult = (m_Span[m_dwByteIdx] << 8) | m_Span[m_dwByteIdx + 1];
113   m_dwByteIdx += 2;
114   return 0;
115 }
116 
alignByte()117 void CJBig2_BitStream::alignByte() {
118   if (m_dwBitIdx != 0) {
119     ++m_dwByteIdx;
120     m_dwBitIdx = 0;
121   }
122 }
123 
getCurByte() const124 uint8_t CJBig2_BitStream::getCurByte() const {
125   return IsInBounds() ? m_Span[m_dwByteIdx] : 0;
126 }
127 
incByteIdx()128 void CJBig2_BitStream::incByteIdx() {
129   if (IsInBounds())
130     ++m_dwByteIdx;
131 }
132 
getCurByte_arith() const133 uint8_t CJBig2_BitStream::getCurByte_arith() const {
134   return IsInBounds() ? m_Span[m_dwByteIdx] : 0xFF;
135 }
136 
getNextByte_arith() const137 uint8_t CJBig2_BitStream::getNextByte_arith() const {
138   return m_dwByteIdx + 1 < m_Span.size() ? m_Span[m_dwByteIdx + 1] : 0xFF;
139 }
140 
getOffset() const141 uint32_t CJBig2_BitStream::getOffset() const {
142   return m_dwByteIdx;
143 }
144 
setOffset(uint32_t dwOffset)145 void CJBig2_BitStream::setOffset(uint32_t dwOffset) {
146   m_dwByteIdx = std::min<size_t>(dwOffset, m_Span.size());
147 }
148 
getBitPos() const149 uint32_t CJBig2_BitStream::getBitPos() const {
150   return (m_dwByteIdx << 3) + m_dwBitIdx;
151 }
152 
setBitPos(uint32_t dwBitPos)153 void CJBig2_BitStream::setBitPos(uint32_t dwBitPos) {
154   m_dwByteIdx = dwBitPos >> 3;
155   m_dwBitIdx = dwBitPos & 7;
156 }
157 
getBuf() const158 const uint8_t* CJBig2_BitStream::getBuf() const {
159   return m_Span.data();
160 }
161 
getPointer() const162 const uint8_t* CJBig2_BitStream::getPointer() const {
163   return getBuf() + m_dwByteIdx;
164 }
165 
offset(uint32_t dwOffset)166 void CJBig2_BitStream::offset(uint32_t dwOffset) {
167   m_dwByteIdx += dwOffset;
168 }
169 
getByteLeft() const170 uint32_t CJBig2_BitStream::getByteLeft() const {
171   return m_Span.size() - m_dwByteIdx;
172 }
173 
AdvanceBit()174 void CJBig2_BitStream::AdvanceBit() {
175   if (m_dwBitIdx == 7) {
176     ++m_dwByteIdx;
177     m_dwBitIdx = 0;
178   } else {
179     ++m_dwBitIdx;
180   }
181 }
182 
IsInBounds() const183 bool CJBig2_BitStream::IsInBounds() const {
184   return m_dwByteIdx < m_Span.size();
185 }
186 
LengthInBits() const187 uint32_t CJBig2_BitStream::LengthInBits() const {
188   return m_Span.size() << 3;
189 }
190 
getObjNum() const191 uint32_t CJBig2_BitStream::getObjNum() const {
192   return m_dwObjNum;
193 }
194