Revamped addEccAndInterleave() in C code for simplicity and robustness.

This commit is contained in:
Project Nayuki 2018-08-28 05:31:35 +00:00
parent 2c055c2e67
commit 87cab22ffc
1 changed files with 14 additions and 19 deletions

View File

@ -206,28 +206,23 @@ testable void addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ec
int numShortBlocks = numBlocks - rawCodewords % numBlocks;
int shortBlockDataLen = rawCodewords / numBlocks - blockEccLen;
// Split data into blocks and append ECC after all data
// Split data into blocks, calculate ECC, and interleave
// (not concatenate) the bytes into a single sequence
uint8_t generator[qrcodegen_REED_SOLOMON_DEGREE_MAX];
calcReedSolomonGenerator(blockEccLen, generator);
for (int i = 0, k = 0; i < numBlocks; i++) {
const uint8_t *dat = data;
for (int i = 0; i < numBlocks; i++) {
int datLen = shortBlockDataLen + (i < numShortBlocks ? 0 : 1);
calcReedSolomonRemainder(&data[k], datLen, generator, blockEccLen, &data[dataLen + i * blockEccLen]);
k += datLen;
uint8_t *ecc = &data[dataLen]; // Temporary storage
calcReedSolomonRemainder(dat, datLen, generator, blockEccLen, ecc);
for (int j = 0, k = i; j < datLen; j++, k += numBlocks) { // Copy data
if (j == shortBlockDataLen)
k -= numShortBlocks;
result[k] = dat[j];
}
// Interleave (not concatenate) the bytes from every block into a single sequence
for (int i = 0, k = 0; i < numBlocks; i++) { // Copy data
for (int j = 0, l = i; j < shortBlockDataLen; j++, k++, l += numBlocks)
result[l] = data[k];
if (i >= numShortBlocks)
k++;
}
for (int i = numShortBlocks, k = (numShortBlocks + 1) * shortBlockDataLen, l = numBlocks * shortBlockDataLen;
i < numBlocks; i++, k += shortBlockDataLen + 1, l++)
result[l] = data[k];
for (int i = 0, k = dataLen; i < numBlocks; i++) { // Copy ECC
for (int j = 0, l = dataLen + i; j < blockEccLen; j++, k++, l += numBlocks)
result[l] = data[k];
for (int j = 0, k = dataLen + i; j < blockEccLen; j++, k += numBlocks) // Copy ECC
result[k] = ecc[j];
dat += datLen;
}
}