From: srowen Date: Mon, 10 Mar 2008 20:16:57 +0000 (+0000) Subject: Move BitSource to common package so that it can be reused by Data Matrix decoder X-Git-Url: http://git.rot13.org/?a=commitdiff_plain;h=70ad53775a0a5912c3eec31bdb30968d9846ed6f;hp=978c8a5cb184ab34dcb01ed04bbadfbc83508688;p=zxing.git Move BitSource to common package so that it can be reused by Data Matrix decoder git-svn-id: http://zxing.googlecode.com/svn/trunk@259 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- diff --git a/core/src/com/google/zxing/common/BitSource.java b/core/src/com/google/zxing/common/BitSource.java new file mode 100755 index 00000000..8d592ff5 --- /dev/null +++ b/core/src/com/google/zxing/common/BitSource.java @@ -0,0 +1,96 @@ +/* + * Copyright 2007 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.zxing.common; + +/** + *

This provides an easy abstraction to read bits at a time from a sequence of bytes, where the + * number of bits read is not often a multiple of 8.

+ * + *

This class is not thread-safe.

+ * + * @author srowen@google.com (Sean Owen) + */ +public final class BitSource { + + private final byte[] bytes; + private int byteOffset; + private int bitOffset; + + /** + * @param bytes bytes from which this will read bits. Bits will be read from the first byte first. + * Bits are read within a byte from most-significant to least-significant bit. + */ + public BitSource(byte[] bytes) { + this.bytes = bytes; + } + + /** + * @param numBits number of bits to read + * @return int representing the bits read. The bits will appear as the least-significant + * bits of the int + * @throws IllegalArgumentException if numBits isn't in [1,32] + */ + public int readBits(int numBits) { + if (numBits < 1 || numBits > 32) { + throw new IllegalArgumentException(); + } + + int result = 0; + + // First, read remainder from current byte + if (bitOffset > 0) { + int bitsLeft = 8 - bitOffset; + int toRead = numBits < bitsLeft ? numBits : bitsLeft; + int bitsToNotRead = bitsLeft - toRead; + int mask = (0xFF >> (8 - toRead)) << bitsToNotRead; + result = (bytes[byteOffset] & mask) >> bitsToNotRead; + numBits -= toRead; + bitOffset += toRead; + if (bitOffset == 8) { + bitOffset = 0; + byteOffset++; + } + } + + // Next read whole bytes + if (numBits > 0) { + while (numBits >= 8) { + result = (result << 8) | (bytes[byteOffset] & 0xFF); + byteOffset++; + numBits -= 8; + } + + // Finally read a partial byte + if (numBits > 0) { + int bitsToNotRead = 8 - numBits; + int mask = (0xFF >> bitsToNotRead) << bitsToNotRead; + result = (result << numBits) | ((bytes[byteOffset] & mask) >> bitsToNotRead); + bitOffset += numBits; + } + } + + return result; + } + + /** + * @return number of bits that can be read successfully + */ + public int available() { + return 8 * (bytes.length - byteOffset) - bitOffset; + } + +} diff --git a/core/src/com/google/zxing/qrcode/decoder/DecodedBitStreamParser.java b/core/src/com/google/zxing/qrcode/decoder/DecodedBitStreamParser.java index 059007d3..712a0cbc 100644 --- a/core/src/com/google/zxing/qrcode/decoder/DecodedBitStreamParser.java +++ b/core/src/com/google/zxing/qrcode/decoder/DecodedBitStreamParser.java @@ -17,6 +17,7 @@ package com.google.zxing.qrcode.decoder; import com.google.zxing.ReaderException; +import com.google.zxing.common.BitSource; import java.io.UnsupportedEncodingException; diff --git a/core/test/src/com/google/zxing/common/BitSourceTestCase.java b/core/test/src/com/google/zxing/common/BitSourceTestCase.java new file mode 100644 index 00000000..3f618315 --- /dev/null +++ b/core/test/src/com/google/zxing/common/BitSourceTestCase.java @@ -0,0 +1,46 @@ +/* + * Copyright 2007 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.zxing.common; + +import junit.framework.TestCase; + +/** + * @author srowen@google.com (Sean Owen) + */ +public final class BitSourceTestCase extends TestCase { + + public void testSource() { + byte[] bytes = new byte[]{(byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5}; + BitSource source = new BitSource(bytes); + assertEquals(40, source.available()); + assertEquals(0, source.readBits(1)); + assertEquals(39, source.available()); + assertEquals(0, source.readBits(6)); + assertEquals(33, source.available()); + assertEquals(1, source.readBits(1)); + assertEquals(32, source.available()); + assertEquals(2, source.readBits(8)); + assertEquals(24, source.available()); + assertEquals(12, source.readBits(10)); + assertEquals(14, source.available()); + assertEquals(16, source.readBits(8)); + assertEquals(6, source.available()); + assertEquals(5, source.readBits(6)); + assertEquals(0, source.available()); + } + +} \ No newline at end of file