large.c: replace binary_load/add() etc with uint64_t based large_load/add() etc for performance

This commit is contained in:
gitlost 2020-06-14 14:42:40 +01:00
parent 3690c19749
commit e8a238aad1
14 changed files with 1566 additions and 804 deletions

View file

@ -133,11 +133,9 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
char postcode[10];
int postcode_type;
char pattern[10];
short int destination_postcode[112];
short int a[112];
short int b[112];
short int temp[112];
short int cdv[112];
large_int destination_postcode;
large_int b;
large_int cdv;
unsigned char data[26];
int data_top, data_step;
unsigned char check[7];
@ -170,7 +168,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
to_upper((unsigned char*) local_source);
if (symbol->debug) {
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Producing Mailmark %s\n", local_source);
}
@ -279,164 +277,107 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
}
// Convert postcode to internal user field
for (i = 0; i < 112; i++) {
destination_postcode[i] = 0;
a[i] = 0;
b[i] = 0;
}
large_load_u64(&destination_postcode, 0);
if (postcode_type != 7) {
strcpy(pattern, postcode_format[postcode_type - 1]);
binary_load(b, "0", 1);
large_load_u64(&b, 0);
for (i = 0; i < 9; i++) {
switch (pattern[i]) {
case 'F':
binary_multiply(b, "26");
binary_load(temp, "0", 1);
for (j = 0; j < 5; j++) {
if (posn(SET_F, postcode[i]) & (0x01 << j)) temp[j] = 1;
}
binary_add(b, temp);
large_mul_u64(&b, 26);
large_add_u64(&b, posn(SET_F, postcode[i]));
break;
case 'L':
binary_multiply(b, "20");
binary_load(temp, "0", 1);
for (j = 0; j < 5; j++) {
if (posn(SET_L, postcode[i]) & (0x01 << j)) temp[j] = 1;
}
binary_add(b, temp);
large_mul_u64(&b, 20);
large_add_u64(&b, posn(SET_L, postcode[i]));
break;
case 'N':
binary_multiply(b, "10");
binary_load(temp, "0", 1);
for (j = 0; j < 4; j++) {
if (posn(SET_N, postcode[i]) & (0x01 << j)) temp[j] = 1;
}
binary_add(b, temp);
large_mul_u64(&b, 10);
large_add_u64(&b, posn(SET_N, postcode[i]));
break;
// case 'S' ignorred as value is 0
// case 'S' ignored as value is 0
}
}
large_load(&destination_postcode, &b);
// destination_postcode = a + b
binary_load(destination_postcode, "0", 1);
binary_add(destination_postcode, b);
binary_load(a, "1", 1);
large_load_u64(&b, 1);
if (postcode_type == 1) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
binary_load(temp, "5408000000", 10);
binary_add(a, temp);
large_add_u64(&b, 5408000000);
if (postcode_type == 2) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
binary_load(temp, "5408000000", 10);
binary_add(a, temp);
large_add_u64(&b, 5408000000);
if (postcode_type == 3) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
binary_load(temp, "54080000000", 11);
binary_add(a, temp);
large_add_u64(&b, 54080000000);
if (postcode_type == 4) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
binary_load(temp, "140608000000", 12);
binary_add(a, temp);
large_add_u64(&b, 140608000000);
if (postcode_type == 5) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
binary_load(temp, "208000000", 9);
binary_add(a, temp);
large_add_u64(&b, 208000000);
if (postcode_type == 6) {
binary_add(destination_postcode, a);
large_add(&destination_postcode, &b);
}
}
// Conversion from Internal User Fields to Consolidated Data Value
// Set CDV to 0
binary_load(cdv, "0", 1);
large_load_u64(&cdv, 0);
// Add Destination Post Code plus DPS
binary_add(cdv, destination_postcode);
large_add(&cdv, &destination_postcode);
// Multiply by 100,000,000
binary_multiply(cdv, "100000000");
large_mul_u64(&cdv, 100000000);
// Add Item ID
binary_load(temp, "0", 1);
for (i = 0; i < 31; i++) {
if (0x01 & (item_id >> i)) temp[i] = 1;
}
binary_add(cdv, temp);
large_add_u64(&cdv, item_id);
if (length == 22) {
// Barcode C - Multiply by 100
binary_multiply(cdv, "100");
large_mul_u64(&cdv, 100);
} else {
// Barcode L - Multiply by 1,000,000
binary_multiply(cdv, "1000000");
large_mul_u64(&cdv, 1000000);
}
// Add Supply Chain ID
binary_load(temp, "0", 1);
for (i = 0; i < 20; i++) {
if (0x01 & (supply_chain_id >> i)) temp[i] = 1;
}
binary_add(cdv, temp);
large_add_u64(&cdv, supply_chain_id);
// Multiply by 15
binary_multiply(cdv, "15");
large_mul_u64(&cdv, 15);
// Add Class
binary_load(temp, "0", 1);
for (i = 0; i < 4; i++) {
if (0x01 & (mail_class >> i)) temp[i] = 1;
}
binary_add(cdv, temp);
large_add_u64(&cdv, mail_class);
// Multiply by 5
binary_multiply(cdv, "5");
large_mul_u64(&cdv, 5);
// Add Format
binary_load(temp, "0", 1);
for (i = 0; i < 4; i++) {
if (0x01 & (format >> i)) temp[i] = 1;
}
binary_add(cdv, temp);
large_add_u64(&cdv, format);
// Multiply by 4
binary_multiply(cdv, "4");
large_mul_u64(&cdv, 4);
// Add Version ID
binary_load(temp, "0", 1);
for (i = 0; i < 4; i++) {
if (0x01 & (version_id >> i)) temp[i] = 1;
}
binary_add(cdv, temp);
if (symbol->debug) {
large_add_u64(&cdv, version_id);
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("DPC type %d\n", postcode_type);
printf("CDV: ");
for (i = 96; i >= 0; i-= 4) {
j = 0;
j += cdv[i];
j += cdv[i + 1] * 2;
j += cdv[i + 2] * 4;
j += cdv[i + 3] * 8;
printf("%c", itoc(j));
}
printf("\n");
large_print(&cdv);
}
@ -451,49 +392,13 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
}
// Conversion from Consolidated Data Value to Data Numbers
for (i = 0; i < 112; i++) {
b[i] = cdv[i];
}
for (j = data_top; j >= (data_step + 1); j--) {
for (i = 0; i < 112; i++) {
cdv[i] = b[i];
b[i] = 0;
a[i] = 0;
}
a[96] = 1;
for (i = 91; i >= 0; i--) {
b[i] = !islarger(a, cdv);
if (b[i] == 1) {
binary_subtract(cdv, a);
}
shiftdown(a);
}
data[j] = (cdv[4] * 16) + (cdv[3] * 8) + (cdv[2] * 4) +
(cdv[1] * 2) + cdv[0];
for (j = data_top; j >= (data_step + 1); j--) {
data[j] = large_div_u64(&cdv, 32);
}
for (j = data_step; j >= 0; j--) {
for (i = 0; i < 112; i++) {
cdv[i] = b[i];
b[i] = 0;
a[i] = 0;
}
a[95] = 1;
a[94] = 1;
a[93] = 1;
a[92] = 1;
for (i = 91; i >= 0; i--) {
b[i] = !islarger(a, cdv);
if (b[i] == 1) {
binary_subtract(cdv, a);
}
shiftdown(a);
}
data[j] = (cdv[4] * 16) + (cdv[3] * 8) + (cdv[2] * 4) +
(cdv[1] * 2) + cdv[0];
data[j] = large_div_u64(&cdv, 30);
}
// Generation of Reed-Solomon Check Numbers
@ -507,7 +412,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
data[data_top + i] = check[check_count - i];
}
if (symbol->debug) {
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Codewords: ");
for (i = 0; i <= data_top + check_count; i++) {
printf("%d ", (int) data[i]);
@ -565,7 +470,7 @@ INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[],
bar[(length * 3)] = '\0';
if (symbol->debug) {
if (symbol->debug & ZINT_DEBUG_PRINT) {
printf("Bar pattern: %s\n", bar);
}