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.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef _JBIG2_BIT_STREAM_H_
8 #define _JBIG2_BIT_STREAM_H_
9 #include "JBig2_Define.h"
10 class CJBig2_BitStream : public CJBig2_Object
11 {
12 public:
13 
14     CJBig2_BitStream(FX_BYTE *pBuffer, FX_DWORD dwLength);
15 
16     CJBig2_BitStream(CJBig2_BitStream &bs);
17 
18     ~CJBig2_BitStream();
19 
20     FX_INT32 readNBits(FX_DWORD nBits, FX_DWORD *dwResult);
21 
22     FX_INT32 readNBits(FX_DWORD nBits, FX_INT32 *nResult);
23 
24     FX_INT32 read1Bit(FX_DWORD *dwResult);
25 
26     FX_INT32 read1Bit(FX_BOOL  *bResult);
27 
28     FX_INT32 read1Byte(FX_BYTE *cResult);
29 
30     FX_INT32 readInteger(FX_DWORD *dwResult);
31 
32     FX_INT32 readShortInteger(FX_WORD *wResult);
33 
34     void alignByte();
35 
36     void align4Byte();
37 
38     FX_BYTE getAt(FX_DWORD dwOffset);
39 
40     FX_BYTE getCurByte();
41 
42     FX_BYTE getNextByte();
43 
44     FX_INT32 incByteIdx();
45 
46     FX_BYTE getCurByte_arith();
47 
48     FX_BYTE getNextByte_arith();
49 
50     FX_DWORD getOffset();
51 
52     void setOffset(FX_DWORD dwOffset);
53 
54     FX_DWORD getBitPos();
55 
56     void setBitPos(FX_DWORD dwBitPos);
57 
58     FX_BYTE *getBuf();
59 
getLength()60     FX_DWORD getLength()
61     {
62         return m_dwLength;
63     }
64 
65     FX_BYTE *getPointer();
66 
67     void offset(FX_DWORD dwOffset);
68 
69     FX_DWORD getByteLeft();
70 private:
71 
72     FX_BYTE *m_pBuf;
73 
74     FX_DWORD m_dwLength;
75 
76     FX_DWORD m_dwByteIdx;
77 
78     FX_DWORD m_dwBitIdx;
79 };
CJBig2_BitStream(FX_BYTE * pBuffer,FX_DWORD dwLength)80 inline CJBig2_BitStream::CJBig2_BitStream(FX_BYTE *pBuffer, FX_DWORD dwLength)
81 {
82     m_pBuf = pBuffer;
83     m_dwLength = dwLength;
84     m_dwByteIdx = 0;
85     m_dwBitIdx  = 0;
86     if (m_dwLength > 256 * 1024 * 1024) {
87         m_dwLength = 0;
88         m_pBuf = NULL;
89     }
90 }
CJBig2_BitStream(CJBig2_BitStream & bs)91 inline CJBig2_BitStream::CJBig2_BitStream(CJBig2_BitStream &bs)
92 {
93     m_pBuf = bs.m_pBuf;
94     m_dwLength = bs.m_dwLength;
95     m_dwByteIdx = bs.m_dwByteIdx;
96     m_dwBitIdx = bs.m_dwBitIdx;
97 }
~CJBig2_BitStream()98 inline CJBig2_BitStream::~CJBig2_BitStream()
99 {
100 }
readNBits(FX_DWORD dwBits,FX_DWORD * dwResult)101 inline FX_INT32 CJBig2_BitStream::readNBits(FX_DWORD dwBits, FX_DWORD *dwResult)
102 {
103     FX_DWORD dwTemp = (m_dwByteIdx << 3) + m_dwBitIdx;
104     if(dwTemp <= (m_dwLength << 3)) {
105         *dwResult = 0;
106         if(dwTemp + dwBits <= (m_dwLength << 3)) {
107             dwTemp = dwBits;
108         } else {
109             dwTemp = (m_dwLength << 3) - dwTemp;
110         }
111         while(dwTemp > 0) {
112             *dwResult = (*dwResult << 1) | ((m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
113             if(m_dwBitIdx == 7) {
114                 m_dwByteIdx ++;
115                 m_dwBitIdx = 0;
116             } else {
117                 m_dwBitIdx ++;
118             }
119             dwTemp --;
120         }
121         return 0;
122     } else {
123         return -1;
124     }
125 }
readNBits(FX_DWORD dwBits,FX_INT32 * nResult)126 inline FX_INT32 CJBig2_BitStream::readNBits(FX_DWORD dwBits, FX_INT32 *nResult)
127 {
128     FX_DWORD dwTemp = (m_dwByteIdx << 3) + m_dwBitIdx;
129     if(dwTemp <= (m_dwLength << 3)) {
130         *nResult = 0;
131         if(dwTemp + dwBits <= (m_dwLength << 3)) {
132             dwTemp = dwBits;
133         } else {
134             dwTemp = (m_dwLength << 3) - dwTemp;
135         }
136         while(dwTemp > 0) {
137             *nResult = (*nResult << 1) | ((m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01);
138             if(m_dwBitIdx == 7) {
139                 m_dwByteIdx ++;
140                 m_dwBitIdx = 0;
141             } else {
142                 m_dwBitIdx ++;
143             }
144             dwTemp --;
145         }
146         return 0;
147     } else {
148         return -1;
149     }
150 }
151 
read1Bit(FX_DWORD * dwResult)152 inline FX_INT32 CJBig2_BitStream::read1Bit(FX_DWORD *dwResult)
153 {
154     if(m_dwByteIdx < m_dwLength) {
155         *dwResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
156         if(m_dwBitIdx == 7) {
157             m_dwByteIdx ++;
158             m_dwBitIdx = 0;
159         } else {
160             m_dwBitIdx ++;
161         }
162         return 0;
163     } else {
164         return -1;
165     }
166 }
167 
read1Bit(FX_BOOL * bResult)168 inline FX_INT32 CJBig2_BitStream::read1Bit(FX_BOOL *bResult)
169 {
170     if(m_dwByteIdx < m_dwLength) {
171         *bResult = (m_pBuf[m_dwByteIdx] >> (7 - m_dwBitIdx)) & 0x01;
172         if(m_dwBitIdx == 7) {
173             m_dwByteIdx ++;
174             m_dwBitIdx = 0;
175         } else {
176             m_dwBitIdx ++;
177         }
178         return 0;
179     } else {
180         return -1;
181     }
182 }
read1Byte(FX_BYTE * cResult)183 inline FX_INT32 CJBig2_BitStream::read1Byte(FX_BYTE *cResult)
184 {
185     if(m_dwByteIdx < m_dwLength) {
186         *cResult = m_pBuf[m_dwByteIdx];
187         m_dwByteIdx ++;
188         return 0;
189     } else {
190         return -1;
191     }
192 }
193 
readInteger(FX_DWORD * dwResult)194 inline FX_INT32 CJBig2_BitStream::readInteger(FX_DWORD *dwResult)
195 {
196     if(m_dwByteIdx + 3 < m_dwLength) {
197         *dwResult = (m_pBuf[m_dwByteIdx] << 24) | (m_pBuf[m_dwByteIdx + 1] << 16)
198                     | (m_pBuf[m_dwByteIdx + 2] << 8) | m_pBuf[m_dwByteIdx + 3];
199         m_dwByteIdx += 4;
200         return 0;
201     } else {
202         return -1;
203     }
204 }
205 
readShortInteger(FX_WORD * dwResult)206 inline FX_INT32 CJBig2_BitStream::readShortInteger(FX_WORD *dwResult)
207 {
208     if(m_dwByteIdx + 1 < m_dwLength) {
209         *dwResult = (m_pBuf[m_dwByteIdx] << 8) | m_pBuf[m_dwByteIdx + 1];
210         m_dwByteIdx += 2;
211         return 0;
212     } else {
213         return -1;
214     }
215 }
alignByte()216 inline void CJBig2_BitStream::alignByte()
217 {
218     if(m_dwBitIdx != 0) {
219         m_dwByteIdx ++;
220         m_dwBitIdx = 0;
221     }
222 }
align4Byte()223 inline void CJBig2_BitStream::align4Byte()
224 {
225     if(m_dwBitIdx != 0) {
226         m_dwByteIdx ++;
227         m_dwBitIdx = 0;
228     }
229     m_dwByteIdx = (m_dwByteIdx + 3) & -4;
230 }
getAt(FX_DWORD dwOffset)231 inline FX_BYTE CJBig2_BitStream::getAt(FX_DWORD dwOffset)
232 {
233     if(dwOffset < m_dwLength) {
234         return m_pBuf[dwOffset];
235     } else {
236         return 0;
237     }
238 }
getCurByte()239 inline FX_BYTE CJBig2_BitStream::getCurByte()
240 {
241     if(m_dwByteIdx < m_dwLength) {
242         return m_pBuf[m_dwByteIdx];
243     } else {
244         return 0;
245     }
246 }
getNextByte()247 inline FX_BYTE CJBig2_BitStream::getNextByte()
248 {
249     if(m_dwByteIdx + 1 < m_dwLength) {
250         return m_pBuf[m_dwByteIdx + 1];
251     } else {
252         return 0;
253     }
254 }
incByteIdx()255 inline FX_INT32 CJBig2_BitStream::incByteIdx()
256 {
257     if(m_dwByteIdx < m_dwLength) {
258         m_dwByteIdx ++;
259         return 0;
260     } else {
261         return -1;
262     }
263 }
getCurByte_arith()264 inline FX_BYTE CJBig2_BitStream::getCurByte_arith()
265 {
266     if(m_dwByteIdx < m_dwLength) {
267         return m_pBuf[m_dwByteIdx];
268     } else {
269         return 0xff;
270     }
271 }
getNextByte_arith()272 inline FX_BYTE CJBig2_BitStream::getNextByte_arith()
273 {
274     if(m_dwByteIdx + 1 < m_dwLength) {
275         return m_pBuf[m_dwByteIdx + 1];
276     } else {
277         return 0xff;
278     }
279 }
getOffset()280 inline FX_DWORD CJBig2_BitStream::getOffset()
281 {
282     return m_dwByteIdx;
283 }
setOffset(FX_DWORD dwOffset)284 inline void CJBig2_BitStream::setOffset(FX_DWORD dwOffset)
285 {
286     if (dwOffset > m_dwLength) {
287         dwOffset = m_dwLength;
288     }
289     m_dwByteIdx = dwOffset;
290 }
getBitPos()291 inline FX_DWORD CJBig2_BitStream::getBitPos()
292 {
293     return (m_dwByteIdx << 3) + m_dwBitIdx;
294 }
setBitPos(FX_DWORD dwBitPos)295 inline void CJBig2_BitStream::setBitPos(FX_DWORD dwBitPos)
296 {
297     m_dwByteIdx = dwBitPos >> 3;
298     m_dwBitIdx = dwBitPos & 7;
299 }
getBuf()300 inline FX_BYTE *CJBig2_BitStream::getBuf()
301 {
302     return m_pBuf;
303 }
getPointer()304 inline FX_BYTE *CJBig2_BitStream::getPointer()
305 {
306     return m_pBuf + m_dwByteIdx;
307 }
offset(FX_DWORD dwOffset)308 inline void CJBig2_BitStream::offset(FX_DWORD dwOffset)
309 {
310     m_dwByteIdx += dwOffset;
311 }
getByteLeft()312 inline FX_DWORD CJBig2_BitStream::getByteLeft()
313 {
314     return m_dwLength - m_dwByteIdx;
315 }
316 #endif
317