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