Updated and simplified Reed-Solomon ECC computation to reduce temporary buffers and copying.

pull/134/head
Project Nayuki 6 years ago
parent cdb9172032
commit 887b6255ed

@ -295,16 +295,13 @@ public final class QrCode {
int shortBlockLen = rawCodewords / numBlocks;
// Split data into blocks and append ECC to each block
byte[][] blocks = new byte[numBlocks][];
byte[][] blocks = new byte[numBlocks][shortBlockLen + 1];
ReedSolomonGenerator rs = ReedSolomonGenerator.getInstance(blockEccLen);
byte[] ecc = new byte[blockEccLen];
for (int i = 0, k = 0; i < numBlocks; i++) {
byte[] dat = Arrays.copyOfRange(data, k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
byte[] block = Arrays.copyOf(dat, shortBlockLen + 1);
k += dat.length;
rs.getRemainder(dat, ecc);
System.arraycopy(ecc, 0, block, block.length - blockEccLen, ecc.length);
blocks[i] = block;
int datLen = shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1);
System.arraycopy(data, k, blocks[i], 0, datLen);
rs.getRemainder(data, k, datLen, blocks[i], shortBlockLen + 1 - blockEccLen);
k += datLen;
}
// Interleave (not concatenate) the bytes from every block into a single sequence

@ -116,20 +116,20 @@ final class ReedSolomonGenerator {
}
public void getRemainder(byte[] data, byte[] result) {
public void getRemainder(byte[] data, int dataOff, int dataLen, byte[] result, int resultOff) {
Objects.requireNonNull(data);
Objects.requireNonNull(result);
if (result.length != multiplies.length)
throw new IllegalArgumentException("Array length mismatch");
// Compute the remainder by performing polynomial division
Arrays.fill(result, (byte)0);
for (byte b : data) {
int factor = (b ^ result[0]) & 0xFF;
System.arraycopy(result, 1, result, 0, result.length - 1);
result[result.length - 1] = 0;
for (int i = 0; i < result.length; i++)
result[i] ^= multiplies[i][factor];
int resultEnd = resultOff + multiplies.length;
Arrays.fill(result, resultOff, resultEnd, (byte)0);
for (int i = dataOff, dataEnd = dataOff + dataLen; i < dataEnd; i++) {
byte b = data[i];
int factor = (b ^ result[resultOff]) & 0xFF;
System.arraycopy(result, resultOff + 1, result, resultOff, multiplies.length - 1);
result[resultEnd - 1] = 0;
for (int j = 0; j < multiplies.length; j++)
result[resultOff + j] ^= multiplies[j][factor];
}
}

Loading…
Cancel
Save