mirror of
https://github.com/zxing/zxing.git
synced 2024-11-10 04:54:04 -08:00
Ported over the BitVector bug fix and new unit test from Satoru.
git-svn-id: https://zxing.googlecode.com/svn/trunk@742 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
56f194794b
commit
a8d732d084
|
@ -52,10 +52,8 @@ public final class BitVector {
|
|||
}
|
||||
|
||||
// Return the number of bytes in the bit vector.
|
||||
// JAVAPORT: I would have made this ((sizeInBits + 7) >> 3), but apparently users of this class
|
||||
// depend on the number of bytes being rounded down. I don't see how that works though.
|
||||
public int num_bytes() {
|
||||
return sizeInBits >> 3;
|
||||
return (sizeInBits + 7) >> 3;
|
||||
}
|
||||
|
||||
// Append one bit to the bit vector.
|
||||
|
|
|
@ -101,11 +101,15 @@ public class BitVectorTestCase extends TestCase {
|
|||
BitVector v = new BitVector();
|
||||
assertEquals(0, v.num_bytes());
|
||||
v.AppendBit(0);
|
||||
assertEquals(0, v.num_bytes());
|
||||
// 1 bit was added in the vector, so 1 byte should be consumed.
|
||||
assertEquals(1, v.num_bytes());
|
||||
v.AppendBits(0, 7);
|
||||
assertEquals(1, v.num_bytes());
|
||||
v.AppendBits(0, 8);
|
||||
assertEquals(2, v.num_bytes());
|
||||
v.AppendBits(0, 1);
|
||||
// We now have 17 bits, so 3 bytes should be consumed.
|
||||
assertEquals(3, v.num_bytes());
|
||||
}
|
||||
|
||||
public void testAppendBitVector() {
|
||||
|
|
|
@ -607,4 +607,42 @@ public final class EncoderTestCase extends TestCase {
|
|||
assertFalse(Encoder.IsValidKanjiSequence(new ByteArray("0123")));
|
||||
assertFalse(Encoder.IsValidKanjiSequence(new ByteArray("ABC")));
|
||||
}
|
||||
|
||||
public void testBugInBitVectorNumBytes() throws WriterException {
|
||||
// There was a bug in BitVector::num_bytes() that caused it to return a
|
||||
// smaller-by-one value (ex. 1465 instead of 1466) if the number of bits
|
||||
// in the vector is not 8-bit aligned. In QRCodeEncoder::InitQRCode(),
|
||||
// BitVector::num_bytes() is used for finding the smallest QR Code
|
||||
// version that can fit the given data. Hence there were corner cases
|
||||
// where we chose a wrong QR Code version that cannot fit the given
|
||||
// data. Note that the issue did not occur with MODE_8BIT_BYTE, as the
|
||||
// bits in the bit vector are always 8-bit aligned.
|
||||
//
|
||||
// Before the bug was fixed, the following test didn't pass, because:
|
||||
//
|
||||
// - MODE_NUMERIC is chosen as all bytes in the data are '0'
|
||||
// - The 3518-byte numeric data needs 1466 bytes
|
||||
// - 3518 / 3 * 10 + 7 = 11727 bits = 1465.875 bytes
|
||||
// - 3 numeric bytes are encoded in 10 bits, hence the first
|
||||
// 3516 bytes are encoded in 3516 / 3 * 10 = 11720 bits.
|
||||
// - 2 numeric bytes can be encoded in 7 bits, hence the last
|
||||
// 2 bytes are encoded in 7 bits.
|
||||
// - The version 27 QR Code with the EC level L has 1468 bytes for data.
|
||||
// - 1828 - 360 = 1468
|
||||
// - In InitQRCode(), 3 bytes are reserved for a header. Hence 1465 bytes
|
||||
// (1468 -3) are left for data.
|
||||
// - Because of the bug in BitVector::num_bytes(), InitQRCode() determines
|
||||
// the given data can fit in 1465 bytes, despite it needs 1466 bytes.
|
||||
// - Hence QRCodeEncoder::Encode() failed and returned false.
|
||||
// - To be precise, it needs 11727 + 4 (mode info) + 14 (length info) =
|
||||
// 11745 bits = 1468.125 bytes are needed (i.e. cannot fit in 1468
|
||||
// bytes).
|
||||
final int arraySize = 3518;
|
||||
byte[] data_bytes = new byte[arraySize];
|
||||
for (int x = 0; x < arraySize; x++) {
|
||||
data_bytes[x] = '0';
|
||||
}
|
||||
QRCode qr_code = new QRCode();
|
||||
Encoder.Encode(new ByteArray(data_bytes), QRCode.EC_LEVEL_L, qr_code);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue