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"
10class CJBig2_BitStream : public CJBig2_Object
11{
12public:
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
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();
70private:
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};
80inline 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}
91inline 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}
98inline CJBig2_BitStream::~CJBig2_BitStream()
99{
100}
101inline 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}
126inline 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
152inline 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
168inline 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}
183inline 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
194inline 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
206inline 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}
216inline void CJBig2_BitStream::alignByte()
217{
218    if(m_dwBitIdx != 0) {
219        m_dwByteIdx ++;
220        m_dwBitIdx = 0;
221    }
222}
223inline 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}
231inline 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}
239inline 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}
247inline 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}
255inline 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}
264inline 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}
272inline 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}
280inline FX_DWORD CJBig2_BitStream::getOffset()
281{
282    return m_dwByteIdx;
283}
284inline void CJBig2_BitStream::setOffset(FX_DWORD dwOffset)
285{
286    if (dwOffset > m_dwLength) {
287        dwOffset = m_dwLength;
288    }
289    m_dwByteIdx = dwOffset;
290}
291inline FX_DWORD CJBig2_BitStream::getBitPos()
292{
293    return (m_dwByteIdx << 3) + m_dwBitIdx;
294}
295inline void CJBig2_BitStream::setBitPos(FX_DWORD dwBitPos)
296{
297    m_dwByteIdx = dwBitPos >> 3;
298    m_dwBitIdx = dwBitPos & 7;
299}
300inline FX_BYTE *CJBig2_BitStream::getBuf()
301{
302    return m_pBuf;
303}
304inline FX_BYTE *CJBig2_BitStream::getPointer()
305{
306    return m_pBuf + m_dwByteIdx;
307}
308inline void CJBig2_BitStream::offset(FX_DWORD dwOffset)
309{
310    m_dwByteIdx += dwOffset;
311}
312inline FX_DWORD CJBig2_BitStream::getByteLeft()
313{
314    return m_dwLength - m_dwByteIdx;
315}
316#endif
317