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 #include "core/fpdfapi/parser/cpdf_stream.h"
12 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
13 
CJBig2_BitStream(CPDF_StreamAcc * pSrcStream)14 CJBig2_BitStream::CJBig2_BitStream(CPDF_StreamAcc* pSrcStream)
15     : m_pBuf(pSrcStream->GetData()),
16       m_dwLength(pSrcStream->GetSize()),
17       m_dwByteIdx(0),
18       m_dwBitIdx(0),
19       m_dwObjNum(pSrcStream->GetStream() ? pSrcStream->GetStream()->GetObjNum()
20                                          : 0) {
21   if (m_dwLength > 256 * 1024 * 1024) {
22     m_dwLength = 0;
23     m_pBuf = nullptr;
24   }
25 }
26 
~CJBig2_BitStream()27 CJBig2_BitStream::~CJBig2_BitStream() {}
28 
readNBits(uint32_t dwBits,uint32_t * dwResult)29 int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, uint32_t* dwResult) {
30   uint32_t dwBitPos = getBitPos();
31   if (dwBitPos > LengthInBits())
32     return -1;
33 
34   *dwResult = 0;
35   if (dwBitPos + dwBits <= LengthInBits())
36     dwBitPos = dwBits;
37   else
38     dwBitPos = LengthInBits() - dwBitPos;
39 
40   for (; dwBitPos > 0; --dwBitPos) {
41     *dwResult =
42         (*dwResult << 1) | ((m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
43     AdvanceBit();
44   }
45   return 0;
46 }
47 
readNBits(uint32_t dwBits,int32_t * nResult)48 int32_t CJBig2_BitStream::readNBits(uint32_t dwBits, int32_t* nResult) {
49   uint32_t dwBitPos = getBitPos();
50   if (dwBitPos > LengthInBits())
51     return -1;
52 
53   *nResult = 0;
54   if (dwBitPos + dwBits <= LengthInBits())
55     dwBitPos = dwBits;
56   else
57     dwBitPos = LengthInBits() - dwBitPos;
58 
59   for (; dwBitPos > 0; --dwBitPos) {
60     *nResult =
61         (*nResult << 1) | ((m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
62     AdvanceBit();
63   }
64   return 0;
65 }
66 
read1Bit(uint32_t * dwResult)67 int32_t CJBig2_BitStream::read1Bit(uint32_t* dwResult) {
68   if (!IsInBound())
69     return -1;
70 
71   *dwResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
72   AdvanceBit();
73   return 0;
74 }
75 
read1Bit(bool * bResult)76 int32_t CJBig2_BitStream::read1Bit(bool* bResult) {
77   if (!IsInBound())
78     return -1;
79 
80   *bResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
81   AdvanceBit();
82   return 0;
83 }
84 
read1Byte(uint8_t * cResult)85 int32_t CJBig2_BitStream::read1Byte(uint8_t* cResult) {
86   if (!IsInBound())
87     return -1;
88 
89   *cResult = m_pBuf[m_dwByteIdx];
90   ++m_dwByteIdx;
91   return 0;
92 }
93 
readInteger(uint32_t * dwResult)94 int32_t CJBig2_BitStream::readInteger(uint32_t* dwResult) {
95   if (m_dwByteIdx + 3 >= m_dwLength)
96     return -1;
97 
98   *dwResult = (m_pBuf[m_dwByteIdx] << 24) | (m_pBuf[m_dwByteIdx + 1] << 16) |
99               (m_pBuf[m_dwByteIdx + 2] << 8) | m_pBuf[m_dwByteIdx + 3];
100   m_dwByteIdx += 4;
101   return 0;
102 }
103 
readShortInteger(uint16_t * dwResult)104 int32_t CJBig2_BitStream::readShortInteger(uint16_t* dwResult) {
105   if (m_dwByteIdx + 1 >= m_dwLength)
106     return -1;
107 
108   *dwResult = (m_pBuf[m_dwByteIdx] << 8) | m_pBuf[m_dwByteIdx + 1];
109   m_dwByteIdx += 2;
110   return 0;
111 }
112 
alignByte()113 void CJBig2_BitStream::alignByte() {
114   if (m_dwBitIdx != 0) {
115     ++m_dwByteIdx;
116     m_dwBitIdx = 0;
117   }
118 }
119 
getCurByte() const120 uint8_t CJBig2_BitStream::getCurByte() const {
121   return IsInBound() ? m_pBuf[m_dwByteIdx] : 0;
122 }
123 
incByteIdx()124 void CJBig2_BitStream::incByteIdx() {
125   if (IsInBound())
126     ++m_dwByteIdx;
127 }
128 
getCurByte_arith() const129 uint8_t CJBig2_BitStream::getCurByte_arith() const {
130   return IsInBound() ? m_pBuf[m_dwByteIdx] : 0xFF;
131 }
132 
getNextByte_arith() const133 uint8_t CJBig2_BitStream::getNextByte_arith() const {
134   return m_dwByteIdx + 1 < m_dwLength ? m_pBuf[m_dwByteIdx + 1] : 0xFF;
135 }
136 
getOffset() const137 uint32_t CJBig2_BitStream::getOffset() const {
138   return m_dwByteIdx;
139 }
140 
setOffset(uint32_t dwOffset)141 void CJBig2_BitStream::setOffset(uint32_t dwOffset) {
142   m_dwByteIdx = std::min(dwOffset, m_dwLength);
143 }
144 
getBitPos() const145 uint32_t CJBig2_BitStream::getBitPos() const {
146   return (m_dwByteIdx << 3) + m_dwBitIdx;
147 }
148 
setBitPos(uint32_t dwBitPos)149 void CJBig2_BitStream::setBitPos(uint32_t dwBitPos) {
150   m_dwByteIdx = dwBitPos >> 3;
151   m_dwBitIdx = dwBitPos & 7;
152 }
153 
getBuf() const154 const uint8_t* CJBig2_BitStream::getBuf() const {
155   return m_pBuf;
156 }
157 
getPointer() const158 const uint8_t* CJBig2_BitStream::getPointer() const {
159   return m_pBuf + m_dwByteIdx;
160 }
161 
offset(uint32_t dwOffset)162 void CJBig2_BitStream::offset(uint32_t dwOffset) {
163   m_dwByteIdx += dwOffset;
164 }
165 
getByteLeft() const166 uint32_t CJBig2_BitStream::getByteLeft() const {
167   return m_dwLength - m_dwByteIdx;
168 }
169 
AdvanceBit()170 void CJBig2_BitStream::AdvanceBit() {
171   if (m_dwBitIdx == 7) {
172     ++m_dwByteIdx;
173     m_dwBitIdx = 0;
174   } else {
175     ++m_dwBitIdx;
176   }
177 }
178 
IsInBound() const179 bool CJBig2_BitStream::IsInBound() const {
180   return m_dwByteIdx < m_dwLength;
181 }
182 
LengthInBits() const183 uint32_t CJBig2_BitStream::LengthInBits() const {
184   return m_dwLength << 3;
185 }
186 
getObjNum() const187 uint32_t CJBig2_BitStream::getObjNum() const {
188   return m_dwObjNum;
189 }
190