More minor code improvements
[zxing.git] / core / src / com / google / zxing / qrcode / decoder / BitSource.java
1 /*\r
2  * Copyright 2007 Google Inc.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 package com.google.zxing.qrcode.decoder;\r
18 \r
19 /**\r
20  * <p>This provides an easy abstraction to read bits at a time from a sequence of bytes, where the\r
21  * number of bits read is not often a multiple of 8.</p>\r
22  *\r
23  * <p>This class is not thread-safe.</p>\r
24  *\r
25  * @author srowen@google.com (Sean Owen)\r
26  */\r
27 final class BitSource {\r
28 \r
29   private final byte[] bytes;\r
30   private int byteOffset;\r
31   private int bitOffset;\r
32 \r
33   /**\r
34    * @param bytes bytes from which this will read bits. Bits will be read from the first byte first.\r
35    * Bits are read within a byte from most-significant to least-significant bit.\r
36    */\r
37   BitSource(byte[] bytes) {\r
38     this.bytes = bytes;\r
39   }\r
40 \r
41   /**\r
42    * @param numBits number of bits to read\r
43    * @return int representing the bits read. The bits will appear as the least-significant\r
44    *         bits of the int\r
45    * @throws IllegalArgumentException if numBits isn't in [1,32]\r
46    */\r
47   int readBits(int numBits) {\r
48     if (numBits < 1 || numBits > 32) {\r
49       throw new IllegalArgumentException();\r
50     }\r
51 \r
52     int result = 0;\r
53 \r
54     // First, read remainder from current byte\r
55     if (bitOffset > 0) {\r
56       int bitsLeft = 8 - bitOffset;\r
57       int toRead = numBits < bitsLeft ? numBits : bitsLeft;\r
58       int bitsToNotRead = bitsLeft - toRead;\r
59       int mask = (0xFF >> (8 - toRead)) << bitsToNotRead;\r
60       result = (bytes[byteOffset] & mask) >> bitsToNotRead;\r
61       numBits -= toRead;\r
62       bitOffset += toRead;\r
63       if (bitOffset == 8) {\r
64         bitOffset = 0;\r
65         byteOffset++;\r
66       }\r
67     }\r
68 \r
69     // Next read whole bytes\r
70     if (numBits > 0) {\r
71       while (numBits >= 8) {\r
72         result = (result << 8) | (bytes[byteOffset] & 0xFF);\r
73         byteOffset++;\r
74         numBits -= 8;\r
75       }\r
76 \r
77       // Finally read a partial byte\r
78       if (numBits > 0) {\r
79         int bitsToNotRead = 8 - numBits;\r
80         int mask = (0xFF >> bitsToNotRead) << bitsToNotRead;\r
81         result = (result << numBits) | ((bytes[byteOffset] & mask) >> bitsToNotRead);\r
82         bitOffset += numBits;\r
83       }\r
84     }\r
85 \r
86     return result;\r
87   }\r
88 \r
89   /**\r
90    * @return number of bits that can be read successfully\r
91    */\r
92   int available() {\r
93     return 8 * (bytes.length - byteOffset) - bitOffset;\r
94   }\r
95 \r
96 }\r