mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
Encoding bugfix
This commit is contained in:
parent
d2ac6e7cb6
commit
f68751fbc9
207
backend/aztec.c
207
backend/aztec.c
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "aztec.h"
|
#include "aztec.h"
|
||||||
#include "reedsol.h"
|
#include "reedsol.h"
|
||||||
@ -549,12 +550,13 @@ int aztec_text_process(unsigned char source[], char binary_string[])
|
|||||||
|
|
||||||
int aztec(struct zint_symbol *symbol, unsigned char source[])
|
int aztec(struct zint_symbol *symbol, unsigned char source[])
|
||||||
{
|
{
|
||||||
int x, y, i, j, k, data_blocks, ecc_blocks, layers, total_bits;
|
int x, y, i, j, data_blocks, ecc_blocks, layers, total_bits;
|
||||||
char binary_string[20000], bit_pattern[20045], descriptor[42];
|
char binary_string[20000], bit_pattern[20045], descriptor[42];
|
||||||
char adjusted_string[20000];
|
char adjusted_string[20000];
|
||||||
unsigned int data_part[1500], ecc_part[840];
|
unsigned int data_part[1500], ecc_part[840];
|
||||||
unsigned char desc_data[4], desc_ecc[6];
|
unsigned char desc_data[4], desc_ecc[6];
|
||||||
int err_code, ecc_level, compact, data_length, data_maxsize, codeword_size, adjusted_length;
|
int err_code, ecc_level, compact, data_length, data_maxsize, codeword_size, adjusted_length;
|
||||||
|
int remainder, padbits, count;
|
||||||
|
|
||||||
memset(binary_string,0,20000);
|
memset(binary_string,0,20000);
|
||||||
memset(adjusted_string,0,20000);
|
memset(adjusted_string,0,20000);
|
||||||
@ -663,30 +665,47 @@ int aztec(struct zint_symbol *symbol, unsigned char source[])
|
|||||||
if((layers >= 9) && (layers <= 22)) { codeword_size = 10; }
|
if((layers >= 9) && (layers <= 22)) { codeword_size = 10; }
|
||||||
if(layers >= 23) { codeword_size = 12; }
|
if(layers >= 23) { codeword_size = 12; }
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
count = 0;
|
||||||
for(i = 0; i <= data_length; i++) {
|
for(i = 0; i <= data_length; i++) {
|
||||||
adjusted_string[i] = binary_string[i];
|
remainder = i % codeword_size;
|
||||||
|
if(binary_string[i] == '1') count++;
|
||||||
|
if(remainder == codeword_size - 1) {
|
||||||
|
/* Last bit of codeword */
|
||||||
|
if(count == codeword_size - 1) {
|
||||||
|
/* All 1s - add 0 */
|
||||||
|
adjusted_string[j] = '0';
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
if(count == 0) {
|
||||||
|
/* All 0s - add 1 */
|
||||||
|
adjusted_string[j] = '1';
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
adjusted_string[j] = binary_string[i];
|
||||||
|
j++;
|
||||||
}
|
}
|
||||||
|
adjusted_string[j] = '\0';
|
||||||
/* Data string can't have all '0's or all '1's in a block */
|
|
||||||
i = 0;
|
|
||||||
do{
|
|
||||||
int count0, count1;
|
|
||||||
|
|
||||||
count0 = 0;
|
|
||||||
count1 = 0;
|
|
||||||
for(j = 0; j < codeword_size; j++) {
|
|
||||||
if(adjusted_string[j + i] == '0') { count0++; } else { count1++; }
|
|
||||||
}
|
|
||||||
if(count0 == codeword_size) { /* If all 0s insert a '1' */
|
|
||||||
insert(adjusted_string, i+(codeword_size - 1), '1');
|
|
||||||
}
|
|
||||||
if(count1 == codeword_size) { /* If all 1s insert a '0' */
|
|
||||||
insert(adjusted_string, i+(codeword_size - 1), '0');
|
|
||||||
}
|
|
||||||
i += codeword_size;
|
|
||||||
} while ((i + codeword_size) < strlen(adjusted_string));
|
|
||||||
adjusted_length = strlen(adjusted_string);
|
adjusted_length = strlen(adjusted_string);
|
||||||
|
|
||||||
|
remainder = adjusted_length % codeword_size;
|
||||||
|
|
||||||
|
padbits = codeword_size - remainder;
|
||||||
|
if(padbits == codeword_size) { padbits = 0; }
|
||||||
|
|
||||||
|
for(i = 0; i < padbits; i++) {
|
||||||
|
concat(adjusted_string, "1");
|
||||||
|
}
|
||||||
|
adjusted_length = strlen(adjusted_string);
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
for(i = (adjusted_length - codeword_size); i < adjusted_length; i++) {
|
||||||
|
if(adjusted_string[i] == '1') { count++; }
|
||||||
|
}
|
||||||
|
if(count == codeword_size) { adjusted_string[adjusted_length - 1] = '0'; }
|
||||||
|
|
||||||
} while(adjusted_length > data_maxsize);
|
} while(adjusted_length > data_maxsize);
|
||||||
/* This loop will only repeat on the rare occasions when the rule about not having all 1s or all 0s
|
/* This loop will only repeat on the rare occasions when the rule about not having all 1s or all 0s
|
||||||
means that the binary string has had to be lengthened beyond the maximum number of bits that can
|
means that the binary string has had to be lengthened beyond the maximum number of bits that can
|
||||||
@ -713,30 +732,47 @@ int aztec(struct zint_symbol *symbol, unsigned char source[])
|
|||||||
if((layers >= 9) && (layers <= 22)) { codeword_size = 10; }
|
if((layers >= 9) && (layers <= 22)) { codeword_size = 10; }
|
||||||
if(layers >= 23) { codeword_size = 12; }
|
if(layers >= 23) { codeword_size = 12; }
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
count = 0;
|
||||||
for(i = 0; i <= data_length; i++) {
|
for(i = 0; i <= data_length; i++) {
|
||||||
adjusted_string[i] = binary_string[i];
|
remainder = i % codeword_size;
|
||||||
|
if(binary_string[i] == '1') count++;
|
||||||
|
if(remainder == codeword_size - 1) {
|
||||||
|
/* Last bit of codeword */
|
||||||
|
if(count == codeword_size - 1) {
|
||||||
|
/* All 1s - add 0 */
|
||||||
|
adjusted_string[j] = '0';
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
if(count == 0) {
|
||||||
|
/* All 0s - add 1 */
|
||||||
|
adjusted_string[j] = '1';
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
adjusted_string[j] = binary_string[i];
|
||||||
|
j++;
|
||||||
}
|
}
|
||||||
|
adjusted_string[j] = '\0';
|
||||||
/* Data string can't have all '0's or all '1's in a block */
|
|
||||||
i = 0;
|
|
||||||
do{
|
|
||||||
int count0, count1;
|
|
||||||
|
|
||||||
count0 = 0;
|
|
||||||
count1 = 0;
|
|
||||||
for(j = 0; j < codeword_size; j++) {
|
|
||||||
if(adjusted_string[j + i] == '0') { count0++; } else { count1++; }
|
|
||||||
}
|
|
||||||
if(count0 == codeword_size) { /* If all 0s insert a '1' */
|
|
||||||
insert(adjusted_string, i+(codeword_size - 1), '1');
|
|
||||||
}
|
|
||||||
if(count1 == codeword_size) { /* If all 1s insert a '0' */
|
|
||||||
insert(adjusted_string, i+(codeword_size - 1), '0');
|
|
||||||
}
|
|
||||||
i += codeword_size;
|
|
||||||
} while ((i + codeword_size) < strlen(adjusted_string));
|
|
||||||
adjusted_length = strlen(adjusted_string);
|
adjusted_length = strlen(adjusted_string);
|
||||||
|
|
||||||
|
remainder = adjusted_length % codeword_size;
|
||||||
|
|
||||||
|
padbits = codeword_size - remainder;
|
||||||
|
if(padbits == codeword_size) { padbits = 0; }
|
||||||
|
|
||||||
|
for(i = 0; i < padbits; i++) {
|
||||||
|
concat(adjusted_string, "1");
|
||||||
|
}
|
||||||
|
adjusted_length = strlen(adjusted_string);
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
for(i = (adjusted_length - codeword_size); i < adjusted_length; i++) {
|
||||||
|
if(adjusted_string[i] == '1') { count++; }
|
||||||
|
}
|
||||||
|
if(count == codeword_size) { adjusted_string[adjusted_length - 1] = '0'; }
|
||||||
|
|
||||||
/* Check if the data actually fits into the selected symbol size */
|
/* Check if the data actually fits into the selected symbol size */
|
||||||
if (compact) {
|
if (compact) {
|
||||||
data_maxsize = codeword_size * (AztecCompactSizes[layers - 1] - 3);
|
data_maxsize = codeword_size * (AztecCompactSizes[layers - 1] - 3);
|
||||||
@ -750,24 +786,6 @@ int aztec(struct zint_symbol *symbol, unsigned char source[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The value of i is used from above to indicate the number of bits to the end of the last
|
|
||||||
used data block - this is now a set value */
|
|
||||||
|
|
||||||
/* Insert extra '1's to pad out the final block of data */
|
|
||||||
for(j = 0; j < (i - adjusted_length); j++) {
|
|
||||||
concat(adjusted_string, "1");
|
|
||||||
}
|
|
||||||
adjusted_length = i;
|
|
||||||
|
|
||||||
/* But be careful that the final block of data doesn't contain all '1's */
|
|
||||||
k = 0;
|
|
||||||
for(j = (i - codeword_size); j < i; j++) {
|
|
||||||
if(adjusted_string[j] == '1') { k++; }
|
|
||||||
}
|
|
||||||
if(k == codeword_size) { /* Change the very last bit */
|
|
||||||
adjusted_string[adjusted_length - 1] = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
data_blocks = adjusted_length / codeword_size;
|
data_blocks = adjusted_length / codeword_size;
|
||||||
|
|
||||||
if(compact) {
|
if(compact) {
|
||||||
@ -905,40 +923,41 @@ int aztec(struct zint_symbol *symbol, unsigned char source[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Now add the symbol descriptor */
|
/* Now add the symbol descriptor */
|
||||||
memset(descriptor,0,42);
|
|
||||||
memset(desc_data,0,4);
|
memset(desc_data,0,4);
|
||||||
memset(desc_ecc,0,6);
|
memset(desc_ecc,0,6);
|
||||||
|
|
||||||
if(compact) {
|
if(compact) {
|
||||||
/* The first 2 bits represent the number of layers minus 1 */
|
/* The first 2 bits represent the number of layers minus 1 */
|
||||||
if((layers - 1) & 0x02) { descriptor[0] = '1'; }
|
if((layers - 1) & 0x02) { descriptor[0] = '1'; } else { descriptor[0] = '0'; }
|
||||||
if((layers - 1) & 0x01) { descriptor[1] = '1'; }
|
if((layers - 1) & 0x01) { descriptor[1] = '1'; } else { descriptor[1] = '0'; }
|
||||||
/* The next 6 bits represent the number of data blocks minus 1 */
|
/* The next 6 bits represent the number of data blocks minus 1 */
|
||||||
if((data_blocks - 1) & 0x20) { descriptor[2] = '1'; }
|
if((data_blocks - 1) & 0x20) { descriptor[2] = '1'; } else { descriptor[2] = '0'; }
|
||||||
if((data_blocks - 1) & 0x10) { descriptor[3] = '1'; }
|
if((data_blocks - 1) & 0x10) { descriptor[3] = '1'; } else { descriptor[3] = '0'; }
|
||||||
if((data_blocks - 1) & 0x08) { descriptor[4] = '1'; }
|
if((data_blocks - 1) & 0x08) { descriptor[4] = '1'; } else { descriptor[4] = '0'; }
|
||||||
if((data_blocks - 1) & 0x04) { descriptor[5] = '1'; }
|
if((data_blocks - 1) & 0x04) { descriptor[5] = '1'; } else { descriptor[5] = '0'; }
|
||||||
if((data_blocks - 1) & 0x02) { descriptor[6] = '1'; }
|
if((data_blocks - 1) & 0x02) { descriptor[6] = '1'; } else { descriptor[6] = '0'; }
|
||||||
if((data_blocks - 1) & 0x01) { descriptor[7] = '1'; }
|
if((data_blocks - 1) & 0x01) { descriptor[7] = '1'; } else { descriptor[7] = '0'; }
|
||||||
|
descriptor[8] = '\0';
|
||||||
} else {
|
} else {
|
||||||
/* The first 5 bits represent the number of layers minus 1 */
|
/* The first 5 bits represent the number of layers minus 1 */
|
||||||
if((layers - 1) & 0x10) { descriptor[0] = '1'; }
|
if((layers - 1) & 0x10) { descriptor[0] = '1'; } else { descriptor[0] = '0'; }
|
||||||
if((layers - 1) & 0x08) { descriptor[1] = '1'; }
|
if((layers - 1) & 0x08) { descriptor[1] = '1'; } else { descriptor[1] = '0'; }
|
||||||
if((layers - 1) & 0x04) { descriptor[2] = '1'; }
|
if((layers - 1) & 0x04) { descriptor[2] = '1'; } else { descriptor[2] = '0'; }
|
||||||
if((layers - 1) & 0x02) { descriptor[3] = '1'; }
|
if((layers - 1) & 0x02) { descriptor[3] = '1'; } else { descriptor[3] = '0'; }
|
||||||
if((layers - 1) & 0x01) { descriptor[4] = '1'; }
|
if((layers - 1) & 0x01) { descriptor[4] = '1'; } else { descriptor[4] = '0'; }
|
||||||
/* The next 11 bits represent the number of data blocks minus 1 */
|
/* The next 11 bits represent the number of data blocks minus 1 */
|
||||||
if((data_blocks - 1) & 0x400) { descriptor[5] = '1'; }
|
if((data_blocks - 1) & 0x400) { descriptor[5] = '1'; } else { descriptor[5] = '0'; }
|
||||||
if((data_blocks - 1) & 0x200) { descriptor[6] = '1'; }
|
if((data_blocks - 1) & 0x200) { descriptor[6] = '1'; } else { descriptor[6] = '0'; }
|
||||||
if((data_blocks - 1) & 0x100) { descriptor[7] = '1'; }
|
if((data_blocks - 1) & 0x100) { descriptor[7] = '1'; } else { descriptor[7] = '0'; }
|
||||||
if((data_blocks - 1) & 0x80) { descriptor[8] = '1'; }
|
if((data_blocks - 1) & 0x80) { descriptor[8] = '1'; } else { descriptor[8] = '0'; }
|
||||||
if((data_blocks - 1) & 0x40) { descriptor[9] = '1'; }
|
if((data_blocks - 1) & 0x40) { descriptor[9] = '1'; } else { descriptor[9] = '0'; }
|
||||||
if((data_blocks - 1) & 0x20) { descriptor[10] = '1'; }
|
if((data_blocks - 1) & 0x20) { descriptor[10] = '1'; } else { descriptor[10] = '0'; }
|
||||||
if((data_blocks - 1) & 0x10) { descriptor[11] = '1'; }
|
if((data_blocks - 1) & 0x10) { descriptor[11] = '1'; } else { descriptor[11] = '0'; }
|
||||||
if((data_blocks - 1) & 0x08) { descriptor[12] = '1'; }
|
if((data_blocks - 1) & 0x08) { descriptor[12] = '1'; } else { descriptor[12] = '0'; }
|
||||||
if((data_blocks - 1) & 0x04) { descriptor[13] = '1'; }
|
if((data_blocks - 1) & 0x04) { descriptor[13] = '1'; } else { descriptor[13] = '0'; }
|
||||||
if((data_blocks - 1) & 0x02) { descriptor[14] = '1'; }
|
if((data_blocks - 1) & 0x02) { descriptor[14] = '1'; } else { descriptor[14] = '0'; }
|
||||||
if((data_blocks - 1) & 0x01) { descriptor[15] = '1'; }
|
if((data_blocks - 1) & 0x01) { descriptor[15] = '1'; } else { descriptor[15] = '0'; }
|
||||||
|
descriptor[16] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Split into 4-bit codewords */
|
/* Split into 4-bit codewords */
|
||||||
@ -957,19 +976,19 @@ int aztec(struct zint_symbol *symbol, unsigned char source[])
|
|||||||
rs_init_code(5, 1);
|
rs_init_code(5, 1);
|
||||||
rs_encode(2, desc_data, desc_ecc);
|
rs_encode(2, desc_data, desc_ecc);
|
||||||
for(i = 0; i < 5; i++) {
|
for(i = 0; i < 5; i++) {
|
||||||
if(desc_ecc[i] & 0x08) { descriptor[(i * 4) + 8] = '1'; }
|
if(desc_ecc[4 - i] & 0x08) { descriptor[(i * 4) + 8] = '1'; } else { descriptor[(i * 4) + 8] = '0'; }
|
||||||
if(desc_ecc[i] & 0x04) { descriptor[(i * 4) + 9] = '1'; }
|
if(desc_ecc[4 - i] & 0x04) { descriptor[(i * 4) + 9] = '1'; } else { descriptor[(i * 4) + 9] = '0'; }
|
||||||
if(desc_ecc[i] & 0x02) { descriptor[(i * 4) + 10] = '1'; }
|
if(desc_ecc[4 - i] & 0x02) { descriptor[(i * 4) + 10] = '1'; } else { descriptor[(i * 4) + 10] = '0'; }
|
||||||
if(desc_ecc[i] & 0x01) { descriptor[(i * 4) + 11] = '1'; }
|
if(desc_ecc[4 - i] & 0x01) { descriptor[(i * 4) + 11] = '1'; } else { descriptor[(i * 4) + 11] = '0'; }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rs_init_code(6, 1);
|
rs_init_code(6, 1);
|
||||||
rs_encode(4, desc_data, desc_ecc);
|
rs_encode(4, desc_data, desc_ecc);
|
||||||
for(i = 0; i < 6; i++) {
|
for(i = 0; i < 6; i++) {
|
||||||
if(desc_ecc[i] & 0x08) { descriptor[(i * 4) + 16] = '1'; }
|
if(desc_ecc[5 - i] & 0x08) { descriptor[(i * 4) + 16] = '1'; } else { descriptor[(i * 4) + 16] = '0'; }
|
||||||
if(desc_ecc[i] & 0x04) { descriptor[(i * 4) + 17] = '1'; }
|
if(desc_ecc[5 - i] & 0x04) { descriptor[(i * 4) + 17] = '1'; } else { descriptor[(i * 4) + 17] = '0'; }
|
||||||
if(desc_ecc[i] & 0x02) { descriptor[(i * 4) + 18] = '1'; }
|
if(desc_ecc[5 - i] & 0x02) { descriptor[(i * 4) + 18] = '1'; } else { descriptor[(i * 4) + 18] = '0'; }
|
||||||
if(desc_ecc[i] & 0x01) { descriptor[(i * 4) + 19] = '1'; }
|
if(desc_ecc[5 - i] & 0x01) { descriptor[(i * 4) + 19] = '1'; } else { descriptor[(i * 4) + 19] = '0'; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rs_free();
|
rs_free();
|
||||||
@ -977,9 +996,9 @@ int aztec(struct zint_symbol *symbol, unsigned char source[])
|
|||||||
/* Merge descriptor with the rest of the symbol */
|
/* Merge descriptor with the rest of the symbol */
|
||||||
for(i = 0; i < 40; i++) {
|
for(i = 0; i < 40; i++) {
|
||||||
if(compact) {
|
if(compact) {
|
||||||
bit_pattern[2000 + i] = descriptor[i];
|
bit_pattern[2000 + i - 2] = descriptor[i];
|
||||||
} else {
|
} else {
|
||||||
bit_pattern[20000 + i] = descriptor[i];
|
bit_pattern[20000 + i - 2] = descriptor[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user