2 * Copyright 2008 ZXing authors
\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
8 * http://www.apache.org/licenses/LICENSE-2.0
\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
16 namespace com.google.zxing.common
\r
21 /// <summary> A class which wraps a 2D array of bytes. The default usage is signed. If you want to use it as a
\r
22 /// unsigned container, it's up to you to do byteValue & 0xff at each location.
\r
24 /// JAVAPORT: I'm not happy about the argument ordering throughout the file, as I always like to have
\r
25 /// the horizontal component first, but this is for compatibility with the C++ code. The original
\r
26 /// code was a 2D array of ints, but since it only ever gets assigned -1, 0, and 1, I'm going to use
\r
27 /// less memory and go with bytes.
\r
30 /// <author> dswitkin@google.com (Daniel Switkin)
\r
33 public sealed class BitSource
\r
35 private sbyte[] bytes;
\r
36 private int byteOffset;
\r
37 private int bitOffset;
\r
40 * @param bytes bytes from which this will read bits. Bits will be read from the first byte first.
\r
41 * Bits are read within a byte from most-significant to least-significant bit.
\r
43 public BitSource(sbyte[] bytes) {
\r
48 * @param numBits number of bits to read
\r
49 * @return int representing the bits read. The bits will appear as the least-significant
\r
51 * @throws IllegalArgumentException if numBits isn't in [1,32]
\r
53 public int readBits(int numBits) {
\r
54 if (numBits < 1 || numBits > 32) {
\r
55 throw new Exception();
\r
60 // First, read remainder from current byte
\r
61 if (bitOffset > 0) {
\r
62 int bitsLeft = 8 - bitOffset;
\r
63 int toRead = numBits < bitsLeft ? numBits : bitsLeft;
\r
64 int bitsToNotRead = bitsLeft - toRead;
\r
65 int mask = (0xFF >> (8 - toRead)) << bitsToNotRead;
\r
66 result = (bytes[byteOffset] & mask) >> bitsToNotRead;
\r
68 bitOffset += toRead;
\r
69 if (bitOffset == 8) {
\r
75 // Next read whole bytes
\r
77 while (numBits >= 8) {
\r
78 result = (result << 8) | (bytes[byteOffset] & 0xFF);
\r
83 // Finally read a partial byte
\r
85 int bitsToNotRead = 8 - numBits;
\r
86 int mask = (0xFF >> bitsToNotRead) << bitsToNotRead;
\r
87 result = (result << numBits) | ((bytes[byteOffset] & mask) >> bitsToNotRead);
\r
88 bitOffset += numBits;
\r
96 * @return number of bits that can be read successfully
\r
98 public int available() {
\r
99 return 8 * (bytes.Length - byteOffset) - bitOffset;
\r