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; int shortBlockLen = rawCodewords / numBlocks;
// Split data into blocks and append ECC to each block // 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); ReedSolomonGenerator rs = ReedSolomonGenerator.getInstance(blockEccLen);
byte[] ecc = new byte[blockEccLen];
for (int i = 0, k = 0; i < numBlocks; i++) { for (int i = 0, k = 0; i < numBlocks; i++) {
byte[] dat = Arrays.copyOfRange(data, k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1)); int datLen = shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1);
byte[] block = Arrays.copyOf(dat, shortBlockLen + 1); System.arraycopy(data, k, blocks[i], 0, datLen);
k += dat.length; rs.getRemainder(data, k, datLen, blocks[i], shortBlockLen + 1 - blockEccLen);
rs.getRemainder(dat, ecc); k += datLen;
System.arraycopy(ecc, 0, block, block.length - blockEccLen, ecc.length);
blocks[i] = block;
} }
// Interleave (not concatenate) the bytes from every block into a single sequence // 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(data);
Objects.requireNonNull(result); Objects.requireNonNull(result);
if (result.length != multiplies.length)
throw new IllegalArgumentException("Array length mismatch");
// Compute the remainder by performing polynomial division // Compute the remainder by performing polynomial division
Arrays.fill(result, (byte)0); int resultEnd = resultOff + multiplies.length;
for (byte b : data) { Arrays.fill(result, resultOff, resultEnd, (byte)0);
int factor = (b ^ result[0]) & 0xFF; for (int i = dataOff, dataEnd = dataOff + dataLen; i < dataEnd; i++) {
System.arraycopy(result, 1, result, 0, result.length - 1); byte b = data[i];
result[result.length - 1] = 0; int factor = (b ^ result[resultOff]) & 0xFF;
for (int i = 0; i < result.length; i++) System.arraycopy(result, resultOff + 1, result, resultOff, multiplies.length - 1);
result[i] ^= multiplies[i][factor]; result[resultEnd - 1] = 0;
for (int j = 0; j < multiplies.length; j++)
result[resultOff + j] ^= multiplies[j][factor];
} }
} }

Loading…
Cancel
Save