MAXICODE: maintain current set between segments to prevent invalid

encodation;
  use code set E for padding as well, saves codeword, props Bue
  Jensen (BWIPP PR #279);
  add padding after all segments and limit loops to length to make
  NS compression work better;
  all the above temporary fixes until Bue Jensen's merge request
  with the BWIPP PR #279 algorithm
GUI: expand linux "xcb" platform hack for >= Qt 5.1
This commit is contained in:
gitlost 2024-11-08 16:54:38 +00:00
parent f1f283d6a1
commit 88155343bf
6 changed files with 403 additions and 231 deletions

View File

@ -27,7 +27,7 @@ Changes
add minimal encodation algorithm (non-extended ASCII only), props Alex Geller add minimal encodation algorithm (non-extended ASCII only), props Alex Geller
(ZXing); (ZXing);
reduce extended latch cut-off from 5 to 4 for better encodation in certain 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: return warning on invalid `input_mode` reset
- library/CLI: expanded error messages - library/CLI: expanded error messages
- GS1: new AIs 7250-7259 (GSCN 22-246); - GS1: new AIs 7250-7259 (GSCN 22-246);
@ -37,7 +37,9 @@ Changes
ticket #317, props Andre Maute; ticket #317, props Andre Maute;
return warning if ECC < 5% (due to bit-stuffing when version given) 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 - 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 - GUI: use X11 (xcb) as platform instead of Wayland on Linux to avoid various
weird behaviours; weird behaviours;
in "grpDATF.ui" use "PlainText" rather than "RichText" for tracker ratio in "grpDATF.ui" use "PlainText" rather than "RichText" for tracker ratio
@ -65,6 +67,7 @@ Bugs
Philip Ye Philip Ye
- CODE128: fix extended char latching when exactly 3 extended chars at end - CODE128: fix extended char latching when exactly 3 extended chars at end
- library: need to check for valid UTF-8 after de-escaping - library: need to check for valid UTF-8 after de-escaping
- MAXICODE: maintain current set between segments
Version 2.13.0 (2023-12-18) Version 2.13.0 (2023-12-18)

View File

@ -31,6 +31,7 @@
/* SPDX-License-Identifier: BSD-3-Clause */ /* SPDX-License-Identifier: BSD-3-Clause */
/* Includes corrections thanks to Monica Swanson @ Source Technologies */ /* Includes corrections thanks to Monica Swanson @ Source Technologies */
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include "common.h" #include "common.h"
#include "maxicode.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 */ /* Format text according to Appendix A */
static int maxi_text_process(unsigned char set[144], unsigned char character[144], const int mode, static int maxi_text_process(unsigned char set[144], unsigned char character[144], const unsigned char in_source[],
const unsigned char in_source[], int length, const int eci, const int scm_vv, int *p_sp, int length, const int eci, const int scm_vv, int *p_sp, int current_set, const int debug_print) {
const int debug_print) {
int sp = *p_sp; 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 set15[2] = { 1, 5 };
static const unsigned char set12[2] = { 1, 2 }; 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 */ unsigned char *source_buf = (unsigned char *) z_alloca(length + 9); /* For prefixing 9-character SCM sequence */
if (sp + length > 144) { if (sp + length > 144) {
return ZINT_ERROR_TOO_LONG; return 0;
} }
/* Insert ECI at the beginning of message if needed */ /* Insert ECI at the beginning of message if needed */
/* Encode ECI assignment numbers according to table 3 */ /* Encode ECI assignment numbers according to table 3 */
if (eci != 0) { if (eci != 0) {
if (sp + 1 + length > 144) return ZINT_ERROR_TOO_LONG; if (sp + 1 + length > 144) return 0;
character[sp++] = 27; /* ECI */ character[sp++] = 27; /* ECI */
if (eci <= 31) { if (eci <= 31) {
if (sp + 1 + length > 144) return ZINT_ERROR_TOO_LONG; if (sp + 1 + length > 144) return 0;
character[sp++] = eci; character[sp++] = eci;
} else if (eci <= 1023) { } 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++] = 0x20 | ((eci >> 6) & 0x0F);
character[sp++] = eci & 0x3F; character[sp++] = eci & 0x3F;
} else if (eci <= 32767) { } 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++] = 0x30 | ((eci >> 12) & 0x07);
character[sp++] = (eci >> 6) & 0x3F; character[sp++] = (eci >> 6) & 0x3F;
character[sp++] = eci & 0x3F; character[sp++] = eci & 0x3F;
} else { } 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++] = 0x38 | ((eci >> 18) & 0x03);
character[sp++] = (eci >> 12) & 0x3F; character[sp++] = (eci >> 12) & 0x3F;
character[sp++] = (eci >> 6) & 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 (scm_vv != -1) { /* Add SCM prefix */
if (sp + length > 135) { if (sp + length > 135) {
return ZINT_ERROR_TOO_LONG; return 0;
} }
sprintf((char *) source_buf, "[)>\03601\035%02d", scm_vv); /* [)>\R01\Gvv */ sprintf((char *) source_buf, "[)>\03601\035%02d", scm_vv); /* [)>\R01\Gvv */
memcpy(source_buf + 9, in_source, length); 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 */ /* Find candidates for number compression */
/* Note the prohibition on number compression in the primary message in ISO/IEC 16023:2000 B.1 (1) /* Note the prohibition on number compression in the primary message in ISO/IEC 16023:2000 B.1 (1)
applies to modes 2 & 3 only */ applies to modes 2 & 3 only */
count = 0; 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))) { if ((set[sp + i] == 1) && ((character[sp + i] >= 48) && (character[sp + i] <= 57))) {
/* Character is a number */ /* Character is a number */
count++; 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 */ /* Nine digits in a row can be compressed */
memset(set + sp + 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; count = 0;
#ifndef NDEBUG
ns_count1++;
#endif
} }
} else { } else {
count = 0; count = 0;
@ -311,9 +310,7 @@ static int maxi_text_process(unsigned char set[144], unsigned char character[144
} }
/* Add shift and latch characters */ /* Add shift and latch characters */
current_set = 1; for (i = 0; sp + i < 144 && set[sp + i] != 255; i++) {
i = 0;
do {
if ((set[sp + i] != current_set) && (set[sp + i] != 6)) { if ((set[sp + i] != current_set) && (set[sp + i] != 6)) {
switch (set[sp + i]) { 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++; /* Allow for bump */
} }
i++; }
} while (sp + i < 144);
if (debug_print) fputc('\n', stdout);
/* Number compression has not been forgotten! - It's handled below */ /* Number compression has not been forgotten! - It's handled below */
i = 0; for (i = 0; sp + i < 144 && sp + i <= length - 9; i++) {
do {
if (set[sp + i] == 6) { if (set[sp + i] == 6) {
/* Number compression */ /* Number compression */
int value = to_int(character + sp + i, 9); 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 + 4] = (value & 0xfc0) >> 6;
character[sp + i + 5] = (value & 0x3f); character[sp + i + 5] = (value & 0x3f);
i += 6; memmove(set + sp + i + 6, set + sp + i + 9, 144 - (sp + i + 9));
memmove(set + sp + i, set + sp + i + 3, 141 - (sp + i)); memmove(character + sp + i + 6, character + sp + i + 9, 144 - (sp + i + 9));
memmove(character + sp + i, character + sp + i + 3, 141 - (sp + i)); i += 5;
length -= 3; length -= 3;
} else { #ifndef NDEBUG
i++; 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; *p_sp = sp + length;
return 0; return current_set;
} }
/* Call `maxi_text_process()` for each segment, dealing with Structured Append beforehand and populating /* 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) { const int seg_count, const int structapp_cw, int scm_vv, const int debug_print) {
unsigned char set[144], character[144] = {0}; unsigned char set[144], character[144] = {0};
int i; int i;
int error_number;
int sp = 0; 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); 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++) { 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, current_set = maxi_text_process(set, character, segs[i].source, segs[i].length, segs[i].eci, scm_vv, &sp,
&sp, debug_print); current_set, debug_print);
if (error_number != 0) { if (current_set == 0) {
return error_number; return ZINT_ERROR_TOO_LONG;
} }
scm_vv = -1; 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 */ /* Copy the encoded text into the codeword array */
if ((mode == 2) || (mode == 3)) { if ((mode == 2) || (mode == 3)) {
for (i = 0; i < 84; i++) { /* secondary only */ for (i = 0; i < 84; i++) { /* secondary only */

View File

@ -48,46 +48,52 @@ static void test_large(const testCtx *const p_ctx) {
static const struct item data[] = { static const struct item data[] = {
/* 0*/ { -1, -1, "1", 138, "", 0, 33, 30 }, /* Mode 4 (138 agrees with ISO/IEC 16023:2000) */ /* 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 }, /* 1*/ { -1, -1, "1", 139, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 2*/ { -1, -1, "1", 145, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* Absolute max */ /* 2*/ { -1, -1, "1", 144, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 3*/ { -1, -1, "A", 93, "", 0, 33, 30 }, /* 3*/ { -1, -1, "1", 145, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* Absolute max */
/* 4*/ { -1, -1, "A", 94, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 4*/ { -1, -1, "A", 93, "", 0, 33, 30 },
/* 5*/ { -1, -1, "\001", 90, "", 0, 33, 30 }, /* 5*/ { -1, -1, "A", 94, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 6*/ { -1, -1, "\001", 91, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 6*/ { -1, -1, "\001", 91, "", 0, 33, 30 },
/* 7*/ { -1, -1, "\200", 90, "", 0, 33, 30 }, /* 7*/ { -1, -1, "\001", 92, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 8*/ { -1, -1, "\200", 91, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 8*/ { -1, -1, "\200", 91, "", 0, 33, 30 },
/* 9*/ { 2, -1, "1", 126, "123456789123123", 0, 33, 30 }, /* 9*/ { -1, -1, "\200", 92, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 10*/ { 2, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 10*/ { 2, -1, "1", 126, "123456789123123", 0, 33, 30 },
/* 11*/ { 2, -1, "A", 84, "123456789123123", 0, 33, 30 }, /* 11*/ { 2, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 12*/ { 2, -1, "A", 85, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 12*/ { 2, -1, "A", 84, "123456789123123", 0, 33, 30 },
/* 13*/ { 2, 96, "1", 109, "123456789123123", 0, 33, 30 }, /* 13*/ { 2, -1, "A", 85, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 14*/ { 2, 96, "1", 110, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 14*/ { 2, 96 + 1, "1", 109, "123456789123123", 0, 33, 30 },
/* 15*/ { 2, 96, "1", 136, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* Absolute max with SCM vv */ /* 15*/ { 2, 96 + 1, "1", 110, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 16*/ { 3, -1, "1", 126, "ABCDEF123123", 0, 33, 30 }, /* 16*/ { 2, 96 + 1, "1", 136, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* Absolute max with SCM vv */
/* 17*/ { 3, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 17*/ { 3, -1, "1", 126, "ABCDEF123123", 0, 33, 30 },
/* 18*/ { 3, -1, "A", 84, "ABCDEF123123", 0, 33, 30 }, /* 18*/ { 3, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 19*/ { 3, -1, "A", 85, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 19*/ { 3, -1, "A", 84, "ABCDEF123123", 0, 33, 30 },
/* 20*/ { 3, 96, "1", 109, "ABCDEF123123", 0, 33, 30 }, /* 20*/ { 3, -1, "A", 85, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 21*/ { 3, 96, "1", 110, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 21*/ { 3, 96 + 1, "1", 109, "ABCDEF123123", 0, 33, 30 },
/* 22*/ { 0, -1, "1", 126, "123456789123123", 0, 33, 30 }, /* Mode 2 */ /* 22*/ { 3, 96 + 1, "1", 110, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 23*/ { 0, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 23*/ { 0, -1, "1", 126, "123456789123123", 0, 33, 30 }, /* Mode 2 */
/* 24*/ { 0, -1, "1", 126, "ABCDEF123123", 0, 33, 30 }, /* Mode 3 */ /* 24*/ { 0, -1, "1", 127, "123456789123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 25*/ { 0, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 25*/ { 0, -1, "1", 126, "ABCDEF123123", 0, 33, 30 }, /* Mode 3 */
/* 26*/ { 5, -1, "1", 113, "", 0, 33, 30 }, /* Extra EEC */ /* 26*/ { 0, -1, "1", 127, "ABCDEF123123", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 27*/ { 5, -1, "1", 114, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 27*/ { 5, -1, "1", 113, "", 0, 33, 30 }, /* Extra EEC */
/* 28*/ { 5, -1, "A", 77, "", 0, 33, 30 }, /* 28*/ { 5, -1, "1", 114, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 29*/ { 5, -1, "A", 78, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 29*/ { 5, -1, "A", 77, "", 0, 33, 30 },
/* 30*/ { 6, -1, "1", 138, "", 0, 33, 30 }, /* 30*/ { 5, -1, "A", 78, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 31*/ { 6, -1, "1", 139, "", ZINT_ERROR_TOO_LONG, -1, -1 }, /* 31*/ { 6, -1, "1", 138, "", 0, 33, 30 },
/* 32*/ { 6, -1, "A", 93, "", 0, 33, 30 }, /* 32*/ { 6, -1, "1", 139, "", ZINT_ERROR_TOO_LONG, -1, -1 },
/* 33*/ { 6, -1, "A", 94, "", 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); const int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
struct zint_symbol *symbol = NULL; struct zint_symbol *symbol = NULL;
char data_buf[256]; 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)"; 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); testStartSymbol("test_large", &symbol);
for (i = 0; i < data_size; i++) { 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); 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); 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, "" }, /* 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, "" }, /* 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, "" }, /* 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); const int data_size = ARRAY_SIZE(data);
int i, length, ret; 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", /* 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" "001101011111011100000010101111"
"101100010001001100010000001100" "101100010001001100010000000100"
"101100001010001111001001111101" "101100001010001111001001111101"
"010101010101010101010101010100" "010101010101010101010101010100"
"000000000000000000000000000111" "000000000000000000000000000111"
"101010101010101010101010101000" "101010101010101010101010101000"
"010101010101010101010101010111" "010101010101010101010101010111"
"000000000000000000000000000010" "000000000000000000000000000000"
"101010101010101010101010101000" "101010101010101010101010101010"
"010101011111111100000001010100" "010101011111111100000001010100"
"000000000011110110001000000000" "000000000011110110001000000000"
"101010101110000000111010101000" "101010101110000000111010101000"
"010101100010000000001101010101" "010101100010000000001101010101"
"000000101000000000001000000000" "000000101000000000001000000000"
"101010000000000000011010101000" "101010000000000000011010101011"
"010101010000000000001101010100" "010101010000000000001101010110"
"000000001000000000001000000011" "000000001000000000001000000001"
"101010110000000000001010101010" "101010110000000000001010101010"
"010101101100000000010101010111" "010101101100000000010101010111"
"000000100000000000000000000000" "000000100000000000000000000000"
"101010010110000000000110101011" "101010010110000000000110101011"
"010101010110000000001001010100" "010101010110000000001001010110"
"000000000110001011000000000010" "000000000110001011000000000001"
"101010100110111001010010101000" "101010100110111001010010101000"
"010101010101010101010000101111" "010101010101010101010001100101"
"000000000000000000001100100000" "000000000000000000001111101000"
"101010101010101010100101000001" "101010101010101010100100001101"
"000011000111010110101100010000" "100011000111000111100000110000"
"111001111110111110011000111111" "011011110010111100011100111111"
"000001110010000010110001100100" "110010110110010000110001100100"
"000111000000001111011000010010" "001111010001000111111010011010"
"010110010110001110100000010100" "010010010101001010100000011010"
"010011110011000001010111100111" "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" "110101110110111110111111101111"
"010101010111000011011000010010" "010101010111000011011000010010"
"110110110001001010101010010011" "110110110001001010100110010001"
"111000101010101111111111111100" "111000101010101111111111111110"
"001111000010110010011000000011" "001111000010110010011000000011"
"001001110010101010100000000000" "001001110010101010100000000000"
"111011111110111111101111111110" "111011111110111111101111111110"
@ -377,34 +401,34 @@ static void test_encode(const testCtx *const p_ctx) {
"010001100010101010101001110001" "010001100010101010101001110001"
"110111100011010000011011111100" "110111100011010000011011111100"
"001100110011110000001110101001" "001100110011110000001110101001"
"101110101000000001011111011000" "101110101000000001011111011010"
"101010000000000000010110111100" "101010000000000000010110111111"
"111101100000000000011011100010" "111101100000000000011011100010"
"101010010000000000000110011101" "101010010000000000000110011101"
"001000010000000000011100011110" "001000010000000000011100011110"
"010011001000000000001000001010" "010011001000000000001000001010"
"000000101000000000001010000010" "000000101000000000001010000010"
"000100111100000000001110101010" "000100111100000000001110101010"
"000010101100000000001000110010" "000010101100000000001000110000"
"100000111010000000011101100011" "100000111010000000011101100000"
"101000100000000000110110100000" "101000100000000000110110100000"
"001000001110100101100110100101" "001000001110100101100110100101"
"011001110010101001100000001000" "011001110010101001100000001000"
"000010100010110001010101011010" "000010100010110001010101111010"
"100111000011111000001001011000" "100111000011111000001101101010"
"110010001001010010101100011101" "110010001001010010100000001101"
"001001110101110100011001110010" "000001000110110100111010111100"
"011111010011101100111101010011" "010111010010100100001111011010"
"111111101111101010101101111000" "110111001110101010101101110100"
"101001110101110111010111000011" "011011110001010100010111010011"
"010110101101000001111000100110" "000111101001100001111000010110"
"110110100000010000001011110011" "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" "110101110110111110111111101111"
"010101010111000011011000010010" "010101010111000011011000010010"
"110110110001001010101010010011" "110110110001001010100110010001"
"111000101010101111111111111100" "111000101010101111111111111110"
"001111000010110010011000000011" "001111000010110010011000000011"
"001001110010101010100000000000" "001001110010101010100000000000"
"111011111110111111101111111110" "111011111110111111101111111110"
@ -412,28 +436,28 @@ static void test_encode(const testCtx *const p_ctx) {
"010001100010101010101001110001" "010001100010101010101001110001"
"110111101111010000011011111100" "110111101111010000011011111100"
"001100111111000000001010101001" "001100111111000000001010101001"
"101110100000000001010011011000" "101110100000000001010011011010"
"101010010010000000010110111100" "101010010010000000010110111111"
"111101110000000000010011100010" "111101110000000000010011100010"
"101010110000000000000110011101" "101010110000000000000110011101"
"001000010000000000001100011110" "001000010000000000001100011110"
"010011001000000000001000001010" "010011001000000000001000001010"
"000000101000000000001010000010" "000000101000000000001010000010"
"000100001100000000000010101010" "000100001100000000000010101010"
"000010010100000000000100110010" "000010010100000000000100110000"
"100000111100000000010001100011" "100000111100000000010001100000"
"101000101000000000111110100000" "101000101000000000111110100000"
"001000001110100101011010100101" "001000001110100101011010100101"
"011001111110011001010100001000" "011001111110011001010100001000"
"000010100010110001010101011010" "000010100010110001010101111010"
"100111000011111000001001011000" "100111000011111000001101101010"
"110010001001010010101100011101" "110010001001010010100000001101"
"001001110101110100011001110010" "000001000110110100111010111100"
"011111010011101100111101010011" "010111010010100100001111011010"
"111111101111101010101101111000" "110111001110101010101101110100"
"101001110101110111010111000011" "011011110001010100010111010011"
"010110101101000001111000100110" "000111101001100001111000010110"
"110110100000010000001011110011" "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", /* 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" "000000010101010101010101010111"
@ -540,40 +564,40 @@ static void test_encode(const testCtx *const p_ctx) {
"111010101011001101111001011010" "111010101011001101111001011010"
"011110011111000011101011111011" "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" "000000000000000000101010101011"
"100101010111111111000000001010" "100101010111111111000000001000"
"110010011100100111001001110010" "110010011100100111001001110011"
"010101010101011010101010101010" "010101010101011010101010101000"
"010110101010001101010110101001" "010110101010001101010110101010"
"100011011000110101100011011000" "100011011000110101100011011000"
"010101010101111111111111111110" "010101010101111111111111111100"
"010111111111000000001010101010" "010111111111000000001010101010"
"011100100111001001110010011101" "011100100111001001110010011110"
"010101011011110000001011111110" "101010101011110000001010111100"
"000000001111110010010001010110" "111111111111110010010011010110"
"101010100110000010001001100000" "000000000110000010001000100010"
"010101110010000000001101010111" "101010110010000000001110101011"
"000000111000000000001000000010" "111111111000000000001011111100"
"101010110100000000001110101011" "000000110100000000001100000010"
"010101010000000000001001010100" "101010010000000000001010101000"
"000000001000000000001000000001" "111111001000000000001011111101"
"101010100000000000001010101000" "000000100000000000001000000010"
"010101100000000000001001010110" "101010100000000000001010101001"
"000000000000000000000000000000" "111111000000000000000011111110"
"101010100100000000011110101010" "000000100100000000011100000000"
"101100110100000001110101110110" "001011110100000001110111111000"
"011000000010110101110111000011" "000111000010110101110111101111"
"110111000010110001001000011010" "001110100010110001001010110010"
"100001101111010001110110101000" "110011000100101011100101101100"
"111110011001100100010110010010" "101111101011010011111111100110"
"100011110000001110111011000001" "010001100101111110101001111101"
"111001000110000011101000011000" "001000011101100111100101110010"
"101110110100100001100011011111" "110100001111010010010010001111"
"101100010011001000110000101100" "100010011100101000100000101100"
"110101001101000000111101001111" "110100100100100001111100000111"
"100111110000101000000001110100" "011111011011101100100101001010"
"100101010010100000010101000111" "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", /* 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" "000000000000000000101010101011"
@ -890,40 +914,40 @@ static void test_encode(const testCtx *const p_ctx) {
"010110101111010110101010111100" "010110101111010110101010111100"
"010100000000010110101010010100" "010100000000010110101010010100"
}, },
/* 17*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "¢£¤¥123456789", -1, "", 0, 33, 30, 1, "Mode 4 LCKE NS", /* 17*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "¢£¤¥123456789", -1, "", 0, 33, 30, 0, "Mode 4 LCKE NS; BWIPP different encodation (1 codeword longer)",
"111110110101010101010101010111" "111110101010101010101010101011"
"111010010000000000000000000000" "111010111111111111111111111100"
"000010011010101010101010101000" "000010000000000000000000000011"
"010101010101010101010101010100"
"000000000000000000000000000001"
"101010101010101010101010101010" "101010101010101010101010101010"
"010101010101010101010101010101" "111111111111111111111111111101"
"000000000000000000000000000000" "000000000000000000000000000010"
"101010101010101010101010101001" "101010101010101010101010101011"
"010101011111110100111001010110" "111111111111111111111111111100"
"000000001001110110011100000010" "000000000000000000000000000011"
"101010100110000000111010101010" "101010101111110100111010101000"
"010101001010000000000101010101" "111111111001110110011111111101"
"000000001000000000110100000000" "000000000110000000111000000000"
"101010000100000000000110101011" "101010001010000000000110101011"
"010101011000000000001101010110" "111111001000000000110111111110"
"000000001000000000001000000000" "000000000100000000000100000011"
"101010100000000000001010101000" "101010011000000000001110101010"
"010101010100000000000101010100" "111111001000000000001011111101"
"000000010000000000111100000010" "000000100000000000001000000000"
"101010101100000000110010101001" "101010010100000000000110101001"
"010101010110000001001001010100" "111111010000000000111111111100"
"000000001110110001011000000000" "000000101100000000110000000001"
"101010101010110101010010101010" "101010100110000001001010101010"
"010101010101010101010000101101" "111111111110110001011011111101"
"000000000000000000001110011100" "000000001010110101010000000010"
"101010101010101010100111100010" "101010101010101010100110111001"
"011101100110110110100011110010" "111111111111111111110110001100"
"010001101101001001100100011011" "000000000000000000001100010001"
"100011011110110000101000000010" "001110001011100101010100110000"
"101101111000011101010000100101" "010000101010111000100010110100"
"000000111100011110100001110000" "111011010110010000010100011000"
"101000000010100111001011110101" "111100010011001010110101010101"
"011100101001010011011100111100"
"101101110111011101011010011101"
}, },
/* 18*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "ABCDE12abcde1ÀÁÂ⣤¥1àáâãabcde123A123456789àáâ㢣¤¥abc", -1, "", 0, 33, 30, 1, "Mode 4 mixed sets", /* 18*/ { UNICODE_MODE, 4, -1, { 0, 0, "" }, "ABCDE12abcde1ÀÁÂ⣤¥1àáâãabcde123A123456789àáâ㢣¤¥abc", -1, "", 0, 33, 30, 1, "Mode 4 mixed sets",
"000000001111111100000000111111" "000000001111111100000000111111"
@ -960,7 +984,42 @@ static void test_encode(const testCtx *const p_ctx) {
"100011000001110011101110101000" "100011000001110011101110101000"
"001001110010111101100100010001" "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" "010001111101000000100000100011"
"000000010000000100000000101000" "000000010000000100000000101000"
"001000101000110010011011001000" "001000101000110010011011001000"
@ -995,7 +1054,7 @@ static void test_encode(const testCtx *const p_ctx) {
"010101011101100110111011100100" "010101011101100110111011100100"
"011001000011110011011110111010" "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" "010000000000001010000000010011"
"001000111111010000011111001000" "001000111111010000011111001000"
"101111111010101111101101000101" "101111111010101111101101000101"
@ -1269,7 +1328,7 @@ static void test_encode_segs(const testCtx *const p_ctx) {
"010110101111010110101010111100" "010110101111010110101010111100"
"010100000000010110101010010100" "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" "011100110111111101000011011111"
"001000110000000100100001101000" "001000110000000100100001101000"
"000010110010010000110101000010" "000010110010010000110101000010"
@ -1409,7 +1468,7 @@ static void test_encode_segs(const testCtx *const p_ctx) {
"101010010100011001011101100110" "101010010100011001011101100110"
"111011110000111001101101111000" "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" "001101101011011110111111001111"
"001110011011111100110011001110" "001110011011111100110011001110"
"111000110010110010000110010011" "111000110010110010000110010011"
@ -1444,6 +1503,76 @@ static void test_encode_segs(const testCtx *const p_ctx) {
"101010011010110110110010010100" "101010011010110110110010010100"
"100101010111100011100010101000" "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); const int data_size = ARRAY_SIZE(data);
int i, j, seg_count, ret; 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[] = { 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", /* 0*/ { "am.//ab,\034TA# z\015!", 0, 100, 100, 0, 33, 30, "Different encodation than BWIPP, same number of codewords",
"111010000101111000111101010111" "111010000101111000111101010111"
"111110000000010100111000000000" "111110000000010100011000000000"
"110000101100110100111010101011" "110000101100110100111010101011"
"010101010101010101010101010100" "010101010101010101010101010100"
"000000000000000000000000000000" "000000000000000000000000000000"
"101010101010101010101010101000" "101010101010101010101010101010"
"010101010101010101010101010110" "010101010101010101010101010110"
"000000000000000000000000000000" "000000000000000000000000000010"
"101010101010101010101010101011" "101010101010101010101010101011"
"010101010111001100000101010110" "010101010111001100000101010110"
"000000001011000010000000000010" "000000001011000010000000000010"
"101010101100000000100110101010" "101010101100000000100110101010"
"010101001100000000101101010101" "010101001100000000101101010101"
"000000100000000000010000000010" "000000100000000000010000000010"
"101010110000000000010010101010" "101010110000000000010010101011"
"010101011000000000000101010110" "010101011000000000000101010110"
"000000001000000000001000000010" "000000001000000000001000000011"
"101010001000000000001010101000" "101010001000000000001010101000"
"010101010000000000001101010101" "010101010000000000001101010101"
"000000001100000000000000000010" "000000001100000000000000000010"
"101010110010000000010110101010" "101010110010000000010110101010"
"010101010100000001111001010100" "010101010100000001111001010110"
"000000001110110111111100000011" "000000001110110111111100000000"
"101010100110111101011010101010" "101010100110111101011010101000"
"010101010101010101010011101000" "010101010101010101010001100011"
"000000000000000000001101100000" "000000000000000000001110101000"
"101010101010101010100000100110" "101010101010101010100010100010"
"101001001101110001001011010000" "011000001001000010001111100000"
"100100110110001010011000011100" "110111111010111010011000001100"
"011011000001011011100100100110" "001011000101101010100000110110"
"111001100000101101000111001000" "110001100010100101010101001101"
"111100000110000011011101001110" "111000100110000011001110001100"
"010100101001110111101010110010" "011100101001111011111001111100"
}, },
}; };
const int data_size = ARRAY_SIZE(data); const int data_size = ARRAY_SIZE(data);
int i, length, ret; int i, length, ret;
struct zint_symbol *symbol = NULL; 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); 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) { if (p_ctx->generate) {
printf(" /*%2d*/ { \"%s\", %d, %.0f, %.0f, %d, %d, %d, \"%s\",\n", 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); data[i].w, data[i].h, data[i].ret_vector, symbol->rows, symbol->width, data[i].comment);
testUtilModulesPrint(symbol, " ", "\n"); testUtilModulesPrint(symbol, " ", "\n");
printf(" },\n"); printf(" },\n");
@ -1631,6 +1764,20 @@ static void test_best_supported_set(const testCtx *const p_ctx) {
ret = ZBarcode_Buffer_Vector(symbol, 0); 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); 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); ZBarcode_Delete(symbol);

View File

@ -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 */ /* 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 */ /* 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 == '\'' if (*d < 0x20 || *d >= 0x7F || (*d == '^' && !init_parsefnc) || *d == '"' || *d == '\''
|| (*d == '\\' && !zint_escape_mode)) { || *d == '(' || *d == ')' || (*d == '\\' && !zint_escape_mode)) {
if (b + 4 >= be) { if (b + 4 >= be) {
fprintf(stderr, "testUtilBwippEscape: double quote bwipp_data buffer full (%d)\n", bwipp_data_size); fprintf(stderr, "testUtilBwippEscape: double quote bwipp_data buffer full (%d)\n", bwipp_data_size);
return NULL; 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 'G': val = 0x1d; /* Group Separator */ break;
case 'R': val = 0x1e; /* Record Separator */ break; case 'R': val = 0x1e; /* Record Separator */ break;
case 'x': 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; if (val != -1) d+= 2;
break; break;
case 'd': 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 > 255) val = -1;
if (val != -1) d += 3; if (val != -1) d += 3;
break; break;
case 'o': 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; ? (ctoi(d[1]) << 6) | (ctoi(d[2]) << 3) | ctoi(d[3]) : -1;
if (val > 255) val = -1; if (val > 255) val = -1;
if (val != -1) d += 3; 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) { if (option_2 > 0) {
char scm_vv_buf[32]; char scm_vv_buf[40];
sprintf(scm_vv_buf, "[)>^03001^029%02d", option_2); /* [)>\R01\Gvv */ sprintf(scm_vv_buf, "[^041>^03001^029%02d", option_2 - 1); /* [)>\R01\Gvv */
memmove(bwipp_data + 15, bwipp_data, strlen(bwipp_data) + 1); memmove(bwipp_data + 18, bwipp_data, strlen(bwipp_data) + 1);
memcpy(bwipp_data, scm_vv_buf, 15); memcpy(bwipp_data, scm_vv_buf, 18);
if (!parse) { if (!parse) {
sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%sparse", sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%sparse",
strlen(bwipp_opts_buf) ? " " : ""); 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)); itoc(symbol->structapp.count));
bwipp_opts = bwipp_opts_buf; 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) { } else if (symbology == BARCODE_BC412) {
to_upper((unsigned char *) bwipp_data, (int) strlen(bwipp_data)); to_upper((unsigned char *) bwipp_data, (int) strlen(bwipp_data));
sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%ssemi", strlen(bwipp_opts_buf) ? " " : ""); sprintf(bwipp_opts_buf + strlen(bwipp_opts_buf), "%ssemi", strlen(bwipp_opts_buf) ? " " : "");

View File

@ -37,9 +37,11 @@ run_zxingcpp_test "test_dotcode" "encode"
run_zxingcpp_test "test_dotcode" "encode_segs" run_zxingcpp_test "test_dotcode" "encode_segs"
run_zxingcpp_test "test_hanxin" run_zxingcpp_test "test_hanxin"
run_zxingcpp_test "test_mailmark" "2d_encode" run_zxingcpp_test "test_mailmark" "2d_encode"
run_zxingcpp_test "test_maxicode" "large"
run_zxingcpp_test "test_maxicode" "input" run_zxingcpp_test "test_maxicode" "input"
run_zxingcpp_test "test_maxicode" "encode" run_zxingcpp_test "test_maxicode" "encode"
run_zxingcpp_test "test_maxicode" "encode_segs" 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_medical" "encode"
run_zxingcpp_test "test_pdf417" "reader_init" run_zxingcpp_test "test_pdf417" "reader_init"
run_zxingcpp_test "test_pdf417" "input" run_zxingcpp_test "test_pdf417" "input"

View File

@ -21,9 +21,9 @@ int main(int argc, char *argv[])
{ {
Q_INIT_RESOURCE(resources); 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 */ /* 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")); qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("xcb"));
} }
#endif #endif