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:
gitlost 2022-05-09 19:50:50 +01:00
parent 3b9d989894
commit f58c80e290
81 changed files with 12026 additions and 4701 deletions

View file

@ -34,6 +34,7 @@ static void test_large(int index, int debug) {
struct item {
int option_2;
int option_3;
char *pattern;
int length;
int ret;
@ -42,21 +43,27 @@ static void test_large(int index, int debug) {
};
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data[] = {
/* 0*/ { -1, "1", 2751, 0, 162, 162 },
/* 1*/ { -1, "1", 2752, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 2*/ { -1, "1", 2755, ZINT_ERROR_TOO_LONG, -1, -1 }, // Triggers buffer > 9191
/* 3*/ { -1, "A", 1836, 0, 162, 162 },
/* 4*/ { -1, "A", 1837, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 5*/ { -1, "\200", 1143, 0, 162, 162 },
/* 6*/ { -1, "\200", 1144, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 7*/ { 1, "1", 18, 0, 18, 18 },
/* 8*/ { 1, "1", 19, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 9*/ { 1, "A", 13, 0, 18, 18 },
/* 10*/ { 1, "A", 14, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 11*/ { 1, "\200", 7, 0, 18, 18 },
/* 12*/ { 1, "\200", 8, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 13*/ { 11, "1", 1995, 0, 138, 138 },
/* 14*/ { 11, "1", 1996, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 0*/ { -1, -1, "1", 2751, 0, 162, 162 },
/* 1*/ { -1, -1, "1", 2752, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 2*/ { -1, -1, "1", 2755, ZINT_ERROR_TOO_LONG, -1, -1 }, // Triggers buffer > 9191
/* 3*/ { -1, -1, "A", 1836, 0, 162, 162 },
/* 4*/ { -1, -1, "A", 1837, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 5*/ { -1, -1, "A1", 1529, 0, 162, 162 },
/* 6*/ { -1, -1, "A1", 1530, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 7*/ { -1, -1, "\200", 1143, 0, 162, 162 },
/* 8*/ { -1, -1, "\200", 1144, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 9*/ { -1, ZINT_FULL_MULTIBYTE, "\241", 1410, 0, 162, 162 },
/* 10*/ { -1, ZINT_FULL_MULTIBYTE, "\241", 1412, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 11*/ { 1, -1, "1", 18, 0, 18, 18 },
/* 12*/ { 1, -1, "1", 19, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 13*/ { 1, -1, "A", 13, 0, 18, 18 },
/* 14*/ { 1, -1, "A", 14, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 15*/ { 1, -1, "\200", 7, 0, 18, 18 },
/* 16*/ { 1, -1, "\200", 8, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 17*/ { 1, ZINT_FULL_MULTIBYTE, "\241", 8, 0, 18, 18 },
/* 18*/ { 1, ZINT_FULL_MULTIBYTE, "\241", 10, ZINT_ERROR_TOO_LONG, -1, -1 },
/* 19*/ { 11, -1, "1", 1995, 0, 138, 138 },
/* 20*/ { 11, -1, "1", 1996, ZINT_ERROR_TOO_LONG, -1, -1 },
};
int data_size = ARRAY_SIZE(data);
int i, length, ret;
@ -76,7 +83,7 @@ static void test_large(int index, int debug) {
testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length);
assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf));
length = testUtilSetSymbol(symbol, BARCODE_GRIDMATRIX, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug);
length = testUtilSetSymbol(symbol, BARCODE_GRIDMATRIX, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, data[i].option_3, -1 /*output_options*/, data_buf, data[i].length, debug);
ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
@ -501,6 +508,351 @@ static void test_encode(int index, int generate, int debug) {
testFinish();
}
static void test_encode_segs(int index, int generate, int debug) {
struct item {
int input_mode;
int option_1;
int option_2;
struct zint_structapp structapp;
struct zint_seg segs[3];
int ret;
int expected_rows;
int expected_width;
char *comment;
char *expected;
};
struct item data[] = {
/* 0*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 7 }, { TU(""), 0, 0 } }, 0, 30, 30, "Standard example",
"111111000000111111000000111111"
"111101011110111111011110111111"
"100101011110111111011110111111"
"110011000000100001000000100001"
"110011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011100110111010000110001011110"
"010000111111000110111101011110"
"000010100001000110110001000000"
"001000100001001100100001000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111101010110101001010000111111"
"101111011110100001000100111111"
"100011000000110111011000100001"
"110111000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011110110111010110110001011010"
"010110111111011110100001010000"
"011010100001000000101011011100"
"001000100001000000110001000110"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111001011100111111011000111111"
"100001001100111101001110111011"
"100001001010111011011110100011"
"101011000010100001001110100101"
"111111000000111111000000111111"
},
/* 1*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU(""), -1, 0 }, { TU("Ж"), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 30, 30, "Standard example auto-ECI",
"111111000000111111000000111111"
"111101011110111111011110111111"
"100101011110111111011110111111"
"110011000000100001000000100001"
"110011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011100110111010000110001011110"
"010000111111000110111101011110"
"000010100001000110110001000000"
"001000100001001100100001000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111101010110101001010000111111"
"101111011110100001000100111111"
"100011000000110111011000100001"
"110111000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011110110111010110110001011010"
"010110111111011110100001010000"
"011010100001000000101011011100"
"001000100001000000110001000110"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111001011100111111011000111111"
"100001001100111101001110111011"
"100001001010111011011110100011"
"101011000010100001001110100101"
"111111000000111111000000111111"
},
/* 2*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 7 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, 0, 30, 30, "Standard example inverted",
"111111000000111111000000111111"
"111001011110111111011110111111"
"101111011110111111011110111111"
"111101000000100001000000100001"
"101011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011010110111010000110001011110"
"000000111111000000100011011110"
"010000100001001010111011000000"
"011000100001010000110111000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111101010110101001010000111111"
"101011011110100011000110111111"
"111001000000111101000000100001"
"101011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011110110111010000110001011000"
"010000111111000000100011011000"
"001110100001001100101101001100"
"001100100001011000100001000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111111011110111101011000111111"
"101111011010110001001110111101"
"110011001000101101001010110111"
"111101011000101001011010101001"
"111111000000111111000000111111"
},
/* 3*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("Ж"), -1, 0 }, { TU(""), -1, 0 }, { TU(""), 0, 0 } }, ZINT_WARN_USES_ECI, 30, 30, "Standard example inverted auto-ECI",
"111111000000111111000000111111"
"111001011110111111011110111111"
"101111011110111111011110111111"
"111101000000100001000000100001"
"101011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011010110111010000110001011110"
"000000111111000000100011011110"
"010000100001001010111011000000"
"011000100001010000110111000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111101010110101001010000111111"
"101011011110100011000110111111"
"111001000000111101000000100001"
"101011000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011110110111010000110001011000"
"010000111111000000100011011000"
"001110100001001100101101001100"
"001100100001011000100001000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111111011110111101011000111111"
"101111011010110001001110111101"
"110011001000101101001010110111"
"111101011000101001011010101001"
"111111000000111111000000111111"
},
/* 4*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("product:Google Pixel 4a - 128 GB of Storage - Black;price:$439.97"), -1, 3 }, { TU("品名:Google 谷歌 Pixel 4a -128 GB的存储空间-黑色;零售价:¥3149.79"), -1, 29 }, { TU("Produkt:Google Pixel 4a - 128 GB Speicher - Schwarz;Preis:444,90 €"), -1, 17 } }, 0, 78, 78, "AIM ITS/04-023:2022 Annex A example",
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100101000100100101000110100001000100100101000000100111000010100111000000100001"
"101001011010100111011110101001011100101111001110100001001110111101000110100101"
"101111011000100011001010101111000000110001000100110101001010110111001010111001"
"101011001010110111000010101111011100111011011100101001001100111101000000101101"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000000111011011010111001011000111001011010111111011010111111011110111011000100"
"011110101101010010110001000000101111010110111111000000100011011110111111011010"
"010010100001011010110101001010100011010000101001011110110001000010111111001100"
"001000100111000000110011001010111111000000110001011100100001011010101011010100"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100101011000110001010110110111010010110111010000110011010110110111011010100011"
"111001010010110001001100111011010100111111001110101111011100111101010110110001"
"111101011110100011000000111001001010100001001010110111000110111111000000101111"
"111111000010110111010000111011001000100011000010110011011100110101000000110001"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000100111001010110101101001000101001001000101111001000101011010100111111000110"
"000010111011011000110011011010111011011110101001011100110101011010111111010000"
"010010110001000000111011011110101001010010100011010110111011011110100011001010"
"011110100001000010111111011010110011011010110001011110111111000110101111011110"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100101011100110111001100100111000100100101000110100111001110110011011100100111"
"100011010100101111011110110001001110101111010000110001011000111011010010100001"
"111001010110111001000100101111000000110111000100111111000100101101011110101011"
"111101011010100011001010100111000100111111000100101101001010100001011110111111"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000010111111010110101101000000111101011000111101000110101111010110111111000000"
"001010111111011100100001010000110001000000100111011110110011011110100011001100"
"010110100111001100101011010110110001010110111101011000111001011100110001010100"
"000010100101011010101001011110110111011100101111010010100001001110100001010100"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100101011010110111001100100011011000110101011010100001001010110001011110100011"
"110111011010111011011100100011011100111111010110111111000000110001011110110011"
"110111010000110011001110111001010110101101001000111101010100100011001110110011"
"101111000000111111011000100101010110100001011010110001001000100001011110111111"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000110111001010100101101000100111011011010111111000010101101010000111011000000"
"011000111001001010111001010000100101010110111001001110101111001100101101001010"
"011010110101000010110011011010101011000010101101011100111101001010101111010110"
"011010101001001010101101011110111001010010101101000100101001000010100101000100"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100001011110110111001000100101000010100011000010100001001010110001011100100011"
"110011011110100001001000100001001010110111010100101101000000110001011110101101"
"110001001110111001001110100111001000101011011100100111000000111011010000100001"
"111011001000101111011010110111011110110011001100111111010000110111000000100111"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000110111111010000101001001100101111001100101101001100101111010010111111000010"
"000110100111000000100111011010100001011110101001011010111101011010111111000000"
"001010110001011100100101001110100001011100111001000100101011000100100001001000"
"000000100001010010100011001110111111001110100001000110111111001110100011001010"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100001011010110001010100110011010010110111010100110011010010110101011000100011"
"111111010100100111001110111111010010110101011000110011011110111011001010100111"
"111001011110110101011010100111011010110111011100101111001100100001001100100111"
"110011011100111001011100101111000000101011011110111011011010110011010110111001"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"000000111111011110111101011110111001011010111111011110111111011110111001000010"
"001100111111000000111011011110101101011110111111000000101011011110100001000010"
"010010101111010000110111000000110001010110101001000000110111001010100001000110"
"000100111111000000101111010110100001011110110101000000110101010010100001001000"
"000000111111000000111111000000111111000000111111000000111111000000111111000000"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
"100111000110100111000110100101000110100101000100100011000100100111000100100011"
"110011011100111011000100100011001010111001000110110101001100110011000110100001"
"111001000010100011001010100001000010100111010110111011000000110101011100110111"
"110111001010111011001010101011001000101111011110111001011010111111010100111111"
"111111000000111111000000111111000000111111000000111111000000111111000000111111"
},
/* 5*/ { DATA_MODE, -1, -1, { 0, 0, "" }, { { TU("\266"), 1, 0 }, { TU("\266"), 1, 7 }, { TU("\266"), 1, 0 } }, 0, 30, 30, "Standard example + extra seg, data mode",
"111111000000111111000000111111"
"111101011110111111011110111111"
"111011011110111111011110111111"
"111101000000100001000000100001"
"101001000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011010110111010000110001011110"
"000010111111000110111101011110"
"001010100001000110110001000000"
"011100100001001100100001000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111111010000101001010000111111"
"101111000000100001000100111111"
"110001001100110111011000100001"
"101111000000100001000000100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011110110001010010110001011010"
"010100110111010110111001001100"
"000110100001000000101011010010"
"010000100001000000110001000110"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111011011010111101011010111111"
"111001000110101111011000101001"
"111101011000111011010010111011"
"101101011100110001001000111001"
"111111000000111111000000111111"
},
/* 6*/ { UNICODE_MODE, -1, -1, { 1, 16, "" }, { { TU("齄齄"), -1, 29 }, { TU("Τεχτ"), -1, 0 }, { TU("Text"), -1, 0 } }, ZINT_WARN_USES_ECI, 30, 30, "Structured Append",
"111111000000111111000000111111"
"111011011000111101011010111111"
"101011000000101111001110100001"
"111011000010110111011100100011"
"110101010000101001000100111101"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011000110101010000110111011110"
"010110110001000010111111011110"
"011010100111011010111111000000"
"011100111111010000110111000000"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111011010100101001010110111111"
"111111011110101111011110111111"
"100101010010101101011010100001"
"100101011000100001011100100001"
"111111000000111111000000111111"
"000000111111000000111111000000"
"011100110111010010110011011100"
"010110110101001100110001011000"
"000100110001000000101111010100"
"000100100011000100100001001010"
"000000111111000000111111000000"
"111111000000111111000000111111"
"111011011010111001011000111011"
"111001010110100101011000111001"
"110111000010101001011100110011"
"100011011010111011001110101011"
"111111000000111111000000111111"
},
};
int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret;
struct zint_symbol *symbol;
char escaped[8192];
testStart("test_encode_segs");
for (i = 0; i < data_size; i++) {
if (index != -1 && i != index) continue;
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
testUtilSetSymbol(symbol, BARCODE_GRIDMATRIX, data[i].input_mode, -1 /*eci*/,
data[i].option_1, data[i].option_2, -1, -1 /*output_options*/,
NULL, 0, debug);
for (j = 0, seg_count = 0; j < 3 && data[i].segs[j].length; j++, seg_count++);
ret = ZBarcode_Encode_Segs(symbol, data[i].segs, seg_count);
assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode_Segs ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
if (generate) {
char escaped1[8192];
char escaped2[8192];
int length = data[i].segs[0].length == -1 ? (int) ustrlen(data[i].segs[0].source) : data[i].segs[0].length;
int length1 = data[i].segs[1].length == -1 ? (int) ustrlen(data[i].segs[1].source) : data[i].segs[1].length;
int length2 = data[i].segs[2].length == -1 ? (int) ustrlen(data[i].segs[2].source) : data[i].segs[2].length;
printf(" /*%3d*/ { %s, %d, %d, { %d, %d, \"%s\" }, { { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d }, { TU(\"%s\"), %d, %d } }, %s, %d, %d, \"%s\",\n",
i, testUtilInputModeName(data[i].input_mode), data[i].option_1, data[i].option_2,
data[i].structapp.index, data[i].structapp.count, data[i].structapp.id,
testUtilEscape((const char *) data[i].segs[0].source, length, escaped, sizeof(escaped)), data[i].segs[0].length, data[i].segs[0].eci,
testUtilEscape((const char *) data[i].segs[1].source, length1, escaped1, sizeof(escaped1)), data[i].segs[1].length, data[i].segs[1].eci,
testUtilEscape((const char *) data[i].segs[2].source, length2, escaped2, sizeof(escaped2)), data[i].segs[2].length, data[i].segs[2].eci,
testUtilErrorName(data[i].ret),
symbol->rows, symbol->width, data[i].comment);
testUtilModulesPrint(symbol, " ", "\n");
printf(" },\n");
} else {
if (ret < ZINT_ERROR) {
int width, row;
assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d\n", i, ret, width, row);
}
}
ZBarcode_Delete(symbol);
}
testFinish();
}
#include <time.h>
#define TEST_PERF_ITERATIONS 1000
@ -593,6 +945,7 @@ int main(int argc, char *argv[]) {
{ "test_options", test_options, 1, 0, 1 },
{ "test_input", test_input, 1, 1, 1 },
{ "test_encode", test_encode, 1, 1, 1 },
{ "test_encode_segs", test_encode_segs, 1, 1, 1 },
{ "test_perf", test_perf, 1, 0, 1 },
};