diff --git a/ChangeLog b/ChangeLog index 3b23b5c9..af4f700c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,7 +27,7 @@ Changes add minimal encodation algorithm (non-extended ASCII only), props Alex Geller (ZXing); reduce extended latch cut-off from 5 to 4 for better encodation in certain - cases, props lyngklip (BWIPP) + cases, props Bue Jensen (BWIPP) - library: return warning on invalid `input_mode` reset - library/CLI: expanded error messages - GS1: new AIs 7250-7259 (GSCN 22-246); @@ -37,7 +37,9 @@ Changes ticket #317, props Andre Maute; return warning if ECC < 5% (due to bit-stuffing when version given) - MAXICODE: zero-pad US postcodes that lack "+4" (Annex B.1.4a), from - OkapiBarcode, props Daniel Gredler + OkapiBarcode, props Daniel Gredler; + use code set E for padding as well, saves codeword, props Bue Jensen (BWIPP PR + #279) - GUI: use X11 (xcb) as platform instead of Wayland on Linux to avoid various weird behaviours; in "grpDATF.ui" use "PlainText" rather than "RichText" for tracker ratio @@ -65,6 +67,7 @@ Bugs Philip Ye - CODE128: fix extended char latching when exactly 3 extended chars at end - library: need to check for valid UTF-8 after de-escaping +- MAXICODE: maintain current set between segments Version 2.13.0 (2023-12-18) diff --git a/backend/maxicode.c b/backend/maxicode.c index 809d651f..99cfd6b7 100644 --- a/backend/maxicode.c +++ b/backend/maxicode.c @@ -31,6 +31,7 @@ /* SPDX-License-Identifier: BSD-3-Clause */ /* Includes corrections thanks to Monica Swanson @ Source Technologies */ +#include #include #include "common.h" #include "maxicode.h" @@ -140,12 +141,14 @@ static int maxi_bestSurroundingSet(const int index, const int length, const unsi } /* Format text according to Appendix A */ -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) { +static int maxi_text_process(unsigned char set[144], unsigned char character[144], const unsigned char in_source[], + int length, const int eci, const int scm_vv, int *p_sp, int current_set, const int debug_print) { int sp = *p_sp; - int i, count, current_set, padding_set; + int i, count; +#ifndef NDEBUG + int ns_count1 = 0, ns_count2 = 0; +#endif static const unsigned char set15[2] = { 1, 5 }; static const unsigned char set12[2] = { 1, 2 }; @@ -155,28 +158,28 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144 unsigned char *source_buf = (unsigned char *) z_alloca(length + 9); /* For prefixing 9-character SCM sequence */ if (sp + length > 144) { - return ZINT_ERROR_TOO_LONG; + return 0; } /* 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; + if (sp + 1 + length > 144) return 0; character[sp++] = 27; /* ECI */ if (eci <= 31) { - if (sp + 1 + length > 144) return ZINT_ERROR_TOO_LONG; + if (sp + 1 + length > 144) return 0; character[sp++] = eci; } else if (eci <= 1023) { - if (sp + 2 + length > 144) return ZINT_ERROR_TOO_LONG; + if (sp + 2 + length > 144) return 0; character[sp++] = 0x20 | ((eci >> 6) & 0x0F); character[sp++] = eci & 0x3F; } else if (eci <= 32767) { - if (sp + 3 + length > 144) return ZINT_ERROR_TOO_LONG; + if (sp + 3 + length > 144) return 0; 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; + if (sp + 4 + length > 144) return 0; character[sp++] = 0x38 | ((eci >> 18) & 0x03); character[sp++] = (eci >> 12) & 0x3F; character[sp++] = (eci >> 6) & 0x3F; @@ -186,7 +189,7 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144 if (scm_vv != -1) { /* Add SCM prefix */ if (sp + length > 135) { - return ZINT_ERROR_TOO_LONG; + return 0; } sprintf((char *) source_buf, "[)>\03601\035%02d", scm_vv); /* [)>\R01\Gvv */ memcpy(source_buf + 9, in_source, length); @@ -285,18 +288,11 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144 } } - padding_set = set[sp + length - 1] == 2 ? 2 : 1; - for (i = length; sp + i < 144; i++) { - /* Add the padding */ - 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; sp + i < 144; i++) { + for (i = 0; sp + i < 144 && sp + i < length; i++) { if ((set[sp + i] == 1) && ((character[sp + i] >= 48) && (character[sp + i] <= 57))) { /* Character is a number */ count++; @@ -304,6 +300,9 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144 /* Nine digits in a row can be compressed */ memset(set + sp + i - 8, 6, 9); /* Set set of nine digits to 6 */ count = 0; +#ifndef NDEBUG + ns_count1++; +#endif } } else { count = 0; @@ -311,9 +310,7 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144 } /* Add shift and latch characters */ - current_set = 1; - i = 0; - do { + for (i = 0; sp + i < 144 && set[sp + i] != 255; i++) { if ((set[sp + i] != current_set) && (set[sp + i] != 6)) { switch (set[sp + i]) { @@ -405,14 +402,10 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144 } i++; /* Allow for bump */ } - i++; - } while (sp + i < 144); - - if (debug_print) fputc('\n', stdout); + } /* Number compression has not been forgotten! - It's handled below */ - i = 0; - do { + for (i = 0; sp + i < 144 && sp + i <= length - 9; i++) { if (set[sp + i] == 6) { /* Number compression */ int value = to_int(character + sp + i, 9); @@ -424,30 +417,20 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144 character[sp + i + 4] = (value & 0xfc0) >> 6; character[sp + i + 5] = (value & 0x3f); - i += 6; - memmove(set + sp + i, set + sp + i + 3, 141 - (sp + i)); - memmove(character + sp + i, character + sp + i + 3, 141 - (sp + i)); + memmove(set + sp + i + 6, set + sp + i + 9, 144 - (sp + i + 9)); + memmove(character + sp + i + 6, character + sp + i + 9, 144 - (sp + i + 9)); + i += 5; length -= 3; - } else { - i++; +#ifndef NDEBUG + ns_count2++; +#endif } - } while (sp + i <= 135); /* 144 - 9 */ - - if (debug_print) printf("Length: %d\n", length); - - if (((mode == 2) || (mode == 3)) && (sp + length > 84)) { - return ZINT_ERROR_TOO_LONG; - - } else if (((mode == 4) || (mode == 6)) && (sp + length > 93)) { - return ZINT_ERROR_TOO_LONG; - - } else if ((mode == 5) && (sp + length > 77)) { - return ZINT_ERROR_TOO_LONG; } + assert(ns_count1 == ns_count2); *p_sp = sp + length; - return 0; + return current_set; } /* Call `maxi_text_process()` for each segment, dealing with Structured Append beforehand and populating @@ -456,8 +439,10 @@ static int maxi_text_process_segs(unsigned char maxi_codeword[144], const int mo 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; + int current_set = 1; /* Initial Code Set A */ + int padding_set = 0, padding_char = 0; /* Suppress clang-tidy-20 warnings */ + const int max_length = mode == 5 ? 77 : mode <= 3 ? 84 : 93; memset(set, 255, 144); @@ -468,14 +453,47 @@ static int maxi_text_process_segs(unsigned char maxi_codeword[144], const int mo } 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; + current_set = maxi_text_process(set, character, segs[i].source, segs[i].length, segs[i].eci, scm_vv, &sp, + current_set, debug_print); + if (current_set == 0) { + return ZINT_ERROR_TOO_LONG; } scm_vv = -1; } + /* If end in Code Set C or D, switch to A for padding */ + if (sp < max_length && (current_set == 3 || current_set == 4)) { + set[sp] = 1; + character[sp] = 58; /* Sets C,D Latch A */ + sp++; + current_set = 1; + if (debug_print) fputs("LCHA ", stdout); + } + + if (debug_print) { + if (sp < max_length) { + printf("\nPads (%d)\n", max_length - sp); + } else { + fputs("\nNo Pads\n", stdout); + } + } + + if (sp < max_length) { + padding_set = current_set == 5 ? 5 : current_set == 2 ? 2 : 1; + padding_char = current_set == 5 ? 28 : 33; + for (; sp < max_length; sp++) { + /* Add the padding */ + set[sp] = padding_set; + character[sp] = padding_char; + } + } + + if (debug_print) printf("Length: %d\n", sp); + + if (sp > max_length) { + return ZINT_ERROR_TOO_LONG; + } + /* Copy the encoded text into the codeword array */ if ((mode == 2) || (mode == 3)) { for (i = 0; i < 84; i++) { /* secondary only */ diff --git a/backend/tests/test_maxicode.c b/backend/tests/test_maxicode.c index beb4edc9..6f46ba7d 100644 --- a/backend/tests/test_maxicode.c +++ b/backend/tests/test_maxicode.c @@ -48,46 +48,52 @@ static void test_large(const testCtx *const p_ctx) { static const struct item data[] = { /* 0*/ { -1, -1, "1", 138, "", 0, 33, 30 }, /* Mode 4 (138 agrees with ISO/IEC 16023:2000) */ /* 1*/ { -1, -1, "1", 139, "", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 2*/ { -1, -1, "1", 145, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* Absolute max */ - /* 3*/ { -1, -1, "A", 93, "", 0, 33, 30 }, - /* 4*/ { -1, -1, "A", 94, "", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 5*/ { -1, -1, "\001", 90, "", 0, 33, 30 }, - /* 6*/ { -1, -1, "\001", 91, "", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 7*/ { -1, -1, "\200", 90, "", 0, 33, 30 }, - /* 8*/ { -1, -1, "\200", 91, "", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 9*/ { 2, -1, "1", 126, "123456789123123", 0, 33, 30 }, - /* 10*/ { 2, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 11*/ { 2, -1, "A", 84, "123456789123123", 0, 33, 30 }, - /* 12*/ { 2, -1, "A", 85, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 13*/ { 2, 96, "1", 109, "123456789123123", 0, 33, 30 }, - /* 14*/ { 2, 96, "1", 110, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 15*/ { 2, 96, "1", 136, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* Absolute max with SCM vv */ - /* 16*/ { 3, -1, "1", 126, "ABCDEF123123", 0, 33, 30 }, - /* 17*/ { 3, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 18*/ { 3, -1, "A", 84, "ABCDEF123123", 0, 33, 30 }, - /* 19*/ { 3, -1, "A", 85, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 20*/ { 3, 96, "1", 109, "ABCDEF123123", 0, 33, 30 }, - /* 21*/ { 3, 96, "1", 110, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 22*/ { 0, -1, "1", 126, "123456789123123", 0, 33, 30 }, /* Mode 2 */ - /* 23*/ { 0, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 24*/ { 0, -1, "1", 126, "ABCDEF123123", 0, 33, 30 }, /* Mode 3 */ - /* 25*/ { 0, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 26*/ { 5, -1, "1", 113, "", 0, 33, 30 }, /* Extra EEC */ - /* 27*/ { 5, -1, "1", 114, "", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 28*/ { 5, -1, "A", 77, "", 0, 33, 30 }, - /* 29*/ { 5, -1, "A", 78, "", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 30*/ { 6, -1, "1", 138, "", 0, 33, 30 }, - /* 31*/ { 6, -1, "1", 139, "", ZINT_ERROR_TOO_LONG, -1, -1 }, - /* 32*/ { 6, -1, "A", 93, "", 0, 33, 30 }, - /* 33*/ { 6, -1, "A", 94, "", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 2*/ { -1, -1, "1", 144, "", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 3*/ { -1, -1, "1", 145, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* Absolute max */ + /* 4*/ { -1, -1, "A", 93, "", 0, 33, 30 }, + /* 5*/ { -1, -1, "A", 94, "", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 6*/ { -1, -1, "\001", 91, "", 0, 33, 30 }, + /* 7*/ { -1, -1, "\001", 92, "", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 8*/ { -1, -1, "\200", 91, "", 0, 33, 30 }, + /* 9*/ { -1, -1, "\200", 92, "", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 10*/ { 2, -1, "1", 126, "123456789123123", 0, 33, 30 }, + /* 11*/ { 2, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 12*/ { 2, -1, "A", 84, "123456789123123", 0, 33, 30 }, + /* 13*/ { 2, -1, "A", 85, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 14*/ { 2, 96 + 1, "1", 109, "123456789123123", 0, 33, 30 }, + /* 15*/ { 2, 96 + 1, "1", 110, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 16*/ { 2, 96 + 1, "1", 136, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* Absolute max with SCM vv */ + /* 17*/ { 3, -1, "1", 126, "ABCDEF123123", 0, 33, 30 }, + /* 18*/ { 3, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 19*/ { 3, -1, "A", 84, "ABCDEF123123", 0, 33, 30 }, + /* 20*/ { 3, -1, "A", 85, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 21*/ { 3, 96 + 1, "1", 109, "ABCDEF123123", 0, 33, 30 }, + /* 22*/ { 3, 96 + 1, "1", 110, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 23*/ { 0, -1, "1", 126, "123456789123123", 0, 33, 30 }, /* Mode 2 */ + /* 24*/ { 0, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 25*/ { 0, -1, "1", 126, "ABCDEF123123", 0, 33, 30 }, /* Mode 3 */ + /* 26*/ { 0, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 27*/ { 5, -1, "1", 113, "", 0, 33, 30 }, /* Extra EEC */ + /* 28*/ { 5, -1, "1", 114, "", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 29*/ { 5, -1, "A", 77, "", 0, 33, 30 }, + /* 30*/ { 5, -1, "A", 78, "", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 31*/ { 6, -1, "1", 138, "", 0, 33, 30 }, + /* 32*/ { 6, -1, "1", 139, "", ZINT_ERROR_TOO_LONG, -1, -1 }, + /* 33*/ { 6, -1, "A", 93, "", 0, 33, 30 }, + /* 34*/ { 6, -1, "A", 94, "", ZINT_ERROR_TOO_LONG, -1, -1 }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; struct zint_symbol *symbol = NULL; char data_buf[256]; + char escaped[1024]; + char cmp_buf[32768]; + char cmp_msg[1024]; const char expected_errtxt[] = "Error 553: Input too long, requires too many codewords (maximum 144)"; + int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ + testStartSymbol("test_large", &symbol); for (i = 0; i < data_size; i++) { @@ -114,6 +120,20 @@ static void test_large(const testCtx *const p_ctx) { assert_zero(strcmp(symbol->errtxt, expected_errtxt), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, expected_errtxt); } + if (ret < ZINT_ERROR) { + if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data_buf, length, debug)) { + int cmp_len, ret_len; + char modules_dump[33 * 33 + 1]; + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, data_buf, length, modules_dump, cmp_buf, sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + + ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data_buf, length, symbol->primary, escaped, &ret_len); + assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped); + } + } + ZBarcode_Delete(symbol); } @@ -192,6 +212,10 @@ static void test_input(const testCtx *const p_ctx) { /* 49*/ { UNICODE_MODE, -1, -1, -1, { 1, 9, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 558: Structured Append count '9' out of range (2 to 8)", 1, 1, "" }, /* 50*/ { UNICODE_MODE, -1, -1, -1, { 3, 2, "" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 559: Structured Append index '3' out of range (1 to count 2)", 1, 1, "" }, /* 51*/ { UNICODE_MODE, -1, -1, -1, { 1, 2, "A" }, "A", -1, "", ZINT_ERROR_INVALID_OPTION, 0, "Error 549: Structured Append ID not available for MaxiCode", 1, 1, "" }, + /* 52*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "b..A", -1, "", 0, 30, "(144) 04 3F 02 31 38 2E 01 21 21 21 23 2F 04 2C 34 3B 28 25 2C 11 21 21 21 21 21 21 21 21", 0, 1, "BWIPP pending PR #279" }, + /* 53*/ { UNICODE_MODE, -1, -1, -1, { 0, 0, "" }, "A123456789b123456789bbbA", -1, "", 0, 30, "(144) 04 01 1F 07 16 3C 34 15 3B 02 08 28 3C 0E 06 03 34 25 3C 1E 1F 07 16 3C 34 15 3F 02", 1, 1, "BWIPP pending PR #279" }, + /* 54*/ { ESCAPE_MODE, -1, -1, -1, { 0, 0, "" }, "\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192", -1, "", 0, 30, "(144) 04 3C 00 3D 00 3D 00 3D 00 3C 32 10 27 30 09 0B 06 16 3D 0D 00 3D 00 3D 00 3D 00 3C", 1, 1, "BWIPP pending PR #279" }, + /* 54*/ { ESCAPE_MODE, -1, -1, -1, { 0, 0, "" }, "\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192\\d224\\d224\\d224\\d192", -1, "", 0, 30, "(144) 04 3C 00 3D 00 3D 00 3D 00 3C 32 10 27 30 09 0B 06 16 3D 0D 00 3D 00 3D 00 3D 00 3C", 1, 1, "BWIPP pending PR #279" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -332,44 +356,44 @@ static void test_encode(const testCtx *const p_ctx) { }, /* 1*/ { -1, 4, -1, { 0, 0, "" }, "MaxiCode (19 chars)", -1, "", 0, 33, 30, 0, "ISO/IEC 16023:2000 Figure H1 **NOT SAME** different encodation (figure uses '3 Shift A' among other differences); BWIPP different encodation again", "001101011111011100000010101111" - "101100010001001100010000001100" + "101100010001001100010000000100" "101100001010001111001001111101" "010101010101010101010101010100" "000000000000000000000000000111" "101010101010101010101010101000" "010101010101010101010101010111" - "000000000000000000000000000010" - "101010101010101010101010101000" + "000000000000000000000000000000" + "101010101010101010101010101010" "010101011111111100000001010100" "000000000011110110001000000000" "101010101110000000111010101000" "010101100010000000001101010101" "000000101000000000001000000000" - "101010000000000000011010101000" - "010101010000000000001101010100" - "000000001000000000001000000011" + "101010000000000000011010101011" + "010101010000000000001101010110" + "000000001000000000001000000001" "101010110000000000001010101010" "010101101100000000010101010111" "000000100000000000000000000000" "101010010110000000000110101011" - "010101010110000000001001010100" - "000000000110001011000000000010" + "010101010110000000001001010110" + "000000000110001011000000000001" "101010100110111001010010101000" - "010101010101010101010000101111" - "000000000000000000001100100000" - "101010101010101010100101000001" - "000011000111010110101100010000" - "111001111110111110011000111111" - "000001110010000010110001100100" - "000111000000001111011000010010" - "010110010110001110100000010100" - "010011110011000001010111100111" + "010101010101010101010001100101" + "000000000000000000001111101000" + "101010101010101010100100001101" + "100011000111000111100000110000" + "011011110010111100011100111111" + "110010110110010000110001100100" + "001111010001000111111010011010" + "010010010101001010100000011010" + "010011010001000101110111100100" }, - /* 2*/ { DATA_MODE | ESCAPE_MODE, 2, 96, { 0, 0, "" }, "1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G634 ALPHA DR\\GPITTSBURGH\\GPA\\R\\E", -1, "152382802840001", 0, 33, 30, 0, "ISO/IEC 16023:2000 Figure B2 **NOT SAME** uses different encodation (figure precedes PAD chars with Latch B); BWIPP different encodation again", + /* 2*/ { ESCAPE_MODE, 2, 96 + 1, { 0, 0, "" }, "1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G634 ALPHA DR\\GPITTSBURGH\\GPA\\R\\E", -1, "152382802840001", 0, 33, 30, 0, "ISO/IEC 16023:2000 Figure B2 **NOT SAME** uses different encodation (figure precedes PAD chars with Latch B); BWIPP different encodation again", "110101110110111110111111101111" "010101010111000011011000010010" - "110110110001001010101010010011" - "111000101010101111111111111100" + "110110110001001010100110010001" + "111000101010101111111111111110" "001111000010110010011000000011" "001001110010101010100000000000" "111011111110111111101111111110" @@ -377,34 +401,34 @@ static void test_encode(const testCtx *const p_ctx) { "010001100010101010101001110001" "110111100011010000011011111100" "001100110011110000001110101001" - "101110101000000001011111011000" - "101010000000000000010110111100" + "101110101000000001011111011010" + "101010000000000000010110111111" "111101100000000000011011100010" "101010010000000000000110011101" "001000010000000000011100011110" "010011001000000000001000001010" "000000101000000000001010000010" "000100111100000000001110101010" - "000010101100000000001000110010" - "100000111010000000011101100011" + "000010101100000000001000110000" + "100000111010000000011101100000" "101000100000000000110110100000" "001000001110100101100110100101" "011001110010101001100000001000" - "000010100010110001010101011010" - "100111000011111000001001011000" - "110010001001010010101100011101" - "001001110101110100011001110010" - "011111010011101100111101010011" - "111111101111101010101101111000" - "101001110101110111010111000011" - "010110101101000001111000100110" - "110110100000010000001011110011" + "000010100010110001010101111010" + "100111000011111000001101101010" + "110010001001010010100000001101" + "000001000110110100111010111100" + "010111010010100100001111011010" + "110111001110101010101101110100" + "011011110001010100010111010011" + "000111101001100001111000010110" + "000100101000110000000111110011" }, - /* 3*/ { ESCAPE_MODE, 2, 96, { 0, 0, "" }, "1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G634 ALPHA DR\\GPITTSBURGH\\GPA\\R\\E", -1, "15238840001", 0, 33, 30, 0, "OkapiBarcode zero-pad postcode lacking +4 (US 840 only), ISO/IEC 16023:2000 Annex B.1.4a; BWIPP different encodation", + /* 3*/ { ESCAPE_MODE, 2, 96 + 1, { 0, 0, "" }, "1Z00004951\\GUPSN\\G06X610\\G159\\G1234567\\G1/1\\G\\GY\\G634 ALPHA DR\\GPITTSBURGH\\GPA\\R\\E", -1, "15238840001", 0, 33, 30, 0, "OkapiBarcode zero-pad postcode lacking +4 (US 840 only), ISO/IEC 16023:2000 Annex B.1.4a; BWIPP different encodation", "110101110110111110111111101111" "010101010111000011011000010010" - "110110110001001010101010010011" - "111000101010101111111111111100" + "110110110001001010100110010001" + "111000101010101111111111111110" "001111000010110010011000000011" "001001110010101010100000000000" "111011111110111111101111111110" @@ -412,28 +436,28 @@ static void test_encode(const testCtx *const p_ctx) { "010001100010101010101001110001" "110111101111010000011011111100" "001100111111000000001010101001" - "101110100000000001010011011000" - "101010010010000000010110111100" + "101110100000000001010011011010" + "101010010010000000010110111111" "111101110000000000010011100010" "101010110000000000000110011101" "001000010000000000001100011110" "010011001000000000001000001010" "000000101000000000001010000010" "000100001100000000000010101010" - "000010010100000000000100110010" - "100000111100000000010001100011" + "000010010100000000000100110000" + "100000111100000000010001100000" "101000101000000000111110100000" "001000001110100101011010100101" "011001111110011001010100001000" - "000010100010110001010101011010" - "100111000011111000001001011000" - "110010001001010010101100011101" - "001001110101110100011001110010" - "011111010011101100111101010011" - "111111101111101010101101111000" - "101001110101110111010111000011" - "010110101101000001111000100110" - "110110100000010000001011110011" + "000010100010110001010101111010" + "100111000011111000001101101010" + "110010001001010010100000001101" + "000001000110110100111010111100" + "010111010010100100001111011010" + "110111001110101010101101110100" + "011011110001010100010111010011" + "000111101001100001111000010110" + "000100101000110000000111110011" }, /* 4*/ { -1, 3, -1, { 0, 0, "" }, "CEN", -1, "B1050056999", 0, 33, 30, 1, "ISO/IEC 16023:2000 B.1 Example (primary only given, data arbitrary); verified manually against tec-it", "000000010101010101010101010111" @@ -540,40 +564,40 @@ static void test_encode(const testCtx *const p_ctx) { "111010101011001101111001011010" "011110011111000011101011111011" }, - /* 7*/ { -1, 5, -1, { 0, 0, "" }, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\037\237\240\242\243\244\245\246\247\251\255\256\266\225\226\227\230\231\232\233\234\235\236", 51, "", 0, 33, 30, 1, "Mode 5 set E", + /* 7*/ { -1, 5, -1, { 0, 0, "" }, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\037\237\240\242\243\244\245\246\247\251\255\256\266\225\226\227\230\231\232\233\234\235\236", 51, "", 0, 33, 30, 0, "Mode 5 set E; BWIPP different encodation", "000000000000000000101010101011" - "100101010111111111000000001010" - "110010011100100111001001110010" - "010101010101011010101010101010" - "010110101010001101010110101001" + "100101010111111111000000001000" + "110010011100100111001001110011" + "010101010101011010101010101000" + "010110101010001101010110101010" "100011011000110101100011011000" - "010101010101111111111111111110" + "010101010101111111111111111100" "010111111111000000001010101010" - "011100100111001001110010011101" - "010101011011110000001011111110" - "000000001111110010010001010110" - "101010100110000010001001100000" - "010101110010000000001101010111" - "000000111000000000001000000010" - "101010110100000000001110101011" - "010101010000000000001001010100" - "000000001000000000001000000001" - "101010100000000000001010101000" - "010101100000000000001001010110" - "000000000000000000000000000000" - "101010100100000000011110101010" - "101100110100000001110101110110" - "011000000010110101110111000011" - "110111000010110001001000011010" - "100001101111010001110110101000" - "111110011001100100010110010010" - "100011110000001110111011000001" - "111001000110000011101000011000" - "101110110100100001100011011111" - "101100010011001000110000101100" - "110101001101000000111101001111" - "100111110000101000000001110100" - "100101010010100000010101000111" + "011100100111001001110010011110" + "101010101011110000001010111100" + "111111111111110010010011010110" + "000000000110000010001000100010" + "101010110010000000001110101011" + "111111111000000000001011111100" + "000000110100000000001100000010" + "101010010000000000001010101000" + "111111001000000000001011111101" + "000000100000000000001000000010" + "101010100000000000001010101001" + "111111000000000000000011111110" + "000000100100000000011100000000" + "001011110100000001110111111000" + "000111000010110101110111101111" + "001110100010110001001010110010" + "110011000100101011100101101100" + "101111101011010011111111100110" + "010001100101111110101001111101" + "001000011101100111100101110010" + "110100001111010010010010001111" + "100010011100101000100000101100" + "110100100100100001111100000111" + "011111011011101100100101001010" + "000011101111000101100100011101" }, /* 8*/ { -1, 6, -1, { 0, 0, "" }, "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\241\250\253\257\260\264\267\270\273\277\212\213\214\215\216\217\220\221\222\223\224", -1, "", 0, 33, 30, 1, "Mode 6 set D", "000000000000000000101010101011" @@ -890,40 +914,40 @@ static void test_encode(const testCtx *const p_ctx) { "010110101111010110101010111100" "010100000000010110101010010100" }, - /* 17*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "¢£¤¥123456789", -1, "", 0, 33, 30, 1, "Mode 4 LCKE NS", - "111110110101010101010101010111" - "111010010000000000000000000000" - "000010011010101010101010101000" - "010101010101010101010101010100" - "000000000000000000000000000001" + /* 17*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "¢£¤¥123456789", -1, "", 0, 33, 30, 0, "Mode 4 LCKE NS; BWIPP different encodation (1 codeword longer)", + "111110101010101010101010101011" + "111010111111111111111111111100" + "000010000000000000000000000011" "101010101010101010101010101010" - "010101010101010101010101010101" - "000000000000000000000000000000" - "101010101010101010101010101001" - "010101011111110100111001010110" - "000000001001110110011100000010" - "101010100110000000111010101010" - "010101001010000000000101010101" - "000000001000000000110100000000" - "101010000100000000000110101011" - "010101011000000000001101010110" - "000000001000000000001000000000" - "101010100000000000001010101000" - "010101010100000000000101010100" - "000000010000000000111100000010" - "101010101100000000110010101001" - "010101010110000001001001010100" - "000000001110110001011000000000" - "101010101010110101010010101010" - "010101010101010101010000101101" - "000000000000000000001110011100" - "101010101010101010100111100010" - "011101100110110110100011110010" - "010001101101001001100100011011" - "100011011110110000101000000010" - "101101111000011101010000100101" - "000000111100011110100001110000" - "101000000010100111001011110101" + "111111111111111111111111111101" + "000000000000000000000000000010" + "101010101010101010101010101011" + "111111111111111111111111111100" + "000000000000000000000000000011" + "101010101111110100111010101000" + "111111111001110110011111111101" + "000000000110000000111000000000" + "101010001010000000000110101011" + "111111001000000000110111111110" + "000000000100000000000100000011" + "101010011000000000001110101010" + "111111001000000000001011111101" + "000000100000000000001000000000" + "101010010100000000000110101001" + "111111010000000000111111111100" + "000000101100000000110000000001" + "101010100110000001001010101010" + "111111111110110001011011111101" + "000000001010110101010000000010" + "101010101010101010100110111001" + "111111111111111111110110001100" + "000000000000000000001100010001" + "001110001011100101010100110000" + "010000101010111000100010110100" + "111011010110010000010100011000" + "111100010011001010110101010101" + "011100101001010011011100111100" + "101101110111011101011010011101" }, /* 18*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "ABCDE12abcde1ÀÁÂ⣤¥1àáâãabcde123A123456789àáâ㢣¤¥abc", -1, "", 0, 33, 30, 1, "Mode 4 mixed sets", "000000001111111100000000111111" @@ -960,7 +984,42 @@ static void test_encode(const testCtx *const p_ctx) { "100011000001110011101110101000" "001001110010111101100100010001" }, - /* 19*/ { UNICODE_MODE, 4, -1, { 3, 7, "" }, "THIS IS A 91 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, APPENDED, MAXICODE SYMBOL...", -1, "", 0, 33, 30, 1, "Mode 4 Structured Append", + /* 19*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789MNO123456789", -1, "", 0, 33, 30, 1, "Mode 4 spaced NSs", + "001011111000100010111110001011" + "101011101000111010111010101100" + "110100001011111101000010001101" + "100010111110001000101111100010" + "111010101110101110101011101011" + "110110000001111110100000011110" + "001011111000100010111110001010" + "101011101010111010111010011110" + "110100001011111101000010001110" + "100010110111101100010011100000" + "110110100001111010011111101010" + "111010000100000000101100011100" + "001011101010000000001011100010" + "101011111100000000110110100110" + "110100001100000000010000100100" + "101111011000000000000110001000" + "101011001000000000001010101100" + "100000001000000000001001111110" + "001000101100000000000110111101" + "011110001100000000111010111010" + "111111100010000000000101000001" + "111110000010000000001010001010" + "101110101010000011011011111011" + "000001110111001001101011001010" + "100000001000101111100001000111" + "101111111110101110101001010000" + "101001111111010000100110111011" + "101100110110010001111000100000" + "111101100110001110010001110001" + "000101001110100101000001111000" + "101101001001111010110101100000" + "011101000011011001001111111000" + "111010010011100000100100111111" + }, + /* 20*/ { UNICODE_MODE, 4, -1, { 3, 7, "" }, "THIS IS A 91 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, APPENDED, MAXICODE SYMBOL...", -1, "", 0, 33, 30, 1, "Mode 4 Structured Append", "010001111101000000100000100011" "000000010000000100000000101000" "001000101000110010011011001000" @@ -995,7 +1054,7 @@ static void test_encode(const testCtx *const p_ctx) { "010101011101100110111011100100" "011001000011110011011110111010" }, - /* 20*/ { UNICODE_MODE, 3, -1, { 1, 8, "" }, "COMMISSION FOR EUROPEAN NORMALIZATION, RUE DE STASSART 36, B-1050 BRUXELLES", -1, "B1050056999", 0, 33, 30, 1, "Mode 3 Structured Append", + /* 21*/ { UNICODE_MODE, 3, -1, { 1, 8, "" }, "COMMISSION FOR EUROPEAN NORMALIZATION, RUE DE STASSART 36, B-1050 BRUXELLES", -1, "B1050056999", 0, 33, 30, 1, "Mode 3 Structured Append", "010000000000001010000000010011" "001000111111010000011111001000" "101111111010101111101101000101" @@ -1269,7 +1328,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { "010110101111010110101010111100" "010100000000010110101010010100" }, - /* 4*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("Pixel 4a 128 GB:$439.97"), -1, 3 }, { TU("Pixel 4a 128 GB:¥3149.79"), -1, 29 }, { TU("Pixel 4a 128 GB:444,90 €"), -1, 17 } }, "", 0, 33, 30, 0, "AIM ITS/04-023:2022 Annex A example (shortened)", + /* 4*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("Pixel 4a 128 GB:$439.97"), -1, 3 }, { TU("Pixel 4a 128 GB:¥3149.79"), -1, 29 }, { TU("Pixel 4a 128 GB:444,90 €"), -1, 17 } }, "", 0, 33, 30, 0, "AIM ITS/04-023:2022 Annex A example (shortened); BWIPP different encodation, same codeword count", "011100110111111101000011011111" "001000110000000100100001101000" "000010110010010000110101000010" @@ -1409,7 +1468,7 @@ static void test_encode_segs(const testCtx *const p_ctx) { "101010010100011001011101100110" "111011110000111001101101111000" }, - /* 8*/ { UNICODE_MODE, -1, -1, { 1, 2, "" }, { { TU("αβ"), -1, 9 }, { TU("ÿ"), -1, 3 }, { TU("貫やぐ禁"), -1, 20 } }, "", 0, 33, 30, 1, "Structured Append", + /* 8*/ { UNICODE_MODE, -1, -1, { 1, 2, "" }, { { TU("αβ"), -1, 9 }, { TU("ÿ"), -1, 3 }, { TU("貫やぐ禁"), -1, 20 } }, "", 0, 33, 30, 0, "Structured Append; BWIPP different encodation", "001101101011011110111111001111" "001110011011111100110011001110" "111000110010110010000110010011" @@ -1444,6 +1503,76 @@ static void test_encode_segs(const testCtx *const p_ctx) { "101010011010110110110010010100" "100101010111100011100010101000" }, + /* 9*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("ab"), -1, 3 }, { TU("ABCD"), -1, 4 }, { TU(""), 0, 0 } }, "", 0, 33, 30, 1, "Code Set B then A", + "000000010101010101010101010111" + "000010000000000000000000000010" + "011100101010101010101010101001" + "010101010101010101010101010110" + "000000000000000000000000000010" + "101010101010101010101010101010" + "010101010101010101010101010100" + "000000000000000000000000000000" + "101010101010101010101010101011" + "010101010111001000000001010100" + "000000000111000110010000000000" + "101010100010000000001010101010" + "010101010010000000110001010110" + "000000110000000000110100000010" + "101010001000000000011110101011" + "010101110000000000001101010110" + "000000101000000000001000000001" + "101010110000000000001010101000" + "010101001100000000000101010101" + "000000101100000000000000000010" + "101010011010000000110110101001" + "010101010000000001111101010100" + "000000001010100111000100000010" + "101010101010010001001110101010" + "010101010101010101011110000100" + "000000000000000000001100111010" + "101010101010101010101100000000" + "110000011010110101000110100010" + "100100110111110111001111101011" + "011111111011111001110100101100" + "101000010001001011101111001010" + "011011011101010101001101001000" + "001010010110100000100111101000" + }, + /* 10*/ { UNICODE_MODE, -1, -1, { 0, 0, "" }, { { TU("\004\004\004\004"), -1, 3 }, { TU("ABCD"), -1, 4 }, { TU("abcd"), -1, 5 } }, "", 0, 33, 30, 1, "Code Set E then A then B", + "001100000000100011000000000111" + "100100000010011011000000100000" + "000110011100111011100111001010" + "010101010101010101010101010100" + "000000000000000000000000000011" + "101010101010101010101010101010" + "010101010101010101010101010111" + "000000000000000000000000000010" + "101010101010101010101010101000" + "010101010111000000000001010110" + "000000001001001010011100000011" + "101010100100000000000110101010" + "010101101010000000110101010100" + "000000100100000000111000000010" + "101010111100000000000010101001" + "010101010000000000000001010110" + "000000001000000000001000000001" + "101010100000000000001010101010" + "010101110100000000010101010110" + "000000111000000000110100000000" + "101010000110000000101010101011" + "010101010000000001010101010110" + "000000000110100011101100000011" + "101010100011011101111110101010" + "010101010101010101010101101000" + "000000000000000000001001000010" + "101010101010101010101010110111" + "100010010101100011100111000100" + "110110101110100010100011010011" + "100001111011001010101000111000" + "101100010110101111011111100011" + "111010100101000101001011011000" + "011111000111001010010000111100" + }, }; const int data_size = ARRAY_SIZE(data); int i, j, seg_count, ret; @@ -1560,45 +1689,49 @@ static void test_best_supported_set(const testCtx *const p_ctx) { static const struct item data[] = { /* 0*/ { "am.//ab,\034TA# z\015!", 0, 100, 100, 0, 33, 30, "Different encodation than BWIPP, same number of codewords", "111010000101111000111101010111" - "111110000000010100111000000000" + "111110000000010100011000000000" "110000101100110100111010101011" "010101010101010101010101010100" "000000000000000000000000000000" - "101010101010101010101010101000" + "101010101010101010101010101010" "010101010101010101010101010110" - "000000000000000000000000000000" + "000000000000000000000000000010" "101010101010101010101010101011" "010101010111001100000101010110" "000000001011000010000000000010" "101010101100000000100110101010" "010101001100000000101101010101" "000000100000000000010000000010" - "101010110000000000010010101010" + "101010110000000000010010101011" "010101011000000000000101010110" - "000000001000000000001000000010" + "000000001000000000001000000011" "101010001000000000001010101000" "010101010000000000001101010101" "000000001100000000000000000010" "101010110010000000010110101010" - "010101010100000001111001010100" - "000000001110110111111100000011" - "101010100110111101011010101010" - "010101010101010101010011101000" - "000000000000000000001101100000" - "101010101010101010100000100110" - "101001001101110001001011010000" - "100100110110001010011000011100" - "011011000001011011100100100110" - "111001100000101101000111001000" - "111100000110000011011101001110" - "010100101001110111101010110010" + "010101010100000001111001010110" + "000000001110110111111100000000" + "101010100110111101011010101000" + "010101010101010101010001100011" + "000000000000000000001110101000" + "101010101010101010100010100010" + "011000001001000010001111100000" + "110111111010111010011000001100" + "001011000101101010100000110110" + "110001100010100101010101001101" + "111000100110000011001110001100" + "011100101001111011111001111100" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; struct zint_symbol *symbol = NULL; - char escaped_data[1024]; + char escaped[1024]; + char cmp_buf[32768]; + char cmp_msg[1024]; + + int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); /* Only do ZXing-C++ test if asked, too slow otherwise */ testStartSymbol("test_best_supported_set", &symbol); @@ -1616,7 +1749,7 @@ static void test_best_supported_set(const testCtx *const p_ctx) { if (p_ctx->generate) { printf(" /*%2d*/ { \"%s\", %d, %.0f, %.0f, %d, %d, %d, \"%s\",\n", - i, testUtilEscape(data[i].data, length, escaped_data, sizeof(escaped_data)), ret, + i, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), ret, data[i].w, data[i].h, data[i].ret_vector, symbol->rows, symbol->width, data[i].comment); testUtilModulesPrint(symbol, " ", "\n"); printf(" },\n"); @@ -1631,6 +1764,20 @@ static void test_best_supported_set(const testCtx *const p_ctx) { ret = ZBarcode_Buffer_Vector(symbol, 0); assert_equal(ret, data[i].ret_vector, "i:%d ZBarcode_Buffer_Vector ret %d != %d\n", i, ret, data[i].ret_vector); + + if (ret < ZINT_ERROR) { + if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { + int cmp_len, ret_len; + char modules_dump[33 * 33 + 1]; + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, cmp_buf, sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + + ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, symbol->primary, escaped, &ret_len); + assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, escaped); + } + } } ZBarcode_Delete(symbol); diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index b467bd0b..0da79e58 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -2472,7 +2472,7 @@ static char *testUtilBwippEscape(char *bwipp_data, int bwipp_data_size, const ch /* Have to escape double quote otherwise Ghostscript gives "Unterminated quote in @-file" for some reason */ /* Escape single quote also to avoid having to do proper shell escaping TODO: proper shell escaping */ if (*d < 0x20 || *d >= 0x7F || (*d == '^' && !init_parsefnc) || *d == '"' || *d == '\'' - || (*d == '\\' && !zint_escape_mode)) { + || *d == '(' || *d == ')' || (*d == '\\' && !zint_escape_mode)) { if (b + 4 >= be) { fprintf(stderr, "testUtilBwippEscape: double quote bwipp_data buffer full (%d)\n", bwipp_data_size); return NULL; @@ -2496,16 +2496,16 @@ static char *testUtilBwippEscape(char *bwipp_data, int bwipp_data_size, const ch case 'G': val = 0x1d; /* Group Separator */ break; case 'R': val = 0x1e; /* Record Separator */ break; case 'x': - val = d + 1 + 2 < de && z_isxdigit(d[1]) && z_isxdigit(d[2]) ? (ctoi(d[1]) << 4) | ctoi(d[2]) : -1; + val = d + 2 < de && z_isxdigit(d[1]) && z_isxdigit(d[2]) ? (ctoi(d[1]) << 4) | ctoi(d[2]) : -1; if (val != -1) d+= 2; break; case 'd': - val = d + 1 + 3 < de ? to_int(d + 1, 3) : -1; + val = d + 3 < de ? to_int(d + 1, 3) : -1; if (val > 255) val = -1; if (val != -1) d += 3; break; case 'o': - val = d + 1 + 3 < de && z_isodigit(d[1]) && z_isodigit(d[2]) && z_isodigit(d[3]) + val = d + 3 < de && z_isodigit(d[1]) && z_isodigit(d[2]) && z_isodigit(d[3]) ? (ctoi(d[1]) << 6) | (ctoi(d[2]) << 3) | ctoi(d[3]) : -1; if (val > 255) val = -1; if (val != -1) d += 3; @@ -3111,10 +3111,10 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int } } if (option_2 > 0) { - char scm_vv_buf[32]; - sprintf(scm_vv_buf, "[)>^03001^029%02d", option_2); /* [)>\R01\Gvv */ - memmove(bwipp_data + 15, bwipp_data, strlen(bwipp_data) + 1); - memcpy(bwipp_data, scm_vv_buf, 15); + char scm_vv_buf[40]; + sprintf(scm_vv_buf, "[^041>^03001^029%02d", option_2 - 1); /* [)>\R01\Gvv */ + memmove(bwipp_data + 18, bwipp_data, strlen(bwipp_data) + 1); + memcpy(bwipp_data, scm_vv_buf, 18); if (!parse) { sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%sparse", strlen(bwipp_opts_buf) ? " " : ""); @@ -3128,6 +3128,8 @@ int testUtilBwipp(int index, const struct zint_symbol *symbol, int option_1, int itoc(symbol->structapp.count)); bwipp_opts = bwipp_opts_buf; } + sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%snewencoder", strlen(bwipp_opts_buf) ? " " : ""); + bwipp_opts = bwipp_opts_buf; } else if (symbology == BARCODE_BC412) { to_upper((unsigned char *) bwipp_data, (int) strlen(bwipp_data)); sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%ssemi", strlen(bwipp_opts_buf) ? " " : ""); diff --git a/backend/tests/tools/run_zxingcpp_tests.sh b/backend/tests/tools/run_zxingcpp_tests.sh index 73bb1e5f..ca9fe8fb 100755 --- a/backend/tests/tools/run_zxingcpp_tests.sh +++ b/backend/tests/tools/run_zxingcpp_tests.sh @@ -37,9 +37,11 @@ run_zxingcpp_test "test_dotcode" "encode" run_zxingcpp_test "test_dotcode" "encode_segs" run_zxingcpp_test "test_hanxin" run_zxingcpp_test "test_mailmark" "2d_encode" +run_zxingcpp_test "test_maxicode" "large" run_zxingcpp_test "test_maxicode" "input" run_zxingcpp_test "test_maxicode" "encode" run_zxingcpp_test "test_maxicode" "encode_segs" +run_zxingcpp_test "test_maxicode" "best_supported_set" run_zxingcpp_test "test_medical" "encode" run_zxingcpp_test "test_pdf417" "reader_init" run_zxingcpp_test "test_pdf417" "input" diff --git a/frontend_qt/main.cpp b/frontend_qt/main.cpp index 45df9003..98ae6582 100644 --- a/frontend_qt/main.cpp +++ b/frontend_qt/main.cpp @@ -21,9 +21,9 @@ int main(int argc, char *argv[]) { Q_INIT_RESOURCE(resources); -#if defined(__linux__) && QT_VERSION > 0x50F02 +#if defined(__linux__) && QT_VERSION >= 0x50100 /* `qEnvironmentVariableIsEmpty()` introduced Qt 5.1 */ /* Not compatible with Wayland for some reason(s) so use X11 unless overridden */ - if (qEnvironmentVariableIsEmpty("QT_QPA_PLATFORM")) { + if (QGuiApplication::platformName() != "xcb" && qEnvironmentVariableIsEmpty("QT_QPA_PLATFORM")) { qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("xcb")); } #endif