]> Pileus Git - ~andy/freeotp/blob - src/com/google/zxing/common/BitSource.java
Add native camera support
[~andy/freeotp] / src / com / google / zxing / common / BitSource.java
1 /*
2  * Copyright 2007 ZXing authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.zxing.common;
18
19 /**
20  * <p>This provides an easy abstraction to read bits at a time from a sequence of bytes, where the
21  * number of bits read is not often a multiple of 8.</p>
22  *
23  * <p>This class is thread-safe but not reentrant -- unless the caller modifies the bytes array
24  * it passed in, in which case all bets are off.</p>
25  *
26  * @author Sean Owen
27  */
28 public final class BitSource {
29
30   private final byte[] bytes;
31   private int byteOffset;
32   private int bitOffset;
33
34   /**
35    * @param bytes bytes from which this will read bits. Bits will be read from the first byte first.
36    * Bits are read within a byte from most-significant to least-significant bit.
37    */
38   public BitSource(byte[] bytes) {
39     this.bytes = bytes;
40   }
41
42   /**
43    * @return index of next bit in current byte which would be read by the next call to {@link #readBits(int)}.
44    */
45   public int getBitOffset() {
46     return bitOffset;
47   }
48
49   /**
50    * @return index of next byte in input byte array which would be read by the next call to {@link #readBits(int)}.
51    */
52   public int getByteOffset() {
53     return byteOffset;
54   }
55
56   /**
57    * @param numBits number of bits to read
58    * @return int representing the bits read. The bits will appear as the least-significant
59    *         bits of the int
60    * @throws IllegalArgumentException if numBits isn't in [1,32] or more than is available
61    */
62   public int readBits(int numBits) {
63     if (numBits < 1 || numBits > 32 || numBits > available()) {
64       throw new IllegalArgumentException(String.valueOf(numBits));
65     }
66
67     int result = 0;
68
69     // First, read remainder from current byte
70     if (bitOffset > 0) {
71       int bitsLeft = 8 - bitOffset;
72       int toRead = numBits < bitsLeft ? numBits : bitsLeft;
73       int bitsToNotRead = bitsLeft - toRead;
74       int mask = (0xFF >> (8 - toRead)) << bitsToNotRead;
75       result = (bytes[byteOffset] & mask) >> bitsToNotRead;
76       numBits -= toRead;
77       bitOffset += toRead;
78       if (bitOffset == 8) {
79         bitOffset = 0;
80         byteOffset++;
81       }
82     }
83
84     // Next read whole bytes
85     if (numBits > 0) {
86       while (numBits >= 8) {
87         result = (result << 8) | (bytes[byteOffset] & 0xFF);
88         byteOffset++;
89         numBits -= 8;
90       }
91
92       // Finally read a partial byte
93       if (numBits > 0) {
94         int bitsToNotRead = 8 - numBits;
95         int mask = (0xFF >> bitsToNotRead) << bitsToNotRead;
96         result = (result << numBits) | ((bytes[byteOffset] & mask) >> bitsToNotRead);
97         bitOffset += numBits;
98       }
99     }
100
101     return result;
102   }
103
104   /**
105    * @return number of bits that can be read successfully
106    */
107   public int available() {
108     return 8 * (bytes.length - byteOffset) - bitOffset;
109   }
110
111 }