mirror of
https://git.code.sf.net/p/zint/code
synced 2025-05-12 22:25:59 -04:00
Add multiple segments support for AZTEC, CODEONE, DATAMATRIX, DOTCODE,
GRIDMATRIX, HANXIN, MAXICODE, MICROPDF417, PDF417, QRCODE, RMQR, ULTRA RMQR: fix ECI encoding (wrong bit length for indicator) MICROQR: check versions M1 and M2 for allowed characters so as to give better error messages DOTCODE: some small optimizations common.c: add is_chr(), segs_length(), segs_cpy() CODEONE/CODE128/DOTCODE/GRIDMATRIX/HANXIN/MAXICODE/QRCODE/ULTRA: add namespace prefixes to static funcs/data includes: use Z_ prefix, unuse double underscore prefixes (guard defines) manual.txt: compress some tables using double/treble column sets
This commit is contained in:
parent
3b9d989894
commit
f58c80e290
81 changed files with 12026 additions and 4701 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
Copyright (C) 2010-2021 Robin Stuart <rstuart114@gmail.com>
|
||||
Copyright (C) 2010-2022 Robin Stuart <rstuart114@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
@ -29,7 +29,6 @@
|
|||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
||||
/* Includes corrections thanks to Monica Swanson @ Source Technologies */
|
||||
#include <stdio.h>
|
||||
|
@ -114,7 +113,7 @@ static void maxi_bump(unsigned char set[], unsigned char character[], const int
|
|||
}
|
||||
|
||||
/* If the value is present in array, return the value, else return badvalue */
|
||||
static int value_in_array(const unsigned char val, const unsigned char arr[], const int badvalue,
|
||||
static int maxi_value_in_array(const unsigned char val, const unsigned char arr[], const int badvalue,
|
||||
const int arrLength) {
|
||||
int i;
|
||||
for (i = 0; i < arrLength; i++) {
|
||||
|
@ -125,13 +124,13 @@ static int value_in_array(const unsigned char val, const unsigned char arr[], co
|
|||
|
||||
/* Choose the best set from previous and next set in the range of the setval array, if no value can be found we
|
||||
* return setval[0] */
|
||||
static int bestSurroundingSet(const int index, const int length, const unsigned char set[],
|
||||
static int maxi_bestSurroundingSet(const int index, const int length, const unsigned char set[], const int sp,
|
||||
const unsigned char setval[], const int setLength) {
|
||||
int badValue = -1;
|
||||
int option1 = value_in_array(set[index - 1], setval, badValue, setLength);
|
||||
int option1 = maxi_value_in_array(set[sp + index - 1], setval, badValue, setLength);
|
||||
if (index + 1 < length) {
|
||||
// we have two options to check (previous & next)
|
||||
int option2 = value_in_array(set[index + 1], setval, badValue, setLength);
|
||||
int option2 = maxi_value_in_array(set[sp + index + 1], setval, badValue, setLength);
|
||||
if (option2 != badValue && option1 > option2) {
|
||||
return option2;
|
||||
}
|
||||
|
@ -144,10 +143,11 @@ static int bestSurroundingSet(const int index, const int length, const unsigned
|
|||
}
|
||||
|
||||
/* Format text according to Appendix A */
|
||||
static int maxi_text_process(unsigned char maxi_codeword[144], const int mode, const unsigned char in_source[],
|
||||
int length, const int structapp_cw, const int eci, const int scm_vv, const int debug_print) {
|
||||
static int maxi_text_process(unsigned char set[144], unsigned char character[144], const int mode,
|
||||
const unsigned char in_source[], int length, const int eci, const int scm_vv, int *p_sp,
|
||||
const int debug_print) {
|
||||
|
||||
unsigned char set[144], character[144] = {0};
|
||||
int sp = *p_sp;
|
||||
int i, count, current_set, padding_set;
|
||||
|
||||
static const unsigned char set15[2] = { 1, 5 };
|
||||
|
@ -161,12 +161,38 @@ static int maxi_text_process(unsigned char maxi_codeword[144], const int mode, c
|
|||
unsigned char *source_buf = (unsigned char *) _alloca(length + 9);
|
||||
#endif
|
||||
|
||||
if (length > 144) {
|
||||
if (sp + length > 144) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Insert ECI at the beginning of message if needed */
|
||||
/* Encode ECI assignment numbers according to table 3 */
|
||||
if (eci != 0) {
|
||||
if (sp + 1 + length > 144) return ZINT_ERROR_TOO_LONG;
|
||||
character[sp++] = 27; // ECI
|
||||
if (eci <= 31) {
|
||||
if (sp + 1 + length > 144) return ZINT_ERROR_TOO_LONG;
|
||||
character[sp++] = eci;
|
||||
} else if (eci <= 1023) {
|
||||
if (sp + 2 + length > 144) return ZINT_ERROR_TOO_LONG;
|
||||
character[sp++] = 0x20 | ((eci >> 6) & 0x0F);
|
||||
character[sp++] = eci & 0x3F;
|
||||
} else if (eci <= 32767) {
|
||||
if (sp + 3 + length > 144) return ZINT_ERROR_TOO_LONG;
|
||||
character[sp++] = 0x30 | ((eci >> 12) & 0x07);
|
||||
character[sp++] = (eci >> 6) & 0x3F;
|
||||
character[sp++] = eci & 0x3F;
|
||||
} else {
|
||||
if (sp + 4 + length > 144) return ZINT_ERROR_TOO_LONG;
|
||||
character[sp++] = 0x38 | ((eci >> 18) & 0x03);
|
||||
character[sp++] = (eci >> 12) & 0x3F;
|
||||
character[sp++] = (eci >> 6) & 0x3F;
|
||||
character[sp++] = eci & 0x3F;
|
||||
}
|
||||
}
|
||||
|
||||
if (scm_vv != -1) { /* Add SCM prefix */
|
||||
if (length > 135) {
|
||||
if (sp + length > 135) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
}
|
||||
sprintf((char *) source_buf, "[)>\03601\035%02d", scm_vv); /* [)>\R01\Gvv */
|
||||
|
@ -175,117 +201,115 @@ static int maxi_text_process(unsigned char maxi_codeword[144], const int mode, c
|
|||
length += 9;
|
||||
}
|
||||
|
||||
memset(set, 255, 144);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
/* Look up characters in table from Appendix A - this gives
|
||||
value and code set for most characters */
|
||||
set[i] = maxiCodeSet[source[i]];
|
||||
character[i] = maxiSymbolChar[source[i]];
|
||||
set[sp + i] = maxiCodeSet[source[i]];
|
||||
character[sp + i] = maxiSymbolChar[source[i]];
|
||||
}
|
||||
|
||||
/* If a character can be represented in more than one code set,
|
||||
pick which version to use */
|
||||
if (set[0] == 0) {
|
||||
if (character[0] == 13) {
|
||||
character[0] = 0;
|
||||
if (set[sp + 0] == 0) {
|
||||
if (character[sp + 0] == 13) {
|
||||
character[sp + 0] = 0;
|
||||
}
|
||||
set[0] = 1;
|
||||
set[sp + 0] = 1;
|
||||
}
|
||||
|
||||
for (i = 1; i < length; i++) {
|
||||
if (set[i] == 0) {
|
||||
if (set[sp + i] == 0) {
|
||||
/* Special character */
|
||||
if (character[i] == 13) {
|
||||
if (character[sp + i] == 13) {
|
||||
/* Carriage Return */
|
||||
set[i] = bestSurroundingSet(i, length, set, set15, 2);
|
||||
if (set[i] == 5) {
|
||||
character[i] = 13;
|
||||
set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set15, 2);
|
||||
if (set[sp + i] == 5) {
|
||||
character[sp + i] = 13;
|
||||
} else {
|
||||
character[i] = 0;
|
||||
character[sp + i] = 0;
|
||||
}
|
||||
|
||||
} else if (character[i] == 28) {
|
||||
} else if (character[sp + i] == 28) {
|
||||
/* FS */
|
||||
set[i] = bestSurroundingSet(i, length, set, set12345, 5);
|
||||
if (set[i] == 5) {
|
||||
character[i] = 32;
|
||||
set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5);
|
||||
if (set[sp + i] == 5) {
|
||||
character[sp + i] = 32;
|
||||
}
|
||||
|
||||
} else if (character[i] == 29) {
|
||||
} else if (character[sp + i] == 29) {
|
||||
/* GS */
|
||||
set[i] = bestSurroundingSet(i, length, set, set12345, 5);
|
||||
if (set[i] == 5) {
|
||||
character[i] = 33;
|
||||
set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5);
|
||||
if (set[sp + i] == 5) {
|
||||
character[sp + i] = 33;
|
||||
}
|
||||
|
||||
} else if (character[i] == 30) {
|
||||
} else if (character[sp + i] == 30) {
|
||||
/* RS */
|
||||
set[i] = bestSurroundingSet(i, length, set, set12345, 5);
|
||||
if (set[i] == 5) {
|
||||
character[i] = 34;
|
||||
set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5);
|
||||
if (set[sp + i] == 5) {
|
||||
character[sp + i] = 34;
|
||||
}
|
||||
|
||||
} else if (character[i] == 32) {
|
||||
} else if (character[sp + i] == 32) {
|
||||
/* Space */
|
||||
set[i] = bestSurroundingSet(i, length, set, set12345, 5);
|
||||
if (set[i] == 1) {
|
||||
character[i] = 32;
|
||||
} else if (set[i] == 2) {
|
||||
character[i] = 47;
|
||||
set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12345, 5);
|
||||
if (set[sp + i] == 1) {
|
||||
character[sp + i] = 32;
|
||||
} else if (set[sp + i] == 2) {
|
||||
character[sp + i] = 47;
|
||||
} else {
|
||||
character[i] = 59;
|
||||
character[sp + i] = 59;
|
||||
}
|
||||
|
||||
} else if (character[i] == 44) {
|
||||
} else if (character[sp + i] == 44) {
|
||||
/* Comma */
|
||||
set[i] = bestSurroundingSet(i, length, set, set12, 2);
|
||||
if (set[i] == 2) {
|
||||
character[i] = 48;
|
||||
set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2);
|
||||
if (set[sp + i] == 2) {
|
||||
character[sp + i] = 48;
|
||||
}
|
||||
|
||||
} else if (character[i] == 46) {
|
||||
} else if (character[sp + i] == 46) {
|
||||
/* Full Stop */
|
||||
set[i] = bestSurroundingSet(i, length, set, set12, 2);
|
||||
if (set[i] == 2) {
|
||||
character[i] = 49;
|
||||
set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2);
|
||||
if (set[sp + i] == 2) {
|
||||
character[sp + i] = 49;
|
||||
}
|
||||
|
||||
} else if (character[i] == 47) {
|
||||
} else if (character[sp + i] == 47) {
|
||||
/* Slash */
|
||||
set[i] = bestSurroundingSet(i, length, set, set12, 2);
|
||||
if (set[i] == 2) {
|
||||
character[i] = 50;
|
||||
set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2);
|
||||
if (set[sp + i] == 2) {
|
||||
character[sp + i] = 50;
|
||||
}
|
||||
|
||||
} else if (character[i] == 58) {
|
||||
} else if (character[sp + i] == 58) {
|
||||
/* Colon */
|
||||
set[i] = bestSurroundingSet(i, length, set, set12, 2);
|
||||
if (set[i] == 2) {
|
||||
character[i] = 51;
|
||||
set[sp + i] = maxi_bestSurroundingSet(i, length, set, sp, set12, 2);
|
||||
if (set[sp + i] == 2) {
|
||||
character[sp + i] = 51;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
padding_set = set[length - 1] == 2 ? 2 : 1;
|
||||
for (i = length; i < 144; i++) {
|
||||
padding_set = set[sp + length - 1] == 2 ? 2 : 1;
|
||||
for (i = length; sp + i < 144; i++) {
|
||||
/* Add the padding */
|
||||
set[i] = padding_set;
|
||||
character[i] = 33;
|
||||
set[sp + i] = padding_set;
|
||||
character[sp + i] = 33;
|
||||
}
|
||||
|
||||
/* Find candidates for number compression */
|
||||
/* Note the prohibition on number compression in the primary message in ISO/IEC 16023:2000 B.1 (1)
|
||||
applies to modes 2 & 3 only */
|
||||
count = 0;
|
||||
for (i = 0; i < 144; i++) {
|
||||
if ((set[i] == 1) && ((character[i] >= 48) && (character[i] <= 57))) {
|
||||
for (i = 0; sp + i < 144; i++) {
|
||||
if ((set[sp + i] == 1) && ((character[sp + i] >= 48) && (character[sp + i] <= 57))) {
|
||||
/* Character is a number */
|
||||
count++;
|
||||
if (count == 9) {
|
||||
/* Nine digits in a row can be compressed */
|
||||
memset(set + i - 8, 6, 9); /* Set set of nine digits to 6 */
|
||||
memset(set + sp + i - 8, 6, 9); /* Set set of nine digits to 6 */
|
||||
count = 0;
|
||||
}
|
||||
} else {
|
||||
|
@ -298,58 +322,59 @@ static int maxi_text_process(unsigned char maxi_codeword[144], const int mode, c
|
|||
i = 0;
|
||||
do {
|
||||
|
||||
if ((set[i] != current_set) && (set[i] != 6)) {
|
||||
switch (set[i]) {
|
||||
if ((set[sp + i] != current_set) && (set[sp + i] != 6)) {
|
||||
switch (set[sp + i]) {
|
||||
case 1:
|
||||
if (current_set == 2) { /* Set B */
|
||||
if (i + 1 < 144 && set[i + 1] == 1) {
|
||||
if (i + 2 < 144 && set[i + 2] == 1) {
|
||||
if (i + 3 < 144 && set[i + 3] == 1) {
|
||||
if (sp + i + 1 < 144 && set[sp + i + 1] == 1) {
|
||||
if (sp + i + 2 < 144 && set[sp + i + 2] == 1) {
|
||||
if (sp + i + 3 < 144 && set[sp + i + 3] == 1) {
|
||||
/* Latch A */
|
||||
maxi_bump(set, character, i, &length);
|
||||
character[i] = 63; /* Set B Latch A */
|
||||
maxi_bump(set, character, sp + i, &length);
|
||||
character[sp + i] = 63; /* Set B Latch A */
|
||||
current_set = 1;
|
||||
i += 3; /* Next 3 Set A so skip over */
|
||||
if (debug_print) printf("LCHA ");
|
||||
} else {
|
||||
/* 3 Shift A */
|
||||
maxi_bump(set, character, i, &length);
|
||||
character[i] = 57; /* Set B triple shift A */
|
||||
maxi_bump(set, character, sp + i, &length);
|
||||
character[sp + i] = 57; /* Set B triple shift A */
|
||||
i += 2; /* Next 2 Set A so skip over */
|
||||
if (debug_print) printf("3SHA ");
|
||||
}
|
||||
} else {
|
||||
/* 2 Shift A */
|
||||
maxi_bump(set, character, i, &length);
|
||||
character[i] = 56; /* Set B double shift A */
|
||||
maxi_bump(set, character, sp + i, &length);
|
||||
character[sp + i] = 56; /* Set B double shift A */
|
||||
i++; /* Next Set A so skip over */
|
||||
if (debug_print) printf("2SHA ");
|
||||
}
|
||||
} else {
|
||||
/* Shift A */
|
||||
maxi_bump(set, character, i, &length);
|
||||
character[i] = 59; /* Set A Shift B */
|
||||
maxi_bump(set, character, sp + i, &length);
|
||||
character[sp + i] = 59; /* Set A Shift B */
|
||||
if (debug_print) printf("SHA ");
|
||||
}
|
||||
} else { /* All sets other than B only have latch */
|
||||
/* Latch A */
|
||||
maxi_bump(set, character, i, &length);
|
||||
character[i] = 58; /* Sets C,D,E Latch A */
|
||||
maxi_bump(set, character, sp + i, &length);
|
||||
character[sp + i] = 58; /* Sets C,D,E Latch A */
|
||||
current_set = 1;
|
||||
if (debug_print) printf("LCHA ");
|
||||
}
|
||||
break;
|
||||
case 2: /* Set B */
|
||||
if (current_set != 1 || (i + 1 < 144 && set[i + 1] == 2)) { /* If not Set A or next Set B */
|
||||
/* If not Set A or next Set B */
|
||||
if (current_set != 1 || (sp + i + 1 < 144 && set[sp + i + 1] == 2)) {
|
||||
/* Latch B */
|
||||
maxi_bump(set, character, i, &length);
|
||||
character[i] = 63; /* Sets A,C,D,E Latch B */
|
||||
maxi_bump(set, character, sp + i, &length);
|
||||
character[sp + i] = 63; /* Sets A,C,D,E Latch B */
|
||||
current_set = 2;
|
||||
if (debug_print) printf("LCHB ");
|
||||
} else { /* Only available from Set A */
|
||||
/* Shift B */
|
||||
maxi_bump(set, character, i, &length);
|
||||
character[i] = 59; /* Set B Shift A */
|
||||
maxi_bump(set, character, sp + i, &length);
|
||||
character[sp + i] = 59; /* Set B Shift A */
|
||||
if (debug_print) printf("SHB ");
|
||||
}
|
||||
break;
|
||||
|
@ -357,116 +382,107 @@ static int maxi_text_process(unsigned char maxi_codeword[144], const int mode, c
|
|||
case 4: /* Set D */
|
||||
case 5: /* Set E */
|
||||
/* If first and next 3 same set, or not first and previous and next 2 same set */
|
||||
if ((i == 0 && i + 3 < 144 && set[i + 1] == set[i] && set[i + 2] == set[i]
|
||||
&& set[i + 3] == set[i])
|
||||
|| (i > 0 && set[i - 1] == set[i] && i + 2 < 144 && set[i + 1] == set[i]
|
||||
&& set[i + 2] == set[i])) {
|
||||
if ((sp + i == 0 && sp + i + 3 < 144 && set[sp + i + 1] == set[sp + i]
|
||||
&& set[sp + i + 2] == set[sp + i] && set[sp + i + 3] == set[sp + i])
|
||||
|| (sp + i > 0 && set[sp + i - 1] == set[sp + i] && sp + i + 2 < 144
|
||||
&& set[sp + i + 1] == set[sp + i] && set[sp + i + 2] == set[sp + i])) {
|
||||
/* Lock in C/D/E */
|
||||
if (i == 0) {
|
||||
maxi_bump(set, character, i, &length);
|
||||
character[i] = 60 + set[i] - 3;
|
||||
if (sp + i == 0) {
|
||||
maxi_bump(set, character, sp + i, &length);
|
||||
character[sp + i] = 60 + set[sp + i] - 3;
|
||||
i++; /* Extra bump */
|
||||
maxi_bump(set, character, i, &length);
|
||||
character[i] = 60 + set[i] - 3;
|
||||
maxi_bump(set, character, sp + i, &length);
|
||||
character[sp + i] = 60 + set[sp + i] - 3;
|
||||
i += 3; /* Next 3 same set so skip over */
|
||||
} else {
|
||||
/* Add single Shift to previous Shift */
|
||||
maxi_bump(set, character, i - 1, &length);
|
||||
character[i - 1] = 60 + set[i] - 3;
|
||||
maxi_bump(set, character, sp + i - 1, &length);
|
||||
character[sp + i - 1] = 60 + set[sp + i] - 3;
|
||||
i += 2; /* Next 2 same set so skip over */
|
||||
}
|
||||
current_set = set[i];
|
||||
if (debug_print) printf("LCK%c ", 'C' + set[i] - 3);
|
||||
current_set = set[sp + i];
|
||||
if (debug_print) printf("LCK%c ", 'C' + set[sp + i] - 3);
|
||||
} else {
|
||||
/* Shift C/D/E */
|
||||
maxi_bump(set, character, i, &length);
|
||||
character[i] = 60 + set[i] - 3;
|
||||
if (debug_print) printf("SH%c ", 'C' + set[i] - 3);
|
||||
maxi_bump(set, character, sp + i, &length);
|
||||
character[sp + i] = 60 + set[sp + i] - 3;
|
||||
if (debug_print) printf("SH%c ", 'C' + set[sp + i] - 3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++; /* Allow for bump */
|
||||
}
|
||||
i++;
|
||||
} while (i < 144);
|
||||
} while (sp + i < 144);
|
||||
|
||||
if (debug_print) printf("\n");
|
||||
|
||||
/* Number compression has not been forgotten! - It's handled below */
|
||||
i = 0;
|
||||
do {
|
||||
if (set[i] == 6) {
|
||||
if (set[sp + i] == 6) {
|
||||
/* Number compression */
|
||||
int value = to_int(character + i, 9);
|
||||
int value = to_int(character + sp + i, 9);
|
||||
|
||||
character[i] = 31; /* NS */
|
||||
character[i + 1] = (value & 0x3f000000) >> 24;
|
||||
character[i + 2] = (value & 0xfc0000) >> 18;
|
||||
character[i + 3] = (value & 0x3f000) >> 12;
|
||||
character[i + 4] = (value & 0xfc0) >> 6;
|
||||
character[i + 5] = (value & 0x3f);
|
||||
character[sp + i] = 31; /* NS */
|
||||
character[sp + i + 1] = (value & 0x3f000000) >> 24;
|
||||
character[sp + i + 2] = (value & 0xfc0000) >> 18;
|
||||
character[sp + i + 3] = (value & 0x3f000) >> 12;
|
||||
character[sp + i + 4] = (value & 0xfc0) >> 6;
|
||||
character[sp + i + 5] = (value & 0x3f);
|
||||
|
||||
i += 6;
|
||||
memmove(set + i, set + i + 3, 141 - i);
|
||||
memmove(character + i, character + i + 3, 141 - i);
|
||||
memmove(set + sp + i, set + sp + i + 3, 141 - (sp + i));
|
||||
memmove(character + sp + i, character + sp + i + 3, 141 - (sp + i));
|
||||
length -= 3;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
} while (i <= 135); /* 144 - 9 */
|
||||
|
||||
/* Insert ECI at the beginning of message if needed */
|
||||
/* Encode ECI assignment numbers according to table 3 */
|
||||
if (eci != 0) {
|
||||
maxi_bump(set, character, 0, &length);
|
||||
character[0] = 27; // ECI
|
||||
if (eci <= 31) {
|
||||
maxi_bump(set, character, 1, &length);
|
||||
character[1] = eci;
|
||||
} else if (eci <= 1023) {
|
||||
maxi_bump(set, character, 1, &length);
|
||||
maxi_bump(set, character, 1, &length);
|
||||
character[1] = 0x20 | ((eci >> 6) & 0x0F);
|
||||
character[2] = eci & 0x3F;
|
||||
} else if (eci <= 32767) {
|
||||
maxi_bump(set, character, 1, &length);
|
||||
maxi_bump(set, character, 1, &length);
|
||||
maxi_bump(set, character, 1, &length);
|
||||
character[1] = 0x30 | ((eci >> 12) & 0x07);
|
||||
character[2] = (eci >> 6) & 0x3F;
|
||||
character[3] = eci & 0x3F;
|
||||
} else {
|
||||
maxi_bump(set, character, 1, &length);
|
||||
maxi_bump(set, character, 1, &length);
|
||||
maxi_bump(set, character, 1, &length);
|
||||
maxi_bump(set, character, 1, &length);
|
||||
character[1] = 0x38 | ((eci >> 18) & 0x03);
|
||||
character[2] = (eci >> 12) & 0x3F;
|
||||
character[3] = (eci >> 6) & 0x3F;
|
||||
character[4] = eci & 0x3F;
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert Structured Append at beginning if needed */
|
||||
if (structapp_cw) {
|
||||
maxi_bump(set, character, 0, &length);
|
||||
character[0] = 33; // PAD
|
||||
maxi_bump(set, character, 1, &length);
|
||||
character[1] = structapp_cw;
|
||||
}
|
||||
} while (sp + i <= 135); /* 144 - 9 */
|
||||
|
||||
if (debug_print) printf("Length: %d\n", length);
|
||||
|
||||
if (((mode == 2) || (mode == 3)) && (length > 84)) {
|
||||
if (((mode == 2) || (mode == 3)) && (sp + length > 84)) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
|
||||
} else if (((mode == 4) || (mode == 6)) && (length > 93)) {
|
||||
} else if (((mode == 4) || (mode == 6)) && (sp + length > 93)) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
|
||||
} else if ((mode == 5) && (length > 77)) {
|
||||
} else if ((mode == 5) && (sp + length > 77)) {
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
}
|
||||
|
||||
*p_sp = sp + length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Call `maxi_text_process()` for each segment, dealing with Structured Append beforehand and populating
|
||||
`maxi_codeword` afterwards */
|
||||
static int maxi_text_process_segs(unsigned char maxi_codeword[144], const int mode, const struct zint_seg segs[],
|
||||
const int seg_count, const int structapp_cw, int scm_vv, const int debug_print) {
|
||||
unsigned char set[144], character[144] = {0};
|
||||
int i;
|
||||
int error_number;
|
||||
int sp = 0;
|
||||
|
||||
memset(set, 255, 144);
|
||||
|
||||
/* Insert Structured Append at beginning if needed */
|
||||
if (structapp_cw) {
|
||||
character[sp++] = 33; // PAD
|
||||
character[sp++] = structapp_cw;
|
||||
}
|
||||
|
||||
for (i = 0; i < seg_count; i++) {
|
||||
error_number = maxi_text_process(set, character, mode, segs[i].source, segs[i].length, segs[i].eci, scm_vv,
|
||||
&sp, debug_print);
|
||||
if (error_number != 0) {
|
||||
return error_number;
|
||||
}
|
||||
scm_vv = -1;
|
||||
}
|
||||
|
||||
/* Copy the encoded text into the codeword array */
|
||||
if ((mode == 2) || (mode == 3)) {
|
||||
for (i = 0; i < 84; i++) { /* secondary only */
|
||||
|
@ -534,9 +550,9 @@ static void maxi_do_primary_3(unsigned char maxi_codeword[144], unsigned char po
|
|||
maxi_codeword[9] = ((service & 0x3f0) >> 4);
|
||||
}
|
||||
|
||||
INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
INTERNAL int maxicode(struct zint_symbol *symbol, struct zint_seg segs[], const int seg_count) {
|
||||
int i, j, block, shift, mode, lp = 0;
|
||||
int error_number = 0, eclen;
|
||||
int error_number, eclen;
|
||||
unsigned char maxi_codeword[144] = {0};
|
||||
int scm_vv = -1;
|
||||
int structapp_cw = 0;
|
||||
|
@ -658,10 +674,10 @@ INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char source[], int le
|
|||
structapp_cw = (symbol->structapp.count - 1) | ((symbol->structapp.index - 1) << 3);
|
||||
}
|
||||
|
||||
i = maxi_text_process(maxi_codeword, mode, source, length, structapp_cw, symbol->eci, scm_vv, debug_print);
|
||||
if (i == ZINT_ERROR_TOO_LONG) {
|
||||
error_number = maxi_text_process_segs(maxi_codeword, mode, segs, seg_count, structapp_cw, scm_vv, debug_print);
|
||||
if (error_number == ZINT_ERROR_TOO_LONG) {
|
||||
strcpy(symbol->errtxt, "553: Input data too long");
|
||||
return i;
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* All the data is sorted - now do error correction */
|
||||
|
@ -724,3 +740,5 @@ INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char source[], int le
|
|||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 et : */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue