Implemented some supporting methods and changes for BitBuffer, QrSegment, QrTemplate.

pull/134/head
Project Nayuki 7 years ago
parent 0c637b5705
commit 2fc396a607

@ -24,6 +24,7 @@
package io.nayuki.fastqrcodegen;
import java.util.Arrays;
import java.util.Objects;
final class BitBuffer {
@ -54,6 +55,16 @@ final class BitBuffer {
}
public byte[] getBytes() {
if (bitLength % 8 != 0)
throw new IllegalStateException("Data is not a whole number of bytes");
byte[] result = new byte[bitLength / 8];
for (int i = 0; i < result.length; i++)
result[i] = (byte)(data[i >>> 2] >>> (~i << 3));
return result;
}
public void appendBits(int val, int len) {
if (len < 0 || len > 31 || val >>> len != 0)
throw new IllegalArgumentException("Value out of range");
@ -76,4 +87,35 @@ final class BitBuffer {
bitLength += len;
}
public void appendBits(int[] vals, int len) {
Objects.requireNonNull(vals);
if (len == 0)
return;
if (len < 0 || len > vals.length * 32)
throw new IllegalArgumentException("Value out of range");
int wholeWords = len / 32;
int tailBits = len % 32;
if (tailBits > 0 && vals[wholeWords] << tailBits != 0)
throw new IllegalArgumentException("Last word must have low bits clear");
while (bitLength + len > data.length * 32)
data = Arrays.copyOf(data, data.length * 2);
int shift = bitLength % 32;
if (shift == 0) {
System.arraycopy(vals, 0, data, bitLength / 32, (len + 31) / 32);
bitLength += len;
} else {
for (int i = 0; i < wholeWords; i++) {
int word = vals[i];
data[bitLength >>> 5] |= word >>> shift;
bitLength += 32;
data[bitLength >>> 5] = word << (32 - shift);
}
if (tailBits > 0)
appendBits(vals[wholeWords] >>> (32 - tailBits), tailBits);
}
}
}

@ -167,6 +167,27 @@ public final class QrSegment {
}
// Package-private helper function.
static int getTotalBits(List<QrSegment> segs, int version) {
Objects.requireNonNull(segs);
if (version < 1 || version > 40)
throw new IllegalArgumentException("Version number out of range");
long result = 0;
for (QrSegment seg : segs) {
Objects.requireNonNull(seg);
int ccbits = seg.mode.numCharCountBits(version);
// Fail if segment length value doesn't fit in the length field's bit-width
if (seg.numChars >= (1 << ccbits))
return -1;
result += 4L + ccbits + seg.bitLength;
if (result > Integer.MAX_VALUE)
return -1;
}
return (int)result;
}
/*---- Constants ----*/

@ -300,7 +300,7 @@ final class QrTemplate {
// Returns the number of data bits that can be stored in a QR Code of the given version number, after
// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
private static int getNumRawDataModules(int ver) {
static int getNumRawDataModules(int ver) {
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw new IllegalArgumentException("Version number out of range");
int result = (16 * ver + 128) * ver + 64;

Loading…
Cancel
Save