|
|
|
@ -116,9 +116,17 @@ static uint8_t *addEccAndInterleaveReference(const uint8_t *data, int version, e
|
|
|
|
|
// Split data into blocks and append ECC to each block
|
|
|
|
|
uint8_t **blocks = malloc(numBlocks * sizeof(uint8_t*));
|
|
|
|
|
uint8_t *generator = malloc(blockEccLen * sizeof(uint8_t));
|
|
|
|
|
if (blocks == NULL || generator == NULL) {
|
|
|
|
|
perror("malloc");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
reedSolomonComputeDivisor((int)blockEccLen, generator);
|
|
|
|
|
for (size_t i = 0, k = 0; i < numBlocks; i++) {
|
|
|
|
|
uint8_t *block = malloc((shortBlockLen + 1) * sizeof(uint8_t));
|
|
|
|
|
if (block == NULL) {
|
|
|
|
|
perror("malloc");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
size_t datLen = shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1);
|
|
|
|
|
memcpy(block, &data[k], datLen * sizeof(uint8_t));
|
|
|
|
|
reedSolomonComputeRemainder(&data[k], (int)datLen, generator, (int)blockEccLen, &block[shortBlockLen + 1 - blockEccLen]);
|
|
|
|
@ -129,6 +137,10 @@ static uint8_t *addEccAndInterleaveReference(const uint8_t *data, int version, e
|
|
|
|
|
|
|
|
|
|
// Interleave (not concatenate) the bytes from every block into a single sequence
|
|
|
|
|
uint8_t *result = malloc(rawCodewords * sizeof(uint8_t));
|
|
|
|
|
if (result == NULL) {
|
|
|
|
|
perror("malloc");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
for (size_t i = 0, k = 0; i < shortBlockLen + 1; i++) {
|
|
|
|
|
for (size_t j = 0; j < numBlocks; j++) {
|
|
|
|
|
// Skip the padding byte in short blocks
|
|
|
|
@ -150,14 +162,26 @@ static void testAddEccAndInterleave(void) {
|
|
|
|
|
for (int ecl = 0; ecl < 4; ecl++) {
|
|
|
|
|
size_t dataLen = (size_t)getNumDataCodewords(version, (enum qrcodegen_Ecc)ecl);
|
|
|
|
|
uint8_t *pureData = malloc(dataLen * sizeof(uint8_t));
|
|
|
|
|
if (pureData == NULL) {
|
|
|
|
|
perror("malloc");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
for (size_t i = 0; i < dataLen; i++)
|
|
|
|
|
pureData[i] = (uint8_t)(rand() % 256);
|
|
|
|
|
uint8_t *expectOutput = addEccAndInterleaveReference(pureData, version, (enum qrcodegen_Ecc)ecl);
|
|
|
|
|
|
|
|
|
|
size_t dataAndEccLen = (size_t)getNumRawDataModules(version) / 8;
|
|
|
|
|
uint8_t *paddedData = malloc(dataAndEccLen * sizeof(uint8_t));
|
|
|
|
|
if (paddedData == NULL) {
|
|
|
|
|
perror("malloc");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
memcpy(paddedData, pureData, dataLen * sizeof(uint8_t));
|
|
|
|
|
uint8_t *actualOutput = malloc(dataAndEccLen * sizeof(uint8_t));
|
|
|
|
|
if (actualOutput == NULL) {
|
|
|
|
|
perror("malloc");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
addEccAndInterleave(paddedData, version, (enum qrcodegen_Ecc)ecl, actualOutput);
|
|
|
|
|
|
|
|
|
|
assert(memcmp(actualOutput, expectOutput, dataAndEccLen * sizeof(uint8_t)) == 0);
|
|
|
|
@ -363,7 +387,10 @@ static void testReedSolomonMultiply(void) {
|
|
|
|
|
static void testInitializeFunctionModulesEtc(void) {
|
|
|
|
|
for (int ver = 1; ver <= 40; ver++) {
|
|
|
|
|
uint8_t *qrcode = malloc((size_t)qrcodegen_BUFFER_LEN_FOR_VERSION(ver) * sizeof(uint8_t));
|
|
|
|
|
assert(qrcode != NULL);
|
|
|
|
|
if (qrcode == NULL) {
|
|
|
|
|
perror("malloc");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
initializeFunctionModules(ver, qrcode);
|
|
|
|
|
|
|
|
|
|
int size = qrcodegen_getSize(qrcode);
|
|
|
|
|